diff options
| author | Stefan Monnier | 2003-05-30 18:52:46 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2003-05-30 18:52:46 +0000 |
| commit | 8084f5d87c5235ee3619daabba474e4246bb7a62 (patch) | |
| tree | a336d265350c60040b7909a44d8c7e2fc80cc830 | |
| parent | ad2feb08904628531585213bb77036befe9a2db2 (diff) | |
| download | emacs-8084f5d87c5235ee3619daabba474e4246bb7a62.tar.gz emacs-8084f5d87c5235ee3619daabba474e4246bb7a62.zip | |
(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.
| -rw-r--r-- | lisp/textmodes/tex-mode.el | 86 |
1 files changed, 67 insertions, 19 deletions
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index c0e606e744c..a94090d8577 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el | |||
| @@ -1212,6 +1212,24 @@ A prefix arg inhibits the checking." | |||
| 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 |
| @@ -1229,8 +1247,8 @@ Puts point on a blank line between them." | |||
| 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 |
| @@ -1572,23 +1590,35 @@ IN can be either a string (with the same % escapes in it) indicating | |||
| 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)) |
| @@ -1618,6 +1648,7 @@ ALL other buffers." | |||
| 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")))) |
| @@ -1705,8 +1736,8 @@ FILE is typically the output DVI or PDF file." | |||
| 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)) |
| @@ -1724,12 +1755,16 @@ FILE is typically the output DVI or PDF file." | |||
| 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))))) |
| @@ -1748,27 +1783,40 @@ FILE is typically the output DVI or PDF file." | |||
| 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)) |