>>>>> Ikumi Keita <[email protected]> writes:
> Thanks for your comments. I'll install the proposed fix as well as
> macrocode*? support, unless Mosè or Tassilo objects explicitly.
> Since `LaTeX-find-matching-begin' and `LaTeX-current-environment' is
> very similar in their task in implementation, I probably factor out the
> common code and simplify.
My current status is the attached patch, but it fails with regression
test `LaTeX-change-environment-with-esc', of course. Mosè, Tassilo, do
you think that `LaTeX-modify-environment' should keep the ability to
change environment named "\foo{bar}"?
Regards,
Ikumi Keita
#StandWithUkraine #StopWarInUkraine
diff --git a/latex.el b/latex.el
index 29ac9502..f0dc898c 100644
--- a/latex.el
+++ b/latex.el
@@ -910,34 +910,45 @@ environment in commented regions with the same comment prefix.
The functions `LaTeX-find-matching-begin' and `LaTeX-find-matching-end'
work analogously."
+ (or (save-excursion (LaTeX-backward-up-environment arg t))
+ "document"))
+
+(defun LaTeX-backward-up-environment (&optional arg want-name)
+ "Move backward out of the enclosing environment.
+With optional ARG>=1, find that outer level.
+Return non-nil if the operation succeeded.
+Return the (outermost) environment name if WANT-NAME is non-nil.
+
+Assume the current point is on neither \"begin{foo}\" nor \"end{foo}\"."
(setq arg (if arg (if (< arg 1) 1 arg) 1))
(let* ((in-comment (TeX-in-commented-line))
(comment-prefix (and in-comment (TeX-comment-prefix)))
(case-fold-search nil))
- (save-excursion
- (while (and (/= arg 0)
- (re-search-backward
- "\\\\\\(begin\\|end\\) *{\\([^}]+\\)}" nil t))
- (when (or (and LaTeX-syntactic-comments
- (eq in-comment (TeX-in-commented-line))
- (or (not in-comment)
- ;; Consider only matching prefixes in the
- ;; commented case.
- (string= comment-prefix (TeX-comment-prefix))))
- (and (not LaTeX-syntactic-comments)
- (not (TeX-in-commented-line)))
- ;; macrocode*? in docTeX-mode is special since we
- ;; have also regular code lines not starting with a
- ;; comment-prefix. Hence, the next check just looks
- ;; if we're inside such a group and returns t to
- ;; recognize such a situation.
- (and (eq major-mode 'doctex-mode)
- (member (match-string-no-properties 2)
- '("macrocode" "macrocode*"))))
- (setq arg (if (string= (match-string 1) "end") (1+ arg) (1- arg)))))
- (if (/= arg 0)
- "document"
- (match-string-no-properties 2)))))
+ (while (and (/= arg 0)
+ (re-search-backward
+ "\\\\\\(begin\\|end\\) *{\\([^}]+\\)}" nil t))
+ (when (or (and LaTeX-syntactic-comments
+ (eq in-comment (TeX-in-commented-line))
+ (or (not in-comment)
+ ;; Consider only matching prefixes in the
+ ;; commented case.
+ (string= comment-prefix (TeX-comment-prefix))))
+ (and (not LaTeX-syntactic-comments)
+ (not (TeX-in-commented-line)))
+ ;; macrocode*? in docTeX-mode is special since we have
+ ;; also regular code lines not starting with a
+ ;; comment-prefix. Hence, the next check just looks
+ ;; if we're inside such a group and returns non-nil to
+ ;; recognize such a situation.
+ (and (eq major-mode 'doctex-mode)
+ (member (match-string-no-properties 2)
+ '("macrocode" "macrocode*"))))
+ (setq arg (if (= (char-after (match-beginning 1)) ?e)
+ (1+ arg)
+ (1- arg)))))
+ (if (= arg 0)
+ (or (not want-name)
+ (match-string-no-properties 2)))))
(defun docTeX-in-macrocode-p ()
"Determine if point is inside a macrocode environment."
@@ -5263,18 +5274,23 @@ If function is called inside a comment and
`LaTeX-syntactic-comments' is enabled, try to find the
environment in commented regions with the same comment prefix."
(interactive)
- (let* ((regexp (concat (regexp-quote TeX-esc) "\\(begin\\|end\\)\\b"))
+ (let* ((regexp (concat (regexp-quote TeX-esc)
+ "\\(begin\\|end\\) *{\\([^}]+\\)}"))
(level 1)
(in-comment (TeX-in-commented-line))
(comment-prefix (and in-comment (TeX-comment-prefix)))
(case-fold-search nil))
+ ;; The following code until `while' handles exceptional cases that
+ ;; the point is on "\begin{foo}" or "\end{foo}".
(let ((pt (point)))
- (skip-chars-backward (concat "a-zA-Z \t" (regexp-quote TeX-grop)))
+ (skip-chars-backward (concat "a-zA-Z* \t" TeX-grop))
(unless (bolp)
(backward-char 1)
(if (and (looking-at regexp)
- (char-equal (char-after (1+ (match-beginning 0))) ?e))
- (setq level 0)
+ (char-equal (char-after (match-beginning 1)) ?e))
+ (progn
+ (setq level 0)
+ (goto-char (match-end 0)))
(goto-char pt))))
(while (and (> level 0) (re-search-forward regexp nil t))
(when (or (and LaTeX-syntactic-comments
@@ -5284,14 +5300,21 @@ environment in commented regions with the same comment prefix."
(or (not in-comment)
(string= comment-prefix (TeX-comment-prefix))))
(and (not LaTeX-syntactic-comments)
- (not (TeX-in-commented-line))))
- (if (= (char-after (1+ (match-beginning 0))) ?b) ;;begin
- (setq level (1+ level))
- (setq level (1- level)))))
- (if (= level 0)
- (re-search-forward
- (concat TeX-grop (LaTeX-environment-name-regexp) TeX-grcl))
- (error "Can't locate end of current environment"))))
+ (not (TeX-in-commented-line)))
+ ;; macrocode*? in docTeX-mode is special since we have
+ ;; also regular code lines not starting with a
+ ;; comment-prefix. Hence, the next check just looks
+ ;; if we're inside such a group and returns non-nil to
+ ;; recognize such a situation.
+ (and (eq major-mode 'doctex-mode)
+ (member (match-string-no-properties 2)
+ '("macrocode" "macrocode*"))))
+ (setq level
+ (if (= (char-after (match-beginning 1)) ?b) ;;begin
+ (1+ level)
+ (1- level)))))
+ (or (= level 0)
+ (error "Can't locate end of current environment"))))
(defun LaTeX-find-matching-begin ()
"Move point to the \\begin of the current environment.
@@ -5300,30 +5323,17 @@ If function is called inside a comment and
`LaTeX-syntactic-comments' is enabled, try to find the
environment in commented regions with the same comment prefix."
(interactive)
- (let* ((regexp (concat (regexp-quote TeX-esc) "\\(begin\\|end\\)\\b"))
- (level 1)
- (in-comment (TeX-in-commented-line))
- (comment-prefix (and in-comment (TeX-comment-prefix)))
- (case-fold-search nil))
- (skip-chars-backward (concat "a-zA-Z \t" (regexp-quote TeX-grop)))
+ (let ((regexp (concat (regexp-quote TeX-esc) "begin\\b"))
+ done)
+ ;; The following code until `or' handles exceptional cases that
+ ;; the point is on "\begin{foo}" or "\end{foo}".
+ (skip-chars-backward (concat "a-zA-Z* \t" TeX-grop))
(unless (bolp)
(backward-char 1)
(and (looking-at regexp)
- (char-equal (char-after (1+ (match-beginning 0))) ?b)
- (setq level 0)))
- (while (and (> level 0) (re-search-backward regexp nil t))
- (when (or (and LaTeX-syntactic-comments
- (eq in-comment (TeX-in-commented-line))
- ;; If we are in a commented line, check if the
- ;; prefix matches the one we started out with.
- (or (not in-comment)
- (string= comment-prefix (TeX-comment-prefix))))
- (and (not LaTeX-syntactic-comments)
- (not (TeX-in-commented-line))))
- (if (= (char-after (1+ (match-beginning 0))) ?e) ;;end
- (setq level (1+ level))
- (setq level (1- level)))))
- (or (= level 0)
+ (setq done t)))
+ (or done
+ (LaTeX-backward-up-environment)
(error "Can't locate beginning of current environment"))))
(defun LaTeX-mark-environment (&optional count)