Mercurial > emacs
comparison lisp/textmodes/tex-mode.el @ 51336:c1252b2b2582
(latex-block-args-alist, latex-block-body-alist): New vars.
(latex-insert-block): Use them.
(tex-string-prefix-p): New fun.
(tex-guess-main-file): Use it to detect when the main file
is in a parent directory.
(tex-main-file): Try to find a main-file in parent directories.
(tex-compile-default): Don't use `gv' on pdf files just because
`gv' was used recently on a ps file. Remove unused arg `dir'.
Reuse a previous command as-is if it applied to the same file.
(tex-compile): Use the right file name when file is not in dir.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 30 May 2003 18:52:46 +0000 |
parents | aeb075459c1d |
children | ebea7b586362 |
comparison
equal
deleted
inserted
replaced
51335:816e3b31173a | 51336:c1252b2b2582 |
---|---|
1210 (setq inside t))) | 1210 (setq inside t))) |
1211 inside)))) | 1211 inside)))) |
1212 | 1212 |
1213 (defvar latex-block-default "enumerate") | 1213 (defvar latex-block-default "enumerate") |
1214 | 1214 |
1215 (defvar latex-block-args-alist | |
1216 '(("array" nil ?\{ (skeleton-read "[options]: ") ?\}) | |
1217 ("tabular" nil ?\{ (skeleton-read "[options]: ") ?\})) | |
1218 "Skeleton element to use for arguments to particular environments. | |
1219 Every element of the list has the form (NAME . SKEL-ELEM) where NAME is | |
1220 the name of the environment and SKEL-ELEM is an element to use in | |
1221 a skeleton (see `skeleton-insert').") | |
1222 | |
1223 (defvar latex-block-body-alist | |
1224 '(("enumerate" nil '(latex-insert-item) > _) | |
1225 ("itemize" nil '(latex-insert-item) > _) | |
1226 ("table" nil "\\caption{" > - "}" > \n _) | |
1227 ("figure" nil > _ \n "\\caption{" > _ "}" >)) | |
1228 "Skeleton element to use for the body of particular environments. | |
1229 Every element of the list has the form (NAME . SKEL-ELEM) where NAME is | |
1230 the name of the environment and SKEL-ELEM is an element to use in | |
1231 a skeleton (see `skeleton-insert').") | |
1232 | |
1215 ;; Like tex-insert-braces, but for LaTeX. | 1233 ;; Like tex-insert-braces, but for LaTeX. |
1216 (defalias 'tex-latex-block 'latex-insert-block) | 1234 (defalias 'tex-latex-block 'latex-insert-block) |
1217 (define-skeleton latex-insert-block | 1235 (define-skeleton latex-insert-block |
1218 "Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. | 1236 "Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. |
1219 Puts point on a blank line between them." | 1237 Puts point on a blank line between them." |
1227 (member choice latex-block-names)) | 1245 (member choice latex-block-names)) |
1228 ;; Remember new block names for later completion. | 1246 ;; Remember new block names for later completion. |
1229 (push choice latex-block-names)) | 1247 (push choice latex-block-names)) |
1230 choice) | 1248 choice) |
1231 \n "\\begin{" str "}" | 1249 \n "\\begin{" str "}" |
1232 ?\[ (skeleton-read "[options]: ") & ?\] | -1 | 1250 (cdr (assoc str latex-block-args-alist)) |
1233 > \n _ \n | 1251 > \n (or (cdr (assoc str latex-block-body-alist)) '(nil > _)) \n |
1234 "\\end{" str "}" > \n) | 1252 "\\end{" str "}" > \n) |
1235 | 1253 |
1236 (define-skeleton latex-insert-item | 1254 (define-skeleton latex-insert-item |
1237 "Insert a \item macro." | 1255 "Insert a \item macro." |
1238 nil | 1256 nil |
1570 the name of the input file, or t to indicate that the input is all | 1588 the name of the input file, or t to indicate that the input is all |
1571 the TeX files of the document, or nil if we don't know. | 1589 the TeX files of the document, or nil if we don't know. |
1572 OUT describes the output file and is either a %-escaped string | 1590 OUT describes the output file and is either a %-escaped string |
1573 or nil to indicate that there is no output file.") | 1591 or nil to indicate that there is no output file.") |
1574 | 1592 |
1593 ;; defsubst* gives better byte-code than defsubst. | |
1594 (defsubst* tex-string-prefix-p (str1 str2) | |
1595 "Return non-nil if STR1 is a prefix of STR2" | |
1596 (eq t (compare-strings str2 nil (length str1) str1 nil nil))) | |
1597 | |
1575 (defun tex-guess-main-file (&optional all) | 1598 (defun tex-guess-main-file (&optional all) |
1576 "Find a likely `tex-main-file'. | 1599 "Find a likely `tex-main-file'. |
1577 Looks for hints in other buffers in the same directory or in | 1600 Looks for hints in other buffers in the same directory or in |
1578 ALL other buffers." | 1601 ALL other buffers. If ALL is `sub' only look at buffers in parent directories |
1602 of the current buffer." | |
1579 (let ((dir default-directory) | 1603 (let ((dir default-directory) |
1580 (header-re tex-start-of-header)) | 1604 (header-re tex-start-of-header)) |
1581 (catch 'found | 1605 (catch 'found |
1582 ;; Look for a buffer with `tex-main-file' set. | 1606 ;; Look for a buffer with `tex-main-file' set. |
1583 (dolist (buf (if (consp all) all (buffer-list))) | 1607 (dolist (buf (if (consp all) all (buffer-list))) |
1584 (with-current-buffer buf | 1608 (with-current-buffer buf |
1585 (when (and (or all (equal dir default-directory)) | 1609 (when (and (cond |
1610 ((null all) (equal dir default-directory)) | |
1611 ((eq all 'sub) (tex-string-prefix-p default-directory dir)) | |
1612 (t)) | |
1586 (stringp tex-main-file)) | 1613 (stringp tex-main-file)) |
1587 (throw 'found (expand-file-name tex-main-file))))) | 1614 (throw 'found (expand-file-name tex-main-file))))) |
1588 ;; Look for a buffer containing the magic `tex-start-of-header'. | 1615 ;; Look for a buffer containing the magic `tex-start-of-header'. |
1589 (dolist (buf (if (consp all) all (buffer-list))) | 1616 (dolist (buf (if (consp all) all (buffer-list))) |
1590 (with-current-buffer buf | 1617 (with-current-buffer buf |
1591 (when (and (or all (equal dir default-directory)) | 1618 (when (and (cond |
1619 ((null all) (equal dir default-directory)) | |
1620 ((eq all 'sub) (tex-string-prefix-p default-directory dir)) | |
1621 (t)) | |
1592 buffer-file-name | 1622 buffer-file-name |
1593 ;; (or (easy-mmode-derived-mode-p 'latex-mode) | 1623 ;; (or (easy-mmode-derived-mode-p 'latex-mode) |
1594 ;; (easy-mmode-derived-mode-p 'plain-tex-mode)) | 1624 ;; (easy-mmode-derived-mode-p 'plain-tex-mode)) |
1595 (save-excursion | 1625 (save-excursion |
1596 (save-restriction | 1626 (save-restriction |
1616 (+ (point) 10000) t)) | 1646 (+ (point) 10000) t)) |
1617 ;; This is the main file. | 1647 ;; This is the main file. |
1618 buffer-file-name | 1648 buffer-file-name |
1619 ;; This isn't the main file, let's try to find better, | 1649 ;; This isn't the main file, let's try to find better, |
1620 (or (tex-guess-main-file) | 1650 (or (tex-guess-main-file) |
1651 (tex-guess-main-file 'sub) | |
1621 ;; (tex-guess-main-file t) | 1652 ;; (tex-guess-main-file t) |
1622 buffer-file-name))))))) | 1653 buffer-file-name))))))) |
1623 (if (file-exists-p file) file (concat file ".tex")))) | 1654 (if (file-exists-p file) file (concat file ".tex")))) |
1624 | 1655 |
1625 (defun tex-summarize-command (cmd) | 1656 (defun tex-summarize-command (cmd) |
1703 (file-newer-than-file-p | 1734 (file-newer-than-file-p |
1704 file (format-spec out fspec))))) | 1735 file (format-spec out fspec))))) |
1705 (when (and (eq in t) (stringp out)) | 1736 (when (and (eq in t) (stringp out)) |
1706 (not (tex-uptodate-p (format-spec out fspec))))))) | 1737 (not (tex-uptodate-p (format-spec out fspec))))))) |
1707 | 1738 |
1708 (defun tex-compile-default (dir fspec) | 1739 (defun tex-compile-default (fspec) |
1709 "Guess a default command in DIR given the format-spec FSPEC." | 1740 "Guess a default command given the format-spec FSPEC." |
1710 ;; TODO: Learn to do latex+dvips! | 1741 ;; TODO: Learn to do latex+dvips! |
1711 (let ((cmds nil) | 1742 (let ((cmds nil) |
1712 (unchanged-in nil)) | 1743 (unchanged-in nil)) |
1713 ;; Only consider active commands. | 1744 ;; Only consider active commands. |
1714 (dolist (cmd tex-compile-commands) | 1745 (dolist (cmd tex-compile-commands) |
1722 ;; is inexistent doesn't matter). | 1753 ;; is inexistent doesn't matter). |
1723 (let ((tmp nil)) | 1754 (let ((tmp nil)) |
1724 (dolist (cmd cmds) | 1755 (dolist (cmd cmds) |
1725 (unless (member (nth 1 cmd) unchanged-in) | 1756 (unless (member (nth 1 cmd) unchanged-in) |
1726 (push cmd tmp))) | 1757 (push cmd tmp))) |
1758 ;; Only remove if there's something left. | |
1727 (if tmp (setq cmds tmp))) | 1759 (if tmp (setq cmds tmp))) |
1728 ;; remove commands whose input is not uptodate either. | 1760 ;; Remove commands whose input is not uptodate either. |
1729 (let ((outs (delq nil (mapcar (lambda (x) (nth 2 x)) cmds)))) | 1761 (let ((outs (delq nil (mapcar (lambda (x) (nth 2 x)) cmds))) |
1730 (dolist (cmd (prog1 cmds (setq cmds nil))) | 1762 (tmp nil)) |
1763 (dolist (cmd cmds) | |
1731 (unless (member (nth 1 cmd) outs) | 1764 (unless (member (nth 1 cmd) outs) |
1732 (push cmd cmds)))) | 1765 (push cmd tmp))) |
1766 ;; Only remove if there's something left. | |
1767 (if tmp (setq cmds tmp))) | |
1733 ;; Select which file we're going to operate on (the latest). | 1768 ;; Select which file we're going to operate on (the latest). |
1734 (let ((latest (nth 1 (car cmds)))) | 1769 (let ((latest (nth 1 (car cmds)))) |
1735 (dolist (cmd (prog1 (cdr cmds) (setq cmds (list (car cmds))))) | 1770 (dolist (cmd (prog1 (cdr cmds) (setq cmds (list (car cmds))))) |
1736 (if (equal latest (nth 1 cmd)) | 1771 (if (equal latest (nth 1 cmd)) |
1737 (push cmd cmds) | 1772 (push cmd cmds) |
1746 ;; Expand the command spec into the actual text. | 1781 ;; Expand the command spec into the actual text. |
1747 (dolist (cmd (prog1 cmds (setq cmds nil))) | 1782 (dolist (cmd (prog1 cmds (setq cmds nil))) |
1748 (push (cons (eval (car cmd)) (cdr cmd)) cmds)) | 1783 (push (cons (eval (car cmd)) (cdr cmd)) cmds)) |
1749 ;; Select the favorite command from the history. | 1784 ;; Select the favorite command from the history. |
1750 (let ((hist tex-compile-history) | 1785 (let ((hist tex-compile-history) |
1751 re) | 1786 re hist-cmd) |
1752 (while hist | 1787 (while hist |
1788 (setq hist-cmd (pop hist)) | |
1753 (setq re (concat "\\`" | 1789 (setq re (concat "\\`" |
1754 (regexp-quote (tex-command-executable (pop hist))) | 1790 (regexp-quote (tex-command-executable hist-cmd)) |
1755 "\\([ \t]\\|\\'\\)")) | 1791 "\\([ \t]\\|\\'\\)")) |
1756 (dolist (cmd cmds) | 1792 (dolist (cmd cmds) |
1757 (if (string-match re (car cmd)) | 1793 ;; If the hist entry uses the same command and applies to a file |
1758 (setq hist nil cmds (list cmd)))))) | 1794 ;; of the same type (e.g. `gv %r.pdf' vs `gv %r.ps'), select cmd. |
1759 ;; Substitute and return. | 1795 (and (string-match re (car cmd)) |
1760 (format-spec (caar cmds) fspec))) | 1796 (or (not (string-match "%[fr]\\([-._[:alnum:]]+\\)" (car cmd))) |
1797 (string-match (regexp-quote (match-string 1 (car cmd))) | |
1798 hist-cmd)) | |
1799 (setq hist nil cmds (list cmd))))) | |
1800 ;; Substitute and return. | |
1801 (if (and hist-cmd | |
1802 (string-match (concat "[' \t\"]" (format-spec "%r" fspec) | |
1803 "\\([;&' \t\"]\\|\\'\\)") hist-cmd)) | |
1804 ;; The history command was already applied to the same file, | |
1805 ;; so just reuse it. | |
1806 hist-cmd | |
1807 (if cmds (format-spec (caar cmds) fspec)))))) | |
1761 | 1808 |
1762 (defun tex-compile (dir cmd) | 1809 (defun tex-compile (dir cmd) |
1763 "Run a command CMD on current TeX buffer's file in DIR." | 1810 "Run a command CMD on current TeX buffer's file in DIR." |
1764 ;; FIXME: Use time-stamps on files to decide the next op. | 1811 ;; FIXME: Use time-stamps on files to decide the next op. |
1765 (interactive | 1812 (interactive |
1766 (let* ((file (tex-main-file)) | 1813 (let* ((file (tex-main-file)) |
1814 (dir (prog1 (file-name-directory (expand-file-name file)) | |
1815 (setq file (file-name-nondirectory file)))) | |
1767 (root (file-name-sans-extension file)) | 1816 (root (file-name-sans-extension file)) |
1768 (dir (file-name-directory (expand-file-name file))) | |
1769 (fspec (list (cons ?r (comint-quote-filename root)) | 1817 (fspec (list (cons ?r (comint-quote-filename root)) |
1770 (cons ?f (comint-quote-filename file)))) | 1818 (cons ?f (comint-quote-filename file)))) |
1771 (default (tex-compile-default dir fspec))) | 1819 (default (tex-compile-default fspec))) |
1772 (list dir | 1820 (list dir |
1773 (completing-read | 1821 (completing-read |
1774 (format "Command [%s]: " (tex-summarize-command default)) | 1822 (format "Command [%s]: " (tex-summarize-command default)) |
1775 (mapcar (lambda (x) | 1823 (mapcar (lambda (x) |
1776 (list (format-spec (eval (car x)) fspec))) | 1824 (list (format-spec (eval (car x)) fspec))) |