+ (1 (prog1 "\""
+ (tex-font-lock-verb
+ (match-beginning 0) (char-after (match-beginning 1))))))))
+
+ (defconst latex-syntax-propertize-rules
+ (syntax-propertize-precompile-rules
+ tex-syntax-propertize-rules
+ ("\\\\\\(?:end\\|begin\\) *\\({[^\n{}]*}\\)"
+ (1 (ignore
+ (tex-env-mark (match-beginning 0)
+ (match-beginning 1) (match-end 1))))))))
+
+(defun tex-env-mark (cmd start end)
+ (when (= cmd (line-beginning-position))
+ (let ((arg (buffer-substring-no-properties (1+ start) (1- end))))
+ (when (member arg tex-verbatim-environments)
+ (if (eq ?b (char-after (1+ cmd)))
+ ;; \begin
+ (put-text-property (line-end-position)
+ (line-beginning-position 2)
+ 'syntax-table (string-to-syntax "< c"))
+ ;; In the case of an empty verbatim env, the \n after the \begin is
+ ;; the same as the \n before the \end. Lucky for us, the "> c"
+ ;; property associated to the \end will be placed afterwards, so it
+ ;; will override the "< c".
+ (put-text-property (1- cmd) cmd
+ 'syntax-table (string-to-syntax "> c"))
+ ;; The text between \end{verbatim} and \n is ignored, so we'll treat
+ ;; it as a comment.
+ (put-text-property end (min (1+ end) (line-end-position))
+ 'syntax-table (string-to-syntax "<"))))))
+ ;; Mark env args for possible electric pairing.
+ (unless (get-char-property (1+ start) 'text-clones) ;Already paired-up.
+ (put-text-property start end 'latex-env-pair t)))
+
+(define-minor-mode latex-electric-env-pair-mode
+ "Automatically update the \\end arg when editing the \\begin one.
+And vice-versa."
+ :lighter "/e"
+ (if latex-electric-env-pair-mode
+ (add-hook 'before-change-functions
+ #'latex-env-before-change nil 'local)
+ (remove-hook 'before-change-functions
+ #'latex-env-before-change 'local)))
+
+(defun latex-env-before-change (start end)
+ (when (get-text-property start 'latex-env-pair)
+ (condition-case err
+ (with-silent-modifications
+ ;; Remove properties even if don't find a pair.
+ (remove-text-properties
+ (previous-single-property-change (1+ start) 'latex-env-pair)
+ (next-single-property-change start 'latex-env-pair)
+ '(latex-env-pair))
+ (unless (or (get-char-property start 'text-clones)
+ (get-char-property (1+ start) 'text-clones)
+ (save-excursion
+ (goto-char start)
+ (not (re-search-backward
+ "\\\\\\(?:end\\|begi\\(n\\)\\) *{"
+ (line-beginning-position) t))))
+ (let ((cmd-start (match-beginning 0))
+ (type (match-end 1)) ;nil for \end, else \begin.
+ (arg-start (1- (match-end 0))))
+ (save-excursion
+ (goto-char (match-end 0))
+ (when (and (looking-at "[^\n{}]*}")
+ (> (match-end 0) end))
+ (let ((arg-end (match-end 0)))
+ (if (null type) ;\end
+ (progn (goto-char arg-end)
+ (latex-forward-sexp -1) (forward-word 1))
+ (goto-char cmd-start)
+ (latex-forward-sexp 1)
+ (let (forward-sexp-function) (backward-sexp)))
+ (when (looking-at
+ (regexp-quote (buffer-substring arg-start arg-end)))
+ (text-clone-create arg-start arg-end))))))))
+ (scan-error nil)
+ (error (message "Error in latex-env-before-change: %s" err)))))