diff options
| author | Stefan Monnier | 2000-10-01 00:47:41 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2000-10-01 00:47:41 +0000 |
| commit | 53c4fe47866097b20949ffc87ed93a6b09387cdf (patch) | |
| tree | 454769a1c45d12baed8d527fb870d111ac2fcfd9 | |
| parent | eedd2812657ce6a083c8bc7ee6265e914bad9f69 (diff) | |
| download | emacs-53c4fe47866097b20949ffc87ed93a6b09387cdf.tar.gz emacs-53c4fe47866097b20949ffc87ed93a6b09387cdf.zip | |
(latex-metasection-list): New var.
(latex-imenu-create-index): Use it.
Move the regexp construction outside loops (and use push).
(tex-font-lock-keywords-1, tex-font-lock-keywords-2)
(tex-font-lock-keywords): Moved from font-lock.el.
(tex-comment-indent): Remove.
(tex-common-initialization): Don't set comment-indent-function.
(latex-block-default): New var.
(tex-latex-block): Use it to provide a default choice.
Add any unknown choice to latex-block-names.
Insert [...] after {...}.
(tex-last-unended-begin): Simplify regexp.
(tex-goto-last-unclosed-latex-block, latex-backward-sexp-1)
(latex-forward-sexp-1, latex-forward-sexp): New functions.
(latex-mode): Set forward-sexp-function.
| -rw-r--r-- | lisp/textmodes/tex-mode.el | 313 |
1 files changed, 253 insertions, 60 deletions
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 99f0d9d0e93..b66cd6470ab 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el | |||
| @@ -268,6 +268,10 @@ Set by \\[tex-region], \\[tex-buffer], and \\[tex-file].") | |||
| 268 | 268 | ||
| 269 | (defvar tex-mode-syntax-table nil | 269 | (defvar tex-mode-syntax-table nil |
| 270 | "Syntax table used while in TeX mode.") | 270 | "Syntax table used while in TeX mode.") |
| 271 | |||
| 272 | ;;;; | ||
| 273 | ;;;; Imenu support | ||
| 274 | ;;;; | ||
| 271 | 275 | ||
| 272 | (defcustom latex-imenu-indent-string ". " | 276 | (defcustom latex-imenu-indent-string ". " |
| 273 | "*String to add repeated in front of nested sectional units for Imenu. | 277 | "*String to add repeated in front of nested sectional units for Imenu. |
| @@ -281,9 +285,19 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 281 | ("subsubsection" . 4) | 285 | ("subsubsection" . 4) |
| 282 | ("paragraph" . 5) ("subparagraph" . 6))) | 286 | ("paragraph" . 5) ("subparagraph" . 6))) |
| 283 | 287 | ||
| 288 | (defvar latex-metasection-list | ||
| 289 | '("documentstyle" "documentclass" | ||
| 290 | "begin{document}" "end{document}" | ||
| 291 | "appendix" "frontmatter" "mainmatter" "backmatter")) | ||
| 292 | |||
| 284 | (defun latex-imenu-create-index () | 293 | (defun latex-imenu-create-index () |
| 285 | "Generates an alist for imenu from a LaTeX buffer." | 294 | "Generate an alist for imenu from a LaTeX buffer." |
| 286 | (let (i0 menu case-fold-search) | 295 | (let ((section-regexp |
| 296 | (concat "\\\\" (regexp-opt (mapcar 'car latex-section-alist) t) | ||
| 297 | "\\*?[ \t]*{")) | ||
| 298 | (metasection-regexp | ||
| 299 | (concat "\\\\" (regexp-opt latex-metasection-list t))) | ||
| 300 | i0 menu case-fold-search) | ||
| 287 | (save-excursion | 301 | (save-excursion |
| 288 | ;; Find the top-most level in this file but don't allow it to be | 302 | ;; Find the top-most level in this file but don't allow it to be |
| 289 | ;; any deeper than "section" (which is top-level in an article). | 303 | ;; any deeper than "section" (which is top-level in an article). |
| @@ -296,10 +310,7 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 296 | 310 | ||
| 297 | ;; Look for chapters and sections. | 311 | ;; Look for chapters and sections. |
| 298 | (goto-char (point-min)) | 312 | (goto-char (point-min)) |
| 299 | (while (search-forward-regexp | 313 | (while (search-forward-regexp section-regexp nil t) |
| 300 | (progn | ||
| 301 | (concat "\\\\" (regexp-opt (mapcar 'car latex-section-alist) t) | ||
| 302 | "\\*?[ \t]*{")) nil t) | ||
| 303 | (let ((start (match-beginning 0)) | 314 | (let ((start (match-beginning 0)) |
| 304 | (here (point)) | 315 | (here (point)) |
| 305 | (i (cdr (assoc (buffer-substring-no-properties | 316 | (i (cdr (assoc (buffer-substring-no-properties |
| @@ -326,30 +337,167 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 326 | (goto-char (point-min)) | 337 | (goto-char (point-min)) |
| 327 | (while (search-forward-regexp | 338 | (while (search-forward-regexp |
| 328 | "\\\\\\(include\\|input\\|verbatiminput\\|bibliography\\)\ | 339 | "\\\\\\(include\\|input\\|verbatiminput\\|bibliography\\)\ |
| 329 | [ \t]*{\\([^}\n]+\\)}" | 340 | \[ \t]*{\\([^}\n]+\\)}" |
| 330 | nil t) | 341 | nil t) |
| 331 | (setq menu | 342 | (push (cons (concat "<<" (buffer-substring-no-properties |
| 332 | (cons (cons (concat "<<" (buffer-substring-no-properties | 343 | (match-beginning 2) |
| 333 | (match-beginning 2) | 344 | (match-end 2)) |
| 334 | (match-end 2)) | 345 | (if (= (char-after (match-beginning 1)) ?b) |
| 335 | (if (= (char-after (match-beginning 1)) ?b) | 346 | ".bbl" |
| 336 | ".bbl" | 347 | ".tex")) |
| 337 | ".tex")) | 348 | (match-beginning 0)) |
| 338 | (match-beginning 0)) | 349 | menu)) |
| 339 | menu))) | ||
| 340 | 350 | ||
| 341 | ;; Look for \frontmatter, \mainmatter, \backmatter, and \appendix. | 351 | ;; Look for \frontmatter, \mainmatter, \backmatter, and \appendix. |
| 342 | (goto-char (point-min)) | 352 | (goto-char (point-min)) |
| 343 | (while (search-forward-regexp | 353 | (while (search-forward-regexp metasection-regexp nil t) |
| 344 | "\\\\\\(frontmatter\\|mainmatter\\|backmatter\\|appendix\\)\\b" | 354 | (push (cons "--" (match-beginning 0)) menu)) |
| 345 | nil t) | ||
| 346 | (setq menu | ||
| 347 | (cons (cons "--" (match-beginning 0)) | ||
| 348 | menu))) | ||
| 349 | 355 | ||
| 350 | ;; Sort in increasing buffer position order. | 356 | ;; Sort in increasing buffer position order. |
| 351 | (sort menu (function (lambda (a b) (< (cdr a) (cdr b)))))))) | 357 | (sort menu (function (lambda (a b) (< (cdr a) (cdr b)))))))) |
| 358 | |||
| 359 | ;;;; | ||
| 360 | ;;;; Outline support | ||
| 361 | ;;;; | ||
| 362 | |||
| 363 | (defvar latex-outline-regexp | ||
| 364 | (concat "\\\\" | ||
| 365 | (regexp-opt (append latex-metasection-list | ||
| 366 | (mapcar 'car latex-section-alist)) t))) | ||
| 367 | |||
| 368 | (defun latex-outline-level () | ||
| 369 | (if (looking-at latex-outline-regexp) | ||
| 370 | (1+ (or (cdr (assoc (match-string 1) latex-section-alist)) -1)) | ||
| 371 | 1000)) | ||
| 372 | |||
| 373 | ;;;; | ||
| 374 | ;;;; Font-Lock support | ||
| 375 | ;;;; | ||
| 376 | |||
| 377 | ;(defvar tex-font-lock-keywords | ||
| 378 | ; ;; Regexps updated with help from Ulrik Dickow <dickow@nbi.dk>. | ||
| 379 | ; '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" | ||
| 380 | ; 2 font-lock-function-name-face) | ||
| 381 | ; ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" | ||
| 382 | ; 2 font-lock-constant-face) | ||
| 383 | ; ;; It seems a bit dubious to use `bold' and `italic' faces since we might | ||
| 384 | ; ;; not be able to display those fonts. | ||
| 385 | ; ("{\\\\bf\\([^}]+\\)}" 1 'bold keep) | ||
| 386 | ; ("{\\\\\\(em\\|it\\|sl\\)\\([^}]+\\)}" 2 'italic keep) | ||
| 387 | ; ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face) | ||
| 388 | ; ("^[ \t\n]*\\\\def[\\\\@]\\(\\w+\\)" 1 font-lock-function-name-face keep)) | ||
| 389 | ; ;; Rewritten and extended for LaTeX2e by Ulrik Dickow <dickow@nbi.dk>. | ||
| 390 | ; '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" | ||
| 391 | ; 2 font-lock-function-name-face) | ||
| 392 | ; ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" | ||
| 393 | ; 2 font-lock-constant-face) | ||
| 394 | ; ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face) | ||
| 395 | ; "\\\\\\([a-zA-Z@]+\\|.\\)" | ||
| 396 | ; ;; It seems a bit dubious to use `bold' and `italic' faces since we might | ||
| 397 | ; ;; not be able to display those fonts. | ||
| 398 | ; ;; LaTeX2e: \emph{This is emphasized}. | ||
| 399 | ; ("\\\\emph{\\([^}]+\\)}" 1 'italic keep) | ||
| 400 | ; ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...} | ||
| 401 | ; ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}" | ||
| 402 | ; 3 (if (match-beginning 2) 'bold 'italic) keep) | ||
| 403 | ; ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. | ||
| 404 | ; ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)" | ||
| 405 | ; 3 (if (match-beginning 2) 'bold 'italic) keep)) | ||
| 406 | |||
| 407 | ;; Rewritten with the help of Alexandra Bac <abac@welcome.disi.unige.it>. | ||
| 408 | (defconst tex-font-lock-keywords-1 | ||
| 409 | (eval-when-compile | ||
| 410 | (let* (;; Names of commands whose arg should be fontified as heading, etc. | ||
| 411 | (headings (regexp-opt | ||
| 412 | '("title" "begin" "end" "chapter" "part" | ||
| 413 | "section" "subsection" "subsubsection" | ||
| 414 | "paragraph" "subparagraph" "subsubparagraph" | ||
| 415 | "newcommand" "renewcommand" "newenvironment" | ||
| 416 | "newtheorem") | ||
| 417 | t)) | ||
| 418 | (variables (regexp-opt | ||
| 419 | '("newcounter" "newcounter*" "setcounter" "addtocounter" | ||
| 420 | "setlength" "addtolength" "settowidth") | ||
| 421 | t)) | ||
| 422 | (includes (regexp-opt | ||
| 423 | '("input" "include" "includeonly" "bibliography" | ||
| 424 | "epsfig" "psfig" "epsf" "nofiles" "usepackage" | ||
| 425 | "includegraphics" "includegraphics*") | ||
| 426 | t)) | ||
| 427 | ;; Miscellany. | ||
| 428 | (slash "\\\\") | ||
| 429 | (opt "\\(\\[[^]]*\\]\\)?") | ||
| 430 | (arg "{\\(\\(?:[^{}]+\\(?:{[^}]*}\\)?\\)+\\)")) | ||
| 431 | (list | ||
| 432 | ;; Heading args. | ||
| 433 | (list (concat slash headings "\\*?" opt arg) | ||
| 434 | 3 'font-lock-function-name-face 'prepend) | ||
| 435 | ;; Variable args. | ||
| 436 | (list (concat slash variables arg) 2 'font-lock-variable-name-face) | ||
| 437 | ;; Include args. | ||
| 438 | (list (concat slash includes opt arg) 3 'font-lock-builtin-face) | ||
| 439 | ;; Definitions. I think. | ||
| 440 | '("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" | ||
| 441 | 1 font-lock-function-name-face) | ||
| 442 | ))) | ||
| 443 | "Subdued expressions to highlight in TeX modes.") | ||
| 444 | |||
| 445 | (defconst tex-font-lock-keywords-2 | ||
| 446 | (append tex-font-lock-keywords-1 | ||
| 447 | (eval-when-compile | ||
| 448 | (let* (;; | ||
| 449 | ;; Names of commands whose arg should be fontified with fonts. | ||
| 450 | (bold (regexp-opt '("bf" "textbf" "textsc" "textup" | ||
| 451 | "boldsymbol" "pmb") t)) | ||
| 452 | (italic (regexp-opt '("it" "textit" "textsl" "emph") t)) | ||
| 453 | (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t)) | ||
| 454 | ;; | ||
| 455 | ;; Names of commands whose arg should be fontified as a citation. | ||
| 456 | (citations (regexp-opt | ||
| 457 | '("label" "ref" "pageref" "vref" "eqref" | ||
| 458 | "cite" "nocite" "caption" "index" "glossary" | ||
| 459 | "footnote" "footnotemark" "footnotetext") | ||
| 460 | t)) | ||
| 461 | ;; | ||
| 462 | ;; Names of commands that should be fontified. | ||
| 463 | (specials (regexp-opt | ||
| 464 | '("\\" | ||
| 465 | "linebreak" "nolinebreak" "pagebreak" "nopagebreak" | ||
| 466 | "newline" "newpage" "clearpage" "cleardoublepage" | ||
| 467 | "displaybreak" "allowdisplaybreaks" "enlargethispage") | ||
| 468 | t)) | ||
| 469 | (general "\\([a-zA-Z@]+\\**\\|[^ \t\n]\\)") | ||
| 470 | ;; | ||
| 471 | ;; Miscellany. | ||
| 472 | (slash "\\\\") | ||
| 473 | (opt "\\(\\[[^]]*\\]\\)?") | ||
| 474 | (arg "{\\(\\(?:[^{}]+\\(?:{[^}]*}\\)?\\)+\\)")) | ||
| 475 | (list | ||
| 476 | ;; | ||
| 477 | ;; Citation args. | ||
| 478 | (list (concat slash citations opt arg) 3 'font-lock-constant-face) | ||
| 479 | ;; | ||
| 480 | ;; Command names, special and general. | ||
| 481 | (cons (concat slash specials) 'font-lock-warning-face) | ||
| 482 | (concat slash general) | ||
| 483 | ;; | ||
| 484 | ;; Font environments. It seems a bit dubious to use `bold' etc. faces | ||
| 485 | ;; since we might not be able to display those fonts. | ||
| 486 | (list (concat slash bold arg) 2 '(quote bold) 'append) | ||
| 487 | (list (concat slash italic arg) 2 '(quote italic) 'append) | ||
| 488 | (list (concat slash type arg) 2 '(quote bold-italic) 'append) | ||
| 489 | ;; | ||
| 490 | ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. | ||
| 491 | (list (concat "\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>" | ||
| 492 | "\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)") | ||
| 493 | 3 '(if (match-beginning 2) 'bold 'italic) 'append) | ||
| 494 | )))) | ||
| 495 | "Gaudy expressions to highlight in TeX modes.") | ||
| 496 | |||
| 497 | (defvar tex-font-lock-keywords tex-font-lock-keywords-1 | ||
| 498 | "Default expressions to highlight in TeX modes.") | ||
| 352 | 499 | ||
| 500 | |||
| 353 | (defun tex-define-common-keys (keymap) | 501 | (defun tex-define-common-keys (keymap) |
| 354 | "Define the keys that we want defined both in TeX mode and in the TeX shell." | 502 | "Define the keys that we want defined both in TeX mode and in the TeX shell." |
| 355 | (define-key keymap "\C-c\C-k" 'tex-kill-job) | 503 | (define-key keymap "\C-c\C-k" 'tex-kill-job) |
| @@ -592,6 +740,7 @@ subshell is initiated, `tex-shell-hook' is run." | |||
| 592 | 'latex-fill-nobreak-predicate) | 740 | 'latex-fill-nobreak-predicate) |
| 593 | (set (make-local-variable 'outline-regexp) latex-outline-regexp) | 741 | (set (make-local-variable 'outline-regexp) latex-outline-regexp) |
| 594 | (set (make-local-variable 'outline-level) 'latex-outline-level) | 742 | (set (make-local-variable 'outline-level) 'latex-outline-level) |
| 743 | (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp) | ||
| 595 | (run-hooks 'tex-mode-hook)) | 744 | (run-hooks 'tex-mode-hook)) |
| 596 | 745 | ||
| 597 | ;;;###autoload | 746 | ;;;###autoload |
| @@ -676,7 +825,6 @@ Entering SliTeX mode runs the hook `text-mode-hook', then the hook | |||
| 676 | (set (make-local-variable 'comment-add) 1) | 825 | (set (make-local-variable 'comment-add) 1) |
| 677 | (set (make-local-variable 'comment-start-skip) | 826 | (set (make-local-variable 'comment-start-skip) |
| 678 | "\\(\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") | 827 | "\\(\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") |
| 679 | (set (make-local-variable 'comment-indent-function) 'tex-comment-indent) | ||
| 680 | (set (make-local-variable 'parse-sexp-ignore-comments) t) | 828 | (set (make-local-variable 'parse-sexp-ignore-comments) t) |
| 681 | (set (make-local-variable 'compare-windows-whitespace) | 829 | (set (make-local-variable 'compare-windows-whitespace) |
| 682 | 'tex-categorize-whitespace) | 830 | 'tex-categorize-whitespace) |
| @@ -699,13 +847,6 @@ Entering SliTeX mode runs the hook `text-mode-hook', then the hook | |||
| 699 | (make-local-variable 'tex-end-of-header) | 847 | (make-local-variable 'tex-end-of-header) |
| 700 | (make-local-variable 'tex-trailer)) | 848 | (make-local-variable 'tex-trailer)) |
| 701 | 849 | ||
| 702 | (defun tex-comment-indent () | ||
| 703 | (if (looking-at "%%%") | ||
| 704 | (current-column) | ||
| 705 | (skip-chars-backward " \t") | ||
| 706 | (max (if (bolp) 0 (1+ (current-column))) | ||
| 707 | comment-column))) | ||
| 708 | |||
| 709 | (defun tex-categorize-whitespace (backward-limit) | 850 | (defun tex-categorize-whitespace (backward-limit) |
| 710 | ;; compare-windows-whitespace is set to this. | 851 | ;; compare-windows-whitespace is set to this. |
| 711 | ;; This is basically a finite-state machine. | 852 | ;; This is basically a finite-state machine. |
| @@ -895,28 +1036,46 @@ A prefix arg inhibits the checking." | |||
| 895 | (setq inside t))))) | 1036 | (setq inside t))))) |
| 896 | inside)) | 1037 | inside)) |
| 897 | 1038 | ||
| 1039 | (defvar latex-block-default "enumerate") | ||
| 1040 | |||
| 898 | ;;; Like tex-insert-braces, but for LaTeX. | 1041 | ;;; Like tex-insert-braces, but for LaTeX. |
| 899 | (define-skeleton tex-latex-block | 1042 | (define-skeleton tex-latex-block |
| 900 | "Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. | 1043 | "Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. |
| 901 | Puts point on a blank line between them." | 1044 | Puts point on a blank line between them." |
| 902 | (completing-read "LaTeX block name: " | 1045 | (let ((choice (completing-read (format "LaTeX block name [%s]: " |
| 903 | (mapcar 'list | 1046 | latex-block-default) |
| 904 | (append standard-latex-block-names | 1047 | (mapcar 'list |
| 905 | latex-block-names))) | 1048 | (append standard-latex-block-names |
| 906 | "\\begin[" | 1049 | latex-block-names)) |
| 907 | (skeleton-read "[options]: ") & ?\] | -1 | 1050 | nil nil nil nil latex-block-default))) |
| 908 | ?\{ | 1051 | (setq latex-block-default choice) |
| 909 | str | 1052 | (unless (or (member choice standard-latex-block-names) |
| 910 | ?\} \n | 1053 | (member choice latex-block-names)) |
| 911 | _ \n | 1054 | ;; Remember new block names for later completion. |
| 912 | "\\end{" str ?\}) | 1055 | (push choice latex-block-names)) |
| 1056 | choice) | ||
| 1057 | "\\begin{" str ?\} | ||
| 1058 | ?\[ (skeleton-read "[options]: ") & ?\] | -1 | ||
| 1059 | \n _ \n | ||
| 1060 | "\\end{" str ?\} >) | ||
| 1061 | |||
| 1062 | |||
| 1063 | ;;;; | ||
| 1064 | ;;;; LaTeX syntax navigation | ||
| 1065 | ;;;; | ||
| 913 | 1066 | ||
| 914 | (defun tex-last-unended-begin () | 1067 | (defun tex-last-unended-begin () |
| 915 | "Leave point at the beginning of the last `\\begin{...}' that is unended." | 1068 | "Leave point at the beginning of the last `\\begin{...}' that is unended." |
| 916 | (while (and (re-search-backward "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)") | 1069 | (while (and (re-search-backward "\\\\\\(begin\\|end\\)\\s *{") |
| 917 | (looking-at "\\\\end{")) | 1070 | (looking-at "\\\\end")) |
| 918 | (tex-last-unended-begin))) | 1071 | (tex-last-unended-begin))) |
| 919 | 1072 | ||
| 1073 | (defun tex-next-unmatched-end () | ||
| 1074 | "Leave point at the end of the next `\\end' that is unended." | ||
| 1075 | (while (and (re-search-forward "\\\\\\(begin\\|end\\)\\s *{[^}]+}") | ||
| 1076 | (looking-at "\\\\begin")) | ||
| 1077 | (tex-next-unmatched-end))) | ||
| 1078 | |||
| 920 | (defun tex-goto-last-unclosed-latex-block () | 1079 | (defun tex-goto-last-unclosed-latex-block () |
| 921 | "Move point to the last unclosed \\begin{...}. | 1080 | "Move point to the last unclosed \\begin{...}. |
| 922 | Mark is left at original location." | 1081 | Mark is left at original location." |
| @@ -930,6 +1089,57 @@ Mark is left at original location." | |||
| 930 | (push-mark) | 1089 | (push-mark) |
| 931 | (goto-char spot))) | 1090 | (goto-char spot))) |
| 932 | 1091 | ||
| 1092 | (defun latex-backward-sexp-1 () | ||
| 1093 | "Like (backward-sexp 1) but aware of multi-char elements." | ||
| 1094 | (let ((pos (point)) | ||
| 1095 | (forward-sexp-function)) | ||
| 1096 | (backward-sexp 1) | ||
| 1097 | (if (looking-at "\\\\begin\\>") | ||
| 1098 | (signal 'scan-error | ||
| 1099 | (list "Containing expression ends prematurely" | ||
| 1100 | (point) (prog1 (point) (goto-char pos)))) | ||
| 1101 | (when (eq (char-after) ?{) | ||
| 1102 | (let ((newpos (point))) | ||
| 1103 | (when (ignore-errors (backward-sexp 1) t) | ||
| 1104 | (if (looking-at "\\\\end\\>") | ||
| 1105 | (tex-last-unended-begin) | ||
| 1106 | (goto-char newpos)))))))) | ||
| 1107 | |||
| 1108 | (defun latex-forward-sexp-1 () | ||
| 1109 | "Like (forward-sexp 1) but aware of multi-char elements." | ||
| 1110 | (let ((pos (point)) | ||
| 1111 | (forward-sexp-function)) | ||
| 1112 | (forward-sexp 1) | ||
| 1113 | (let ((newpos (point))) | ||
| 1114 | (skip-syntax-backward "/w") | ||
| 1115 | (cond | ||
| 1116 | ((looking-at "\\\\end\\>") | ||
| 1117 | (signal 'scan-error | ||
| 1118 | (list "Containing expression ends prematurely" | ||
| 1119 | (point) | ||
| 1120 | (prog1 | ||
| 1121 | (progn (ignore-errors (forward-sexp 2)) (point)) | ||
| 1122 | (goto-char pos))))) | ||
| 1123 | ((looking-at "\\\\begin\\>") | ||
| 1124 | (goto-char (match-end 0)) | ||
| 1125 | (tex-next-unmatched-end)) | ||
| 1126 | (t (goto-char newpos)))))) | ||
| 1127 | |||
| 1128 | (defun latex-forward-sexp (&optional arg) | ||
| 1129 | "Like `forward-sexp' but aware of multi-char elements." | ||
| 1130 | (interactive "P") | ||
| 1131 | (unless arg (setq arg 1)) | ||
| 1132 | (let ((pos (point))) | ||
| 1133 | (condition-case err | ||
| 1134 | (while (/= arg 0) | ||
| 1135 | (setq arg | ||
| 1136 | (if (> arg 0) | ||
| 1137 | (progn (latex-forward-sexp-1) (1- arg)) | ||
| 1138 | (progn (latex-backward-sexp-1) (1+ arg))))) | ||
| 1139 | (scan-error | ||
| 1140 | (goto-char pos) | ||
| 1141 | (signal (car err) (cdr err)))))) | ||
| 1142 | |||
| 933 | (defun tex-close-latex-block () | 1143 | (defun tex-close-latex-block () |
| 934 | "Creates an \\end{...} to match the last unclosed \\begin{...}." | 1144 | "Creates an \\end{...} to match the last unclosed \\begin{...}." |
| 935 | (interactive "*") | 1145 | (interactive "*") |
| @@ -1461,23 +1671,6 @@ Runs the shell command defined by `tex-show-queue-command'." | |||
| 1461 | (tex-send-command tex-bibtex-command tex-out-file)) | 1671 | (tex-send-command tex-bibtex-command tex-out-file)) |
| 1462 | (tex-display-shell)) | 1672 | (tex-display-shell)) |
| 1463 | 1673 | ||
| 1464 | ;;;; | ||
| 1465 | ;;;; Outline support | ||
| 1466 | ;;;; | ||
| 1467 | |||
| 1468 | (defvar latex-outline-regexp | ||
| 1469 | (concat "\\\\" | ||
| 1470 | (regexp-opt (nconc (list "documentstyle" "documentclass" | ||
| 1471 | "begin{document}" "end{document}" | ||
| 1472 | "appendix") | ||
| 1473 | (mapcar 'car latex-section-alist)) t))) | ||
| 1474 | |||
| 1475 | (defun latex-outline-level () | ||
| 1476 | (if (looking-at latex-outline-regexp) | ||
| 1477 | (1+ (or (cdr (assoc (match-string 1) latex-section-alist)) -1)) | ||
| 1478 | 1000)) | ||
| 1479 | |||
| 1480 | |||
| 1481 | (run-hooks 'tex-mode-load-hook) | 1674 | (run-hooks 'tex-mode-load-hook) |
| 1482 | 1675 | ||
| 1483 | (provide 'tex-mode) | 1676 | (provide 'tex-mode) |