changeset 98341:6708b77f19bf

(latex-handle-escaped-parens): New variable. (latex-backward-sexp-1, latex-forward-sexp-1): Treat escaped parens specially only if latex-handle-escaped-parens is non-nil. (latex-indent-within-escaped-parens): New option. (latex-find-indent): Bind latex-handle-escaped-parens to latex-indent-within-escaped-parens. Do not treat escaped parens specially when this is non-nil. (Bug#954)
author Martin Rudalics <rudalics@gmx.at>
date Thu, 25 Sep 2008 08:37:06 +0000
parents ec3e7b117ca4
children 5ec221ffbf0e
files lisp/textmodes/tex-mode.el
diffstat 1 files changed, 116 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/textmodes/tex-mode.el	Thu Sep 25 07:45:35 2008 +0000
+++ b/lisp/textmodes/tex-mode.el	Thu Sep 25 08:37:06 2008 +0000
@@ -1482,18 +1482,25 @@
     (push-mark)
     (goto-char spot)))
 
+(defvar latex-handle-escaped-parens t)
+
 ;; Don't think this one actually _needs_ (for the purposes of
 ;; tex-mode) to handle escaped parens.
+;; Does not handle escaped parens when latex-handle-escaped-parens is nil.
 (defun latex-backward-sexp-1 ()
   "Like (backward-sexp 1) but aware of multi-char elements and escaped parens."
   (let ((pos (point))
 	(forward-sexp-function))
     (backward-sexp 1)
-    (cond ((looking-at "\\\\\\(begin\\>\\|[[({]\\)")
+    (cond ((looking-at
+	    (if latex-handle-escaped-parens
+		"\\\\\\(begin\\>\\|[[({]\\)"
+	      "\\\\begin\\>"))
 	   (signal 'scan-error
 		   (list "Containing expression ends prematurely"
 			 (point) (prog1 (point) (goto-char pos)))))
-	  ((looking-at "\\\\\\([])}]\\)")
+	  ((and latex-handle-escaped-parens
+		(looking-at "\\\\\\([])}]\\)"))
 	   (tex-last-unended-eparen (match-string 1)))
 	  ((eq (char-after) ?{)
 	   (let ((newpos (point)))
@@ -1508,6 +1515,7 @@
 ;; begin/end blocks.
 ;; Needs to handle escaped parens for tex-validate-*.
 ;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2007-09/msg00038.html
+;; Does not handle escaped parens when latex-handle-escaped-parens is nil.
 (defun latex-forward-sexp-1 ()
   "Like (forward-sexp 1) but aware of multi-char elements and escaped parens."
   (let ((pos (point))
@@ -1528,12 +1536,14 @@
 	(tex-next-unmatched-end))
        ;; A better way to handle this, \( .. \) etc, is probably to
        ;; temporarily change the syntax of the \ in \( to punctuation.
-       ((looking-back "\\\\[])}]")
+       ((and latex-handle-escaped-parens
+	     (looking-back "\\\\[])}]"))
 	(signal 'scan-error
 		(list "Containing expression ends prematurely"
 		      (- (point) 2) (prog1 (point)
 				      (goto-char pos)))))
-       ((looking-back "\\\\\\([({[]\\)")
+       ((and latex-handle-escaped-parens
+	     (looking-back "\\\\\\([({[]\\)"))
 	(tex-next-unmatched-eparen (match-string 1)))
        (t (goto-char newpos))))))
 
@@ -2568,103 +2578,115 @@
 	    (indent-line-to indent)
 	  (save-excursion (indent-line-to indent)))))))
 
+(defcustom latex-indent-within-escaped-parens nil
+  "Non-nil means add extra indent to text within escaped parens.
+When this is non-nil, text within matching pairs of escaped
+parens is indented at the column following the open paren.  The
+default value does not add any extra indent thus providing the
+behavior of Emacs 22 and earlier."
+  :type 'boolean
+  :group 'tex
+  :version "23.1")
+
 (defun latex-find-indent (&optional virtual)
   "Find the proper indentation of text after point.
 VIRTUAL if non-nil indicates that we're only trying to find the indentation
   in order to determine the indentation of something else.
 There might be text before point."
-  (save-excursion
-    (skip-chars-forward " \t")
-    (or
-     ;; Stick the first line at column 0.
-     (and (= (point-min) (line-beginning-position)) 0)
-     ;; Trust the current indentation, if such info is applicable.
-     (and virtual (save-excursion (skip-chars-backward " \t&") (bolp))
-	  (current-column))
-     ;; Stick verbatim environments to the left margin.
-     (and (looking-at "\\\\\\(begin\\|end\\) *{\\([^\n}]+\\)")
-	  (member (match-string 2) tex-verbatim-environments)
-	  0)
-     ;; Put leading close-paren where the matching open paren would be.
-     (let (escaped)
-       (and (or (eq (latex-syntax-after) ?\))
-		;; Try to handle escaped close parens but keep original
-		;; position if it doesn't work out.
-		(setq escaped (looking-at "\\\\\\([])}]\\)")))
-	    (ignore-errors
-	     (save-excursion
-	       (when escaped
-		 (goto-char (match-beginning 1)))
-	       (latex-skip-close-parens)
+  (let ((latex-handle-escaped-parens latex-indent-within-escaped-parens))
+    (save-excursion
+      (skip-chars-forward " \t")
+      (or
+       ;; Stick the first line at column 0.
+       (and (= (point-min) (line-beginning-position)) 0)
+       ;; Trust the current indentation, if such info is applicable.
+       (and virtual (save-excursion (skip-chars-backward " \t&") (bolp))
+	    (current-column))
+       ;; Stick verbatim environments to the left margin.
+       (and (looking-at "\\\\\\(begin\\|end\\) *{\\([^\n}]+\\)")
+	    (member (match-string 2) tex-verbatim-environments)
+	    0)
+       ;; Put leading close-paren where the matching open paren would be.
+       (let (escaped)
+	 (and (or (eq (latex-syntax-after) ?\))
+		  ;; Try to handle escaped close parens but keep
+		  ;; original position if it doesn't work out.
+		  (and latex-handle-escaped-parens
+		       (setq escaped (looking-at "\\\\\\([])}]\\)"))))
+	      (ignore-errors
+	       (save-excursion
+		 (when escaped
+		   (goto-char (match-beginning 1)))
+		 (latex-skip-close-parens)
+		 (latex-backward-sexp-1)
+		 (latex-find-indent 'virtual)))))
+       ;; Default (maybe an argument)
+       (let ((pos (point))
+	     ;; Outdent \item if necessary.
+	     (indent (if (looking-at tex-indent-item-re) (- tex-indent-item) 0))
+	     up-list-pos)
+	 ;; Find the previous point which determines our current indentation.
+	 (condition-case err
+	     (progn
 	       (latex-backward-sexp-1)
-	       (latex-find-indent 'virtual)))))
-     ;; Default (maybe an argument)
-     (let ((pos (point))
-	   ;; Outdent \item if necessary.
-	   (indent (if (looking-at tex-indent-item-re) (- tex-indent-item) 0))
-	   up-list-pos)
-       ;; Find the previous point which determines our current indentation.
-       (condition-case err
-	   (progn
-	     (latex-backward-sexp-1)
-	     (while (> (current-column) (current-indentation))
-	       (latex-backward-sexp-1)))
-	 (scan-error
-	  (setq up-list-pos (nth 2 err))))
-       (cond
-	((= (point-min) pos) 0) ; We're really just indenting the first line.
-	((integerp up-list-pos)
-	 ;; Have to indent relative to the open-paren.
-	 (goto-char up-list-pos)
-	 (if (and (not tex-indent-allhanging)
-		  (save-excursion
-		    ;; Make sure we're an argument to a macro and
-		    ;; that the macro is at the beginning of a line.
-		    (condition-case nil
-			(progn
-			  (while (eq (char-syntax (char-after)) ?\()
-			    (forward-sexp -1))
-			  (and (eq (char-syntax (char-after)) ?/)
-			       (progn (skip-chars-backward " \t&")
-				      (bolp))))
-		      (scan-error nil)))
-		  (> pos (progn (latex-down-list)
-				(forward-comment (point-max))
-				(point))))
-		 ;; Align with the first element after the open-paren.
-	     (current-column)
-	   ;; We're the first element after a hanging brace.
+	       (while (> (current-column) (current-indentation))
+		 (latex-backward-sexp-1)))
+	   (scan-error
+	    (setq up-list-pos (nth 2 err))))
+	 (cond
+	  ((= (point-min) pos) 0) ; We're really just indenting the first line.
+	  ((integerp up-list-pos)
+	   ;; Have to indent relative to the open-paren.
 	   (goto-char up-list-pos)
-	   (+ (if (and (looking-at "\\\\begin *{\\([^\n}]+\\)")
-		       (member (match-string 1)
-			       latex-noindent-environments))
-		  0 tex-indent-basic)
-	      indent (latex-find-indent 'virtual))))
-	;; We're now at the "beginning" of a line.
-	((not (and (not virtual) (eq (char-after) ?\\)))
-	 ;; Nothing particular here: just keep the same indentation.
-	 (+ indent (current-column)))
-	;; We're now looking at a macro call.
-	((looking-at tex-indent-item-re)
-	 ;; Indenting relative to an item, have to re-add the outdenting.
-	 (+ indent (current-column) tex-indent-item))
-	(t
-	 (let ((col (current-column)))
-	   (if (or (not (eq (char-syntax (or (char-after pos) ?\s)) ?\())
-		   ;; Can't be an arg if there's an empty line inbetween.
-		   (save-excursion (re-search-forward "^[ \t]*$" pos t)))
-	       ;; If the first char was not an open-paren, there's
-	       ;; a risk that this is really not an argument to the
-	       ;; macro at all.
-	       (+ indent col)
-	     (forward-sexp 1)
-	     (if (< (line-end-position)
-		    (save-excursion (forward-comment (point-max))
-				    (point)))
-		 ;; we're indenting the first argument.
-		 (min (current-column) (+ tex-indent-arg col))
-	       (skip-syntax-forward " ")
-	       (current-column))))))))))
+	   (if (and (not tex-indent-allhanging)
+		    (save-excursion
+		      ;; Make sure we're an argument to a macro and
+		      ;; that the macro is at the beginning of a line.
+		      (condition-case nil
+			  (progn
+			    (while (eq (char-syntax (char-after)) ?\()
+			      (forward-sexp -1))
+			    (and (eq (char-syntax (char-after)) ?/)
+				 (progn (skip-chars-backward " \t&")
+					(bolp))))
+			(scan-error nil)))
+		    (> pos (progn (latex-down-list)
+				  (forward-comment (point-max))
+				  (point))))
+	       ;; Align with the first element after the open-paren.
+	       (current-column)
+	     ;; We're the first element after a hanging brace.
+	     (goto-char up-list-pos)
+	     (+ (if (and (looking-at "\\\\begin *{\\([^\n}]+\\)")
+			 (member (match-string 1)
+				 latex-noindent-environments))
+		    0 tex-indent-basic)
+		indent (latex-find-indent 'virtual))))
+	  ;; We're now at the "beginning" of a line.
+	  ((not (and (not virtual) (eq (char-after) ?\\)))
+	   ;; Nothing particular here: just keep the same indentation.
+	   (+ indent (current-column)))
+	  ;; We're now looking at a macro call.
+	  ((looking-at tex-indent-item-re)
+	   ;; Indenting relative to an item, have to re-add the outdenting.
+	   (+ indent (current-column) tex-indent-item))
+	  (t
+	   (let ((col (current-column)))
+	     (if (or (not (eq (char-syntax (or (char-after pos) ?\s)) ?\())
+		     ;; Can't be an arg if there's an empty line inbetween.
+		     (save-excursion (re-search-forward "^[ \t]*$" pos t)))
+		 ;; If the first char was not an open-paren, there's
+		 ;; a risk that this is really not an argument to the
+		 ;; macro at all.
+		 (+ indent col)
+	       (forward-sexp 1)
+	       (if (< (line-end-position)
+		      (save-excursion (forward-comment (point-max))
+				      (point)))
+		   ;; we're indenting the first argument.
+		   (min (current-column) (+ tex-indent-arg col))
+		 (skip-syntax-forward " ")
+		 (current-column)))))))))))
 ;;; DocTeX support
 
 (defun doctex-font-lock-^^A ()