branch: main
commit 2d271c90605476024c474194aca615bdf4a8ab90
Merge: 6b1c1f6d d0af6f6c
Author: Arash Esbati <ar...@gnu.org>
Commit: Arash Esbati <ar...@gnu.org>

    Merge remote-tracking branch 'origin/master'
---
 NEWS.org           |  34 +++++
 doc/auctex.texi    |  27 ++--
 doc/changes.texi   |  34 ++++-
 font-latex.el      |  15 ++-
 latex.el           | 184 ++++++++++++-------------
 style/changebar.el |  21 ++-
 style/color.el     | 366 +++++++++++++++++++++++++++-----------------------
 style/colortbl.el  | 131 +++++++++++++-----
 style/dinbrief.el  |  69 +++++++---
 style/floatrow.el  |   7 +-
 style/paracol.el   | 128 ++++++++++++++----
 style/xcolor.el    | 386 ++++++++++++++++++++++++++++++++---------------------
 tex.el             | 317 ++++++++++++++++++++++++-------------------
 13 files changed, 1058 insertions(+), 661 deletions(-)

diff --git a/NEWS.org b/NEWS.org
index 451056a7..92c41293 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -6,6 +6,40 @@
 # License: GNU General Public License 3
 # The format is based on [[https://keepachangelog.com/en/1.1.0/][Keep a 
Changelog]]
 
+* [Unreleased]
+
+** Fixed
+
+- Add appropriate ~delete-selection~ properties for
+  ~LaTeX-insert-left-brace~, ~TeX-insert-dollar~ and
+  ~TeX-insert-backslash~ that differentiate between the "electric" and
+  "just-insert-the-symbol" behavior.  That should simplify cooperation
+  with other electric modes.
+
+  As a result of this adjustment, the behavior of ~TeX-insert-dollar~
+  is affected in some ways:
+  - With raw prefix argument =C-u=, =$= (~TeX-insert-dollar~) now
+    inserts four dollars as opposed to one.  This behavior is in-line
+    with other symbols, in particular ="= (~TeX-insert-quote~) and =\=
+    (~TeX-insert-backslash~).  If you need one literal =$=, you can type
+    =C-1 $= or =C-q $=.
+  - We no longer have explicit support of the special behavior that if
+    ~TeX-electric-math~ is non-nil and point is inside math mode right
+    between a couple of single dollars, pressing =$= will insert another
+    pair of dollar signs and leave the point between them.
+
+    It still works as before if ~TeX-electric-math~ is pair of dollars
+    while it inserts =\(= and =\)= when ~TeX-electric-math~ is
+    =("\(" . "\)")=.
+  - When ~TeX-electric-math~ is a pair of dollars and the point is in
+    inline math (without active region), =$= inserts two dollars, not
+    one dollar which just closes the math mode.
+- Recognize =.ltx= extension as regular LaTeX file.
+
+** Removed
+
+- Delete function ~LaTeX-env-contents~.
+
 * [14.0.5] - 2024-05-19
 
 ** Added
diff --git a/doc/auctex.texi b/doc/auctex.texi
index 05695f0f..f57fa752 100644
--- a/doc/auctex.texi
+++ b/doc/auctex.texi
@@ -413,7 +413,7 @@ first dollar sign.
 
 @deffn Command TeX-insert-dollar @var{arg}
 @kindex $
-(@kbd{$}) Insert dollar sign.
+(@kbd{$}) Insert dollar sign (or another math delimiter).
 
 Show matching dollar sign if this dollar sign end the @TeX{} math mode.
 
@@ -437,14 +437,6 @@ Besides @code{nil}, possible values for this variable are 
@code{("$"
 . "$")} for @TeX{} inline equations @samp{$...$}, and @code{("\(" . "\)")}
 for @LaTeX{} inline equations @samp{\(...\)}.
 
-If the variable is non-@code{nil} and point is inside math mode right
-between a couple of single dollars, pressing @kbd{$} will insert another
-pair of dollar signs and leave the point between them.  Thus, if
-@code{TeX-electric-math} is set to @code{("$" . "$")} you can easily
-obtain a @TeX{} display equation @samp{$$...$$} by pressing @kbd{$} twice
-in a row.  (Note that you should not use double dollar signs in @LaTeX{}
-because this practice can lead to wrong spacing in typeset documents.)
-
 In addition, when the variable is non-@code{nil} and there is an active
 region outside math mode, typing @kbd{$} will put around the active region
 symbols for opening and closing inline equation and keep the region
@@ -469,6 +461,9 @@ following to your init file
 
 Math mode which didn't start with dollar(s) shouldn't be closed with dollar.
 @defopt TeX-refuse-unmatched-dollar
+This option @emph{has no effect} when @code{TeX-electric-math} is
+non-@code{nil}.
+
 This option determines the behavior when the user types @kbd{$} at a
 position where @AUCTeX{} thinks that it is in math mode which didn't start
 with dollar(s).
@@ -4452,9 +4447,10 @@ it is a good idea to append a @code{TeX-master} file 
variable entry
 automatically.  When @AUCTeX{} adds the name of the master file as a
 file variable, it does not need to ask next time you edit the file.
 
-If you dislike @AUCTeX{} automatically modifying your files, you can
-set this variable to @samp{"<none>"}.  By default, @AUCTeX{} will modify
-any file with an extension of @samp{.tex}, @samp{.texi} or @samp{.dtx}.
+If you dislike @AUCTeX{} automatically modifying your files, you can set
+this variable to @samp{"<none>"}.  By default, @AUCTeX{} will modify any
+file with an extension of @samp{.tex}, @samp{.ltx}, @samp{.texi} or
+@samp{.dtx}.
 @end defopt
 
 @deffn Command TeX-master-file-ask
@@ -5326,7 +5322,7 @@ Here is a simple example of a style file.
 
 (TeX-add-style-hook
  "book"
- (lambda () 
+ (lambda ()
    (LaTeX-largest-level-set "part"))
  TeX-dialect)
 @end lisp
@@ -5839,9 +5835,6 @@ Insert the given environment with width and height 
specifications.
 @item LaTeX-env-bib
 Insert the given environment with a label for a bibitem.
 
-@item LaTeX-env-contents
-Insert the given environment with a filename as its argument.
-
 @item LaTeX-env-args
 Insert the given environment with arguments.  You can use this as a hook
 in case you want to specify multiple complex arguments just like in
@@ -6293,7 +6286,7 @@ buffer.  Note that you can make, say @samp{Makeinfo}, the 
default by
 adding this statement in your init file:
 
 @lisp
-(add-hook 'Texinfo-mode-hook 
+(add-hook 'Texinfo-mode-hook
           (lambda () (setq TeX-command-default "Makeinfo")))
 @end lisp
 
diff --git a/doc/changes.texi b/doc/changes.texi
index 0d57a654..a8de7322 100644
--- a/doc/changes.texi
+++ b/doc/changes.texi
@@ -213,6 +213,38 @@ Now synctex option is @option{--synctex=repeat} instead of
 ignores @option{--synctex} option if @option{--nonstop} is present.
 @end itemize
 
+@item
+@code{LaTeX-insert-left-brace}, @code{TeX-insert-dollar} and
+@code{TeX-insert-backslash} now have appropriate @code{delete-selection}
+properties, that differentiate between the ``electric'' and
+``just-insert-the-symbol'' behavior.  That should simplify cooperation
+with other electric modes.
+
+As a result of this adjustment, the behavior of @code{TeX-insert-dollar}
+is affected in some ways:
+@itemize @minus
+@item
+With raw prefix argument @kbd{C-u}, @kbd{$} (@code{TeX-insert-dollar}) now
+inserts four dollars as opposed to one.  This behavior is in-line with
+other symbols, in particular @kbd{"} (@code{TeX-insert-quote}) and @kbd{\}
+(@code{TeX-insert-backslash}).  If you need one literal @samp{$}, you can
+type @kbd{C-1 $} or @kbd{C-q $}.
+@item
+We no longer have explicit support of the special behavior that
+if @code{TeX-electric-math} is non-nil and point is inside math
+mode right between a couple of single dollars, pressing @kbd{$}
+will insert another pair of dollar signs and leave the point
+between them.
+
+It still works as before if @code{TeX-electric-math} is pair of dollars
+while it inserts @samp{\(} and @samp{\)} when @code{TeX-electric-math} is
+@code{("\(" . "\)")}.
+@item
+When @code{TeX-electric-math} is a pair of dollars and the point is in
+inline math (without active region), @kbd{$} inserts two dollars, not one
+dollar which just closes the math mode.
+@end itemize
+
 @item
 @AUCTeX{} now requires GNU Emacs 27.1 or higher.
 @end itemize
@@ -1621,7 +1653,7 @@ Verbatim commands like @samp{\verb|...|} will not be 
broken anymore
 during filling.
 
 @item
-You can customize the completion for graphic files with 
+You can customize the completion for graphic files with
 @code{LaTeX-includegraphics-read-file}.
 
 @item
diff --git a/font-latex.el b/font-latex.el
index ccddd8b1..d814642a 100644
--- a/font-latex.el
+++ b/font-latex.el
@@ -1473,12 +1473,21 @@ ignored during the search."
         ;; closing brace gets a comment end syntax.
         ;; (2022 Mar) The latter half of the above paragraph no longer
         ;; applies since we changed the way to fontify ^^A comment.
-        (parse-sexp-lookup-properties nil))
+        (parse-sexp-lookup-properties nil)
+        (syntax (TeX-search-syntax-table openchar closechar)))
     (or
      (condition-case nil
          (progn
-           (goto-char (with-syntax-table
-                          (TeX-search-syntax-table openchar closechar)
+           ;; It is possible to have an opt. arg like \foo[key={]}].
+           ;; Since braces are always balanced in opt. arguments, we
+           ;; change the syntax to "generic comment delimiter".  For the
+           ;; backslash, we switch to "/" in order to ignore things like
+           ;; \{ and \}:
+           (unless (and (= openchar ?\{) (= closechar ?\}))
+             (modify-syntax-entry ?\{ "|" syntax)
+             (modify-syntax-entry ?\} "|" syntax)
+             (modify-syntax-entry ?\\ "/" syntax))
+           (goto-char (with-syntax-table syntax
                         (scan-sexps (point) 1)))
            ;; No error code.  See if closechar is unquoted
            (save-excursion
diff --git a/latex.el b/latex.el
index acdb5f73..d0a9ee6f 100644
--- a/latex.el
+++ b/latex.el
@@ -583,7 +583,7 @@ Styles such as tabularx may set it according to their 
needs.")
 
 (defun LaTeX-environment (arg)
   "Make LaTeX environment (\\begin{...}-\\end{...} pair).
-With optional ARG, modify current environment.
+With prefix ARG, modify current environment.
 
 It may be customized with the following variables:
 
@@ -652,7 +652,7 @@ It may be customized with the following variables:
 
 (defun LaTeX-close-environment (&optional reopen)
   "Create an \\end{...} to match the current environment.
-With prefix-argument, reopen environment afterwards."
+With prefix argument REOPEN, reopen environment afterwards."
   (interactive "*P")
   (if (> (point)
          (save-excursion
@@ -1451,25 +1451,6 @@ Just like array and tabular."
   (delete-horizontal-space)
   (LaTeX-insert-item))
 
-(defun LaTeX-env-contents (environment)
-  "Insert ENVIRONMENT with optional argument and filename for contents."
-  (let* ((opt '("overwrite" "force" "nosearch" "nowarn"))
-         (arg (mapconcat #'identity
-                         (TeX-completing-read-multiple
-                          (TeX-argument-prompt t nil "Options")
-                          (if (string= environment "filecontents*")
-                              opt
-                            (cons "noheader" opt)))
-                         ",")))
-    (LaTeX-insert-environment environment
-                              (concat
-                               (when (and arg (not (string= arg "")))
-                                 (concat LaTeX-optop arg LaTeX-optcl))
-                               TeX-grop
-                               (TeX-read-string "File: ")
-                               TeX-grcl)))
-  (delete-horizontal-space))
-
 (defun LaTeX-env-args (environment &rest args)
   "Insert ENVIRONMENT and arguments defined by ARGS."
   (LaTeX-insert-environment environment)
@@ -2510,7 +2491,7 @@ the list of defined counters."
   "Prompt for a LaTeX savebox.
 If OPTIONAL is non-nil, insert the resulting value as an optional
 argument, otherwise as a mandatory one.  Use PROMPT as the prompt
-string.  If definition is non-nil, the savebox is added to the
+string.  If DEFINITION is non-nil, the savebox is added to the
 list of defined saveboxes."
   (let ((savebox (completing-read (TeX-argument-prompt optional prompt
                                                        (concat "Savebox: "
@@ -3304,80 +3285,65 @@ supply the corresponding macro such as \\right before 
the right brace macro."
         (LaTeX-insert-corresponding-right-macro-and-brace
          left-macro left-brace optional)))))
 
+(defun LaTeX-insert-left-brace-electric (brace)
+  "Insert typed left BRACE and a corresponding right brace.
+
+BRACE should be a character.  See `LaTeX-insert-left-brace' for
+allowed BRACE values."
+  (when (and (TeX-active-mark) (> (point) (mark)))
+    (exchange-point-and-mark))
+  (let ((lbrace (char-to-string brace)) lmacro skip-p)
+    ;; Use `insert' rather than `self-insert-command' so that
+    ;; unexpected side effects from `post-self-insert-hook',
+    ;; e.g. `electric-pair-mode', won't mess up the following
+    ;; outcomes. (bug#47936)
+    (insert brace)
+    (save-excursion
+      (backward-char)
+      ;; The brace "{" is exceptional in two aspects.
+      ;; 1. "\{" should be considered as a single brace
+      ;;    like "(" and "[".
+      ;; 2. "\left{" is nonsense while "\left\{" and
+      ;;    "\left(" are not.
+      (if (string= lbrace TeX-grop)
+          ;; If "{" follows "\", set lbrace to "\{".
+          (if (TeX-escaped-p)
+              (progn
+                (backward-char)
+                (setq lbrace (concat TeX-esc TeX-grop)))
+            ;; Otherwise, don't search for left macros.
+            (setq skip-p t)))
+      (unless skip-p
+        ;; Obtain the name of preceding left macro, if any,
+        ;; such as "left", "bigl" etc.
+        (setq lmacro (LaTeX--find-preceding-left-macro-name))))
+    (let ((TeX-arg-right-insert-p t)
+          ;; "{" and "}" are paired temporally so that typing
+          ;; a single "{" should insert a pair "{}".
+          (TeX-braces-association
+           (cons (cons TeX-grop TeX-grcl) TeX-braces-association)))
+      (save-excursion
+        (if (TeX-active-mark)
+            (goto-char (mark)))
+        (LaTeX-insert-corresponding-right-macro-and-brace
+         lmacro lbrace)))))
+
 (defun LaTeX-insert-left-brace (arg)
-  "Insert typed left brace ARG times and possibly a correspondig right brace.
+  "Insert typed left brace ARG times and possibly a corresponding right brace.
 Automatic right brace insertion is done only if no prefix ARG is given and
 `LaTeX-electric-left-right-brace' is non-nil.
 Normally bound to keys \(, { and [."
   (interactive "*P")
-  ;; If you change the condition for `auto-p', adjust the condition in
-  ;; the `delete-selection' property, just below this defun, accordingly.
-  (let ((auto-p (and LaTeX-electric-left-right-brace (not arg))))
-    (if (and auto-p
-             (TeX-active-mark)
-             (> (point) (mark)))
-        (exchange-point-and-mark))
-    (if auto-p
-        ;; Should supply corresponding right brace with possible
-        ;; \right-like macro.
-        (let ((lbrace (char-to-string last-command-event)) lmacro skip-p)
-          ;; Use `insert' rather than `self-insert-command' so that
-          ;; unexcpected side effects, e.g. `electric-pair-mode',
-          ;; won't mess up the following outcomes. (bug#47936)
-          (insert last-command-event)
-          (save-excursion
-            (backward-char)
-            ;; The brace "{" is exceptional in two aspects.
-            ;; 1. "\{" should be considered as a single brace
-            ;;    like "(" and "[".
-            ;; 2. "\left{" is nonsense while "\left\{" and
-            ;;    "\left(" are not.
-            (if (string= lbrace TeX-grop)
-                ;; If "{" follows "\", set lbrace to "\{".
-                (if (TeX-escaped-p)
-                    (progn
-                      (backward-char)
-                      (setq lbrace (concat TeX-esc TeX-grop)))
-                  ;; Otherwise, don't search for left macros.
-                  (setq skip-p t)))
-            (unless skip-p
-              ;; Obtain the name of preceding left macro, if any,
-              ;; such as "left", "bigl" etc.
-              (setq lmacro (LaTeX--find-preceding-left-macro-name))))
-          (let ((TeX-arg-right-insert-p t)
-                ;; "{" and "}" are paired temporally so that typing
-                ;; a single "{" should insert a pair "{}".
-                (TeX-braces-association
-                 (cons (cons TeX-grop TeX-grcl) TeX-braces-association)))
-            (save-excursion
-              (if (TeX-active-mark)
-                  (goto-char (mark)))
-              (LaTeX-insert-corresponding-right-macro-and-brace
-               lmacro lbrace))))
-      ;; Don't supply right brace and just act as ordinary
-      ;; `self-insert-command'.
-      (self-insert-command (prefix-numeric-value arg)))))
-;; Cater for `delete-selection-mode' (bug#36385)
-;; See the header comment of delsel.el for detail.
-(put #'LaTeX-insert-left-brace 'delete-selection
-     (lambda ()
-       ;; Consult `delete-selection' property when
-       ;; `LaTeX-insert-left-brace' works just the same as
-       ;; `self-insert-command'.
-       (and (or (not LaTeX-electric-left-right-brace)
-                current-prefix-arg)
-            (let ((f (get #'self-insert-command 'delete-selection)))
-              ;; If `delete-selection' property of
-              ;; `self-insert-command' is one of the predefined
-              ;; special symbols, just return itself.
-              (if (memq f '(yank supersede kill t nil))
-                  ;; FIXME: if this list of special symbols is
-                  ;; extended in future delsel.el, this discrimination
-                  ;; will become wrong.
-                  f
-                ;; Otherwise, call it as a function and return
-                ;; its value.
-                (funcall f))))))
+  (if (and LaTeX-electric-left-right-brace (not arg))
+      (LaTeX-insert-left-brace-electric last-command-event)
+    (self-insert-command (prefix-numeric-value arg))))
+
+;; Cater for `delete-selection-mode' (bug#36385). See the header
+;; comment of delsel.el for detail.  In short, whenever a function
+;; performs insertion, we ``inherit'' the `delete-selection' property.
+(TeX--put-electric-delete-selection
+ #'LaTeX-insert-left-brace
+ (lambda () (and LaTeX-electric-left-right-brace (not current-prefix-arg))))
 
 (defun LaTeX-insert-corresponding-right-macro-and-brace
     (lmacro lbrace &optional optional prompt)
@@ -5300,6 +5266,9 @@ See `fill-move-to-break-point' for the meaning of 
LINEBEG."
 
 (defun LaTeX-fill-paragraph (&optional justify)
   "Like `fill-paragraph', but handle LaTeX comments.
+
+With prefix argument JUSTIFY, justify as well.
+
 If any of the current line is a comment, fill the comment or the
 paragraph of it that point is in.  Code comments, that is, comments
 with uncommented code preceding them in the same line, will not
@@ -5598,7 +5567,9 @@ environments."
     (TeX-activate-region)))
 
 (defun LaTeX-fill-environment (justify)
-  "Fill and indent current environment as LaTeX text."
+  "Fill and indent current environment as LaTeX text.
+
+With prefix argument JUSTIFY, justify as well."
   (interactive "*P")
   (save-excursion
     (LaTeX-mark-environment)
@@ -5607,7 +5578,9 @@ environments."
                        (concat " environment " (TeX-match-buffer 1)))))
 
 (defun LaTeX-fill-section (justify)
-  "Fill and indent current logical section as LaTeX text."
+  "Fill and indent current logical section as LaTeX text.
+
+With prefix argument JUSTIFY, justify as well."
   (interactive "*P")
   (save-excursion
     (LaTeX-mark-section)
@@ -5642,7 +5615,9 @@ value of NO-SUBSECTIONS."
   (TeX-activate-region))
 
 (defun LaTeX-fill-buffer (justify)
-  "Fill and indent current buffer as LaTeX text."
+  "Fill and indent current buffer as LaTeX text.
+
+With prefix argument JUSTIFY, justify as well."
   (interactive "*P")
   (save-excursion
     (LaTeX-fill-region
@@ -8758,8 +8733,14 @@ function would return non-nil and `(match-string 1)' 
would return
 
   (when (string-equal LaTeX-version "2e")
     (LaTeX-add-environments
-     '("filecontents" LaTeX-env-contents)
-     '("filecontents*" LaTeX-env-contents))
+     '("filecontents" LaTeX-env-args
+       [TeX-arg-completing-read-multiple
+        ("overwrite" "force" "nosearch" "nowarn" "noheader")]
+       "File")
+     '("filecontents*" LaTeX-env-args
+       [TeX-arg-completing-read-multiple
+        ("overwrite" "force" "nosearch" "nowarn")]
+       "File"))
 
     (TeX-add-symbols
      '("enlargethispage"  (TeX-arg-length nil "1.0\\baselineskip"))
@@ -9376,12 +9357,11 @@ arguments POS and COL for efficiency."
 
 (defmacro LaTeX-check-insert-macro-default-style (&rest body)
   "Check for values of `TeX-insert-macro-default-style' and 
`current-prefix-arg'.
-This is a utility macro with code taken from
-`TeX-parse-arguments'.  It should be used inside more complex
-function within AUCTeX style files where optional and mandatory
-arguments are queried and inserted.  For examples, check the
-functions `TeX-arg-color' (style/color.el) or
-`LaTeX-arg-bicaption-bicaption' (style/bicaption.el)."
+This is a utility macro with code taken from `TeX-parse-arguments'.  It
+should be used inside more complex function within AUCTeX style files
+where optional and mandatory arguments are queried and inserted.  For
+example, check the function `LaTeX-arg-bicaption-bicaption'
+defined in style/bicaption.el."
   `(unless (if (eq TeX-insert-macro-default-style 'show-all-optional-args)
                (equal current-prefix-arg '(4))
              (or
diff --git a/style/changebar.el b/style/changebar.el
index b3020bd7..7783b94e 100644
--- a/style/changebar.el
+++ b/style/changebar.el
@@ -60,11 +60,26 @@
    ;; Options management:
    (when (LaTeX-provided-package-options-member "changebar" "color")
      (TeX-run-style-hooks "color")
-     (TeX-add-symbols '("cbcolor" TeX-arg-color)))
+     (TeX-add-symbols
+      '("cbcolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name"))))))
 
    (when (LaTeX-provided-package-options-member "changebar" "xcolor")
      (TeX-run-style-hooks "xcolor")
-     (TeX-add-symbols '("cbcolor" TeX-arg-xcolor)))
+     (TeX-add-symbols
+      '("cbcolor"
+        [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                          "Color model"
+                                          nil nil "/" "/"]
+        (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+            (TeX-arg-xcolor)
+          ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                    "Color name"))))))
 
    (when (or (LaTeX-provided-package-options-member "changebar" "xetex")
              (LaTeX-provided-package-options-member "changebar" "XeTeX"))
@@ -111,3 +126,5 @@
     "grey" "color" "xcolor")
   "Package options for the changebar package.
 This variable contains only the lowercase version of the options.")
+
+;;; changebar.el ends here
diff --git a/style/color.el b/style/color.el
index a98b01bd..76f80209 100644
--- a/style/color.el
+++ b/style/color.el
@@ -1,6 +1,6 @@
 ;;; color.el --- AUCTeX style for `color.sty' (v1.3d)  -*- lexical-binding: t; 
-*-
 
-;; Copyright (C) 2015--2022 Free Software Foundation, Inc.
+;; Copyright (C) 2015--2024 Free Software Foundation, Inc.
 
 ;; Author: Arash Esbati <ar...@gnu.org>
 ;; Maintainer: auctex-devel@gnu.org
@@ -34,7 +34,7 @@
 
 ;;; Code:
 
-;; Needed for compiling `LaTeX-check-insert-macro-default-style':
+(require 'tex)
 (require 'latex)
 
 ;; Silence the compiler:
@@ -66,9 +66,6 @@
     "WildStrawberry" "Yellow"          "YellowGreen"  "YellowOrange")
   "List of colors defined by package option `dvipsnames' from `color.sty'.")
 
-;; Needed for auto-parsing.
-(require 'tex)
-
 ;; Plug \definecolor into the parser
 (TeX-auto-add-type "color-definecolor" "LaTeX")
 
@@ -83,167 +80,148 @@
 (add-hook 'TeX-auto-prepare-hook #'LaTeX-color-auto-prepare t)
 (add-hook 'TeX-update-style-hook #'TeX-auto-parse t)
 
-(defun TeX-arg-color-definecolor (optional &optional prompt)
-  "Insert arguments of `\\definecolor' from `color.sty'."
+(defconst LaTeX-color-used-model-regexp
+  (concat (regexp-quote TeX-esc)
+          (regexp-opt '("color" "textcolor"
+                        "mathcolor" "pagecolor"
+                        "colorbox" "fcolorbox"
+                        ;; changebar.el
+                        "cbcolor"
+                        ;; colortbl.el
+                        "columncolor" "rowcolor" "cellcolor"
+                        "arrayrulecolor" "doublerulesepcolor"
+                        ;; paracol.el also provides a columncolor which
+                        ;; we don't repeat:
+                        "colseprulecolor"))
+          "\\(?:\\[\\([^]]+\\)\\]\\)?")
+  "Regexp for matching the optional argument of color macros.")
+
+(defvar-local LaTeX-color-used-model nil
+  "Variable containing the color model from last search.
+It is set by the function `LaTeX-color-used-model'.")
+
+(defun LaTeX-color-used-model-requires-spec-p ()
+  "Return non-nil if the used color model requires color specification."
+  (and (save-excursion
+         (re-search-backward LaTeX-color-used-model-regexp
+                             (line-beginning-position) t)
+         (setq LaTeX-color-used-model (match-string-no-properties 1)))
+       (not (string= LaTeX-color-used-model "named"))))
+
+(defun LaTeX-color-available-models ()
+  "Return a list of available color models."
+  (if (or (LaTeX-provided-package-options-member "color" "dvips")
+          (LaTeX-provided-package-options-member "color" "dvipsnames"))
+      LaTeX-color-colour-models
+    (remove "named" LaTeX-color-colour-models)))
+
+(defun LaTeX-color-available-colors ()
+  "Return a list of available colors."
+  (if (string= LaTeX-color-used-model "named")
+      LaTeX-color-dvipsnames-colors
+    (LaTeX-color-definecolor-list)))
+
+(defun TeX-arg-color-definecolor (optional)
+  "Insert <color spec> argument of \\definecolor from color.sty.
+If OPTIONAL is non-nil, insert the argument when non-empty and in
+brackets.  The \"named\" color model is handled inside the hook and not
+in this function."
   ;; \definecolor{<name>}{<model>}{<color spec>}
-  ;; Ask for <name>, add to our list and insert it
-  (let ((colorname (TeX-read-string "Color name: ")))
-    (LaTeX-add-color-definecolors colorname)
-    (TeX-argument-insert colorname optional))
-  ;; Ask and insert <model>
-  (let ((model (completing-read
-                (TeX-argument-prompt optional prompt "Color model")
-                (if (not (or (LaTeX-provided-package-options-member "color" 
"dvips")
-                             (LaTeX-provided-package-options-member "color" 
"dvipsnames")))
-                    (remove "named" LaTeX-color-colour-models)
-                  LaTeX-color-colour-models))))
-    (TeX-argument-insert model optional)
-    ;; Depending on <model>, ask for <color spec> and insert it
-    (cond (;; <cmyk> model
-           (string-equal model "cmyk")
-           (let ((cyan    (TeX-read-string "Value Cyan (between 0,1): "))
-                 (magenta (TeX-read-string "Value Magenta (between 0,1): "))
-                 (yellow  (TeX-read-string "Value Yellow (between 0,1): "))
-                 (black   (TeX-read-string "Value Black (between 0,1): ")))
+  ;; Depending on <model>, ask for <color spec> and insert it
+  (pcase LaTeX-color-used-model
+    ;; <cmyk> model
+    ("cmyk" (let ((cyan    (TeX-read-string "Value Cyan (between 0,1): "))
+                  (magenta (TeX-read-string "Value Magenta (between 0,1): "))
+                  (yellow  (TeX-read-string "Value Yellow (between 0,1): "))
+                  (black   (TeX-read-string "Value Black (between 0,1): ")))
+              (TeX-argument-insert
+               (mapconcat #'identity (list cyan magenta yellow black) ",")
+               optional)))
+    ;; <rgb> model
+    ("rgb" (let ((red   (TeX-read-string "Value Red (between 0,1): "))
+                 (green (TeX-read-string "Value Green (between 0,1): "))
+                 (blue  (TeX-read-string "Value Blue (between 0,1): ")))
              (TeX-argument-insert
-              (concat cyan "," magenta "," yellow "," black) optional)))
-          ;; <rgb> model
-          ((string-equal model "rgb")
-           (let ((red   (TeX-read-string "Value Red (between 0,1): "))
+              (mapconcat #'identity (list red green blue) ",")
+              optional)))
+    ;; <gray> model
+    ("gray" (TeX-argument-insert
+             (TeX-read-string "Value Gray (between 0,1): ")
+             optional))
+    (_ (error "%s" "Finding color model failed"))))
+
+(defun TeX-arg-color (optional)
+  "Insert <color spec> argument of various color commands from color.sty.
+If OPTIONAL is non-nil, insert the argument when non-empty and in
+brackets.  The \"named\" color model is handled inside the hook and not
+in this function."
+  ;; \color[<model>]{<color spec>}: Query for <color spec> based on
+  ;; `LaTeX-color-used-model':
+  (pcase LaTeX-color-used-model
+    ;; <cmyk> model
+    ("cmyk" (let ((cyan    (TeX-read-string "Value Cyan (between 0,1): "))
+                  (magenta (TeX-read-string "Value Magenta (between 0,1): "))
+                  (yellow  (TeX-read-string "Value Yellow (between 0,1): "))
+                  (black   (TeX-read-string "Value Black (between 0,1): ")))
+              (TeX-argument-insert
+               (mapconcat #'identity (list cyan magenta yellow black) ",")
+               optional)))
+    ;; <rgb> model
+    ("rgb" (let ((red   (TeX-read-string "Value Red (between 0,1): "))
                  (green (TeX-read-string "Value Green (between 0,1): "))
                  (blue  (TeX-read-string "Value Blue (between 0,1): ")))
              (TeX-argument-insert
-              (concat red "," green "," blue) optional)))
-          ;; <gray> model
-          ((string-equal model "gray")
-           (let ((grayness (TeX-read-string "Value Gray (between 0,1): ")))
-             (TeX-argument-insert grayness optional)))
-          ;; <named> model takes the dvipsnames
-          ((string-equal model "named")
-           (let ((color (completing-read "Named Color: "
-                                         LaTeX-color-dvipsnames-colors)))
-             (TeX-argument-insert color optional))))))
-
-(defun TeX-arg-color (optional &optional prompt)
-  "Insert arguments of various color commands from `color.sty'."
-  ;; \color{<name>} or \color[<model>]{<color spec>} First, ask for
-  ;; <model>.  This happens depending on the values of
-  ;; `TeX-insert-macro-default-style' and if `current-prefix-arg'.
-  ;; `named' is removed here from completion if package option is not
-  ;; given.
-  (let* ((TeX-last-optional-rejected nil)
-         (model (LaTeX-check-insert-macro-default-style
-                 (completing-read
-                  (TeX-argument-prompt t prompt "Color model")
-                  (if (not (or (LaTeX-provided-package-options-member "color" 
"dvips")
-                               (LaTeX-provided-package-options-member "color" 
"dvipsnames")))
-                      (remove "named" LaTeX-color-colour-models)
-                    LaTeX-color-colour-models)))))
-    ;; If <model> is non-nil because of 'mandatory-args-only and not
-    ;; an empty string, then insert it
-    (if (and model (not (string-equal model "")))
-        (progn
-          (insert (concat LaTeX-optop model LaTeX-optcl))
-          (cond (;; <cmyk> model
-                 (string-equal model "cmyk")
-                 (let ((cyan    (TeX-read-string "Value Cyan (between 0,1): "))
-                       (magenta (TeX-read-string "Value Magenta (between 0,1): 
"))
-                       (yellow  (TeX-read-string "Value Yellow (between 0,1): 
"))
-                       (black   (TeX-read-string "Value Black (between 0,1): 
")))
-                   (TeX-argument-insert
-                    (concat cyan "," magenta "," yellow "," black) optional)))
-                ;; <rgb> model
-                ((string-equal model "rgb")
-                 (let ((red   (TeX-read-string "Value Red (between 0,1): "))
-                       (green (TeX-read-string "Value Green (between 0,1): "))
-                       (blue  (TeX-read-string "Value Blue (between 0,1): ")))
-                   (TeX-argument-insert
-                    (concat red "," green "," blue) optional)))
-                ;; <gray> model
-                ((string-equal model "gray")
-                 (let ((grayness (TeX-read-string "Value Gray (between 0,1): 
")))
-                   (TeX-argument-insert grayness optional)))
-                ;; <named> model; allowed are dvipsnames.
-                ((string-equal model "named")
-                 (let ((color (completing-read "Named Color: "
-                                               LaTeX-color-dvipsnames-colors)))
-                   (TeX-argument-insert color optional)))))
-      ;; if empty, ask for <name> with completion
-      (let ((color (completing-read
-                    (TeX-argument-prompt optional prompt "Color name")
-                    (LaTeX-color-definecolor-list))))
-        (TeX-argument-insert color optional)))))
+              (mapconcat #'identity (list red green blue) ",")
+              optional)))
+    ;; <gray> model
+    ("gray" (TeX-argument-insert
+             (TeX-read-string "Value Gray (between 0,1): ")
+             optional))
+    (_ (error "%s" "Finding color model failed"))))
 
 (defun TeX-arg-color-fcolorbox (optional &optional prompt)
-  "Insert arguments of `\\fcolorbox' from `color.sty'. "
+  "Insert <color spec> argument of `\\fcolorbox' from `color.sty'.
+If OPTIONAL is non-nil, insert the argument when non-empty and in
+brackets.  PROMPT is only \"Box\" when non-nil.  The \"named\" color
+model is handled inside the hook and not in this function."
   ;; \fcolorbox{<frame color name>}{<box color name>}{<text>} or
   ;; \fcolorbox[<model>]{<frame color spec>}{<box color spec>}{<text>}
-  ;; First, ask for <model> depending on
-  ;; `TeX-insert-macro-default-style' and `current-prefix-arg'.
-  ;; Remove `named' if necessary.
-  (let* ((TeX-last-optional-rejected nil)
-         (model (LaTeX-check-insert-macro-default-style
-                 (completing-read
-                  (TeX-argument-prompt t prompt "Color model")
-                  (if (not (or (LaTeX-provided-package-options-member "color" 
"dvips")
-                               (LaTeX-provided-package-options-member "color" 
"dvipsnames")))
-                      (remove "named" LaTeX-color-colour-models)
-                    LaTeX-color-colour-models)))))
-    ;; If <model> is non-nil because of 'mandatory-args-only and not
-    ;; an empty string, then insert [<model>] and cater for 2
-    ;; mandatory args.
-    (if (and model (not (string-equal model "")))
-        (progn
-          (insert (concat LaTeX-optop model LaTeX-optcl))
-          (cond (;; <cmyk> model
-                 (string-equal model "cmyk")
-                 (let ((cyan    (TeX-read-string "Frame value Cyan (between 
0,1): "))
-                       (magenta (TeX-read-string "Frame value Magenta (between 
0,1): "))
-                       (yellow  (TeX-read-string "Frame value Yellow (between 
0,1): "))
-                       (black   (TeX-read-string "Frame value Black (between 
0,1): ")))
-                   (TeX-argument-insert
-                    (concat cyan "," magenta "," yellow "," black) optional))
-                 (let ((cyan    (TeX-read-string "Box value Cyan (between 
0,1): "))
-                       (magenta (TeX-read-string "Box value Magenta (between 
0,1): "))
-                       (yellow  (TeX-read-string "Box value Yellow (between 
0,1): "))
-                       (black   (TeX-read-string "Box value Black (between 
0,1): ")))
-                   (TeX-argument-insert
-                    (concat cyan "," magenta "," yellow "," black) optional)))
-                ;; <rgb> model
-                ((string-equal model "rgb")
-                 (let ((red   (TeX-read-string "Frame value Red (between 0,1): 
"))
-                       (green (TeX-read-string "Frame value Green (between 
0,1): "))
-                       (blue  (TeX-read-string "Frame value Blue (between 
0,1): ")))
-                   (TeX-argument-insert
-                    (concat red "," green "," blue) optional))
-                 (let ((red   (TeX-read-string "Box value Red (between 0,1): 
"))
-                       (green (TeX-read-string "Box value Green (between 0,1): 
"))
-                       (blue  (TeX-read-string "box value Blue (between 0,1): 
")))
-                   (TeX-argument-insert
-                    (concat red "," green "," blue) optional)))
-                ;; <gray> model
-                ((string-equal model "gray")
-                 (let ((grayness (TeX-read-string "Frame value Gray (between 
0,1): ")))
-                   (TeX-argument-insert grayness optional))
-                 (let ((grayness (TeX-read-string "Box value Gray (between 
0,1): ")))
-                   (TeX-argument-insert grayness optional)))
-                ;; <named> model; allowed are dvipsnames.
-                ((string-equal model "named")
-                 (let ((color (completing-read "Frame named Color: "
-                                               LaTeX-color-dvipsnames-colors)))
-                   (TeX-argument-insert color optional))
-                 (let ((color (completing-read "Box named Color: "
-                                               LaTeX-color-dvipsnames-colors)))
-                   (TeX-argument-insert color optional)))))
-      ;; if empty, ask for {<frame color spce>}{<box color name>} with 
completion
-      (let ((frame-color (completing-read
-                          (TeX-argument-prompt optional prompt "Frame color 
name")
-                          (LaTeX-color-definecolor-list)))
-            (box-color   (completing-read
-                          (TeX-argument-prompt optional prompt "Box color 
name")
-                          (LaTeX-color-definecolor-list))))
-        (TeX-argument-insert frame-color optional)
-        (TeX-argument-insert box-color   optional)))))
+  (pcase LaTeX-color-used-model
+    ;; <cmyk> model
+    ("cmyk" (let ((cyan    (TeX-read-string
+                            (concat (or prompt "Frame")
+                                    " value Cyan (between 0,1): ")))
+                  (magenta (TeX-read-string
+                            (concat (or prompt "Frame")
+                                    " value Magenta (between 0,1): ")))
+                  (yellow  (TeX-read-string
+                            (concat (or prompt "Frame")
+                                    " value Yellow (between 0,1): ")))
+                  (black   (TeX-read-string
+                            (concat (or prompt "Frame")
+                                    " value Black (between 0,1): "))))
+              (TeX-argument-insert
+               (mapconcat #'identity (list cyan magenta yellow black) ",")
+               optional)))
+    ;; <rgb> model
+    ("rgb" (let ((red   (TeX-read-string
+                         (concat (or prompt "Frame")
+                                 " value Red (between 0,1): ")))
+                 (green (TeX-read-string
+                         (concat (or prompt "Frame")
+                                 " value Green (between 0,1): ")))
+                 (blue  (TeX-read-string
+                         (concat (or prompt "Frame")
+                                 " value Blue (between 0,1): "))))
+             (TeX-argument-insert
+              (mapconcat #'identity (list red green blue) ",")
+              optional)))
+    ;; <gray> model
+    ("gray" (TeX-argument-insert (TeX-read-string
+                                  (concat (or prompt "Frame")
+                                          " value Gray (between 0,1): "))
+                                 optional))
+    (_ (error "%s" "Finding color model failed"))))
 
 (TeX-add-style-hook
  "color"
@@ -264,33 +242,93 @@
    (unless (member "xcolor" (TeX-style-list))
      (TeX-add-symbols
       ;; \definecolor{<name>}{<model>}{<color spec>}
-      '("definecolor" TeX-arg-color-definecolor)
+      '("definecolor"
+        (lambda (optional)
+          (let ((colorname (TeX-read-string
+                            (TeX-argument-prompt optional nil "Color name"))))
+            (LaTeX-add-color-definecolors colorname)
+            (TeX-argument-insert colorname optional)))
+        (TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model")
+        (TeX-arg-conditional
+            (and (save-excursion
+                   (re-search-backward "\\\\definecolor{[^}]+}{\\([^}]+\\)}"
+                                       (line-beginning-position) t)
+                   (setq LaTeX-color-used-model (match-string-no-properties 
1)))
+                 (not (string= LaTeX-color-used-model "named")))
+            (TeX-arg-color-definecolor)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name"))))
 
       ;; \color{<name>} or \color[<model>]{<color spec>}
-      '("color" TeX-arg-color)
+      '("color"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name"))))
 
       ;; \textcolor{<name>}{<text>} or
       ;; \textcolor[<model>]{<color spec>}{<text>}
-      '("textcolor" TeX-arg-color "Text")
+      '("textcolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name")))
+        "Text")
 
       ;; \mathcolor{<name>}{<math>} or
       ;; \mathcolor[<model>]{<color spec>}{<math>}
-      '("mathcolor" TeX-arg-color "Math")
+      '("mathcolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name")))
+        "Math")
 
       ;; \pagecolor{<name>} or
       ;; \pagecolor[<model>]{<color spec>}
-      '("pagecolor" TeX-arg-color)
+      '("pagecolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name"))))
 
       ;; \nopagecolor
       '("nopagecolor" 0)
 
       ;; \colorbox{<name>}{<text>} or
       ;; \colorbox[<model>]{<color spec>}{<text>}
-      '("colorbox" TeX-arg-color "Text")
+      '("colorbox"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name")))
+        "Text")
 
       ;; \fcolorbox{<frame color name>}{<box color name>}{<text>} or
       ;; \fcolorbox[<model>]{<frame color spec>}{<box color spec>}{<text>}
-      '("fcolorbox" TeX-arg-color-fcolorbox "Text"))
+      '("fcolorbox"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color-fcolorbox)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Frame color name")))
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            ((TeX-arg-color-fcolorbox "Box"))
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Box color name")))
+        "Text"))
 
      ;; Fontification
      (when (and (featurep 'font-latex)
diff --git a/style/colortbl.el b/style/colortbl.el
index 7bbab914..41131c83 100644
--- a/style/colortbl.el
+++ b/style/colortbl.el
@@ -1,6 +1,6 @@
 ;;; colortbl.el --- AUCTeX style for `colortbl.sty' (v1.0a)  -*- 
lexical-binding: t; -*-
 
-;; Copyright (C) 2015, 2016, 2018, 2020 Free Software Foundation, Inc.
+;; Copyright (C) 2015--2024 Free Software Foundation, Inc.
 
 ;; Author: Arash Esbati <ar...@gnu.org>
 ;; Maintainer: auctex-devel@gnu.org
@@ -48,35 +48,102 @@
 
    ;; Load color.el only if xcolor.el is not already loaded.  This is
    ;; mainly for the option `table' from xcolor.sty which loads
-   ;; colortbl.sty, but we don't want to load color.el.
-   (unless (member "xcolor" (TeX-style-list))
-     (TeX-run-style-hooks "color"))
-
-   (TeX-add-symbols
-    ;; `TeX-arg-color' is provided by color.el,
-    ;; `TeX-arg-xcolor' is provided by xcolor.el.
-    '("columncolor" (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                                         (TeX-arg-xcolor)
-                                         (TeX-arg-color))
-      [ TeX-arg-length "Left overhang" ] [ TeX-arg-length "Right overhang" ] )
-
-    '("rowcolor"    (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                                         (TeX-arg-xcolor)
-                                         (TeX-arg-color))
-      [ TeX-arg-length "Left overhang" ] [ TeX-arg-length "Right overhang" ] )
-
-    '("cellcolor"   (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                                         (TeX-arg-xcolor)
-                                         (TeX-arg-color))
-      [ TeX-arg-length "Left overhang" ] [ TeX-arg-length "Right overhang" ] )
-
-    '("arrayrulecolor" (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                                            (TeX-arg-xcolor)
-                                            (TeX-arg-color)))
-
-    '("doublerulesepcolor" (TeX-arg-conditional (member "xcolor" 
(TeX-style-list))
-                                                (TeX-arg-xcolor)
-                                                (TeX-arg-color))))
+   ;; colortbl.sty where we don't want to load color.el:
+   (if (member "xcolor" (TeX-style-list))
+       ;; xcolor.sty
+       (TeX-add-symbols
+        '("columncolor"
+          [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                            "Color model"
+                                            nil nil "/" "/"]
+          (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+              (TeX-arg-xcolor)
+            ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                      "Color name")))
+          [TeX-arg-length "Left overhang"] [TeX-arg-length "Right overhang"] )
+
+        '("rowcolor"
+          [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                            "Color model"
+                                            nil nil "/" "/"]
+          (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+              (TeX-arg-xcolor)
+            ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                      "Color name")))
+          [TeX-arg-length "Left overhang"] [TeX-arg-length "Right overhang"] )
+
+        '("cellcolor"
+          [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                            "Color model"
+                                            nil nil "/" "/"]
+          (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+              (TeX-arg-xcolor)
+            ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                      "Color name")))
+          [TeX-arg-length "Left overhang"] [TeX-arg-length "Right overhang"] )
+
+        '("arrayrulecolor"
+          [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                            "Color model"
+                                            nil nil "/" "/"]
+          (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+              (TeX-arg-xcolor)
+            ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                      "Color name"))))
+
+        '("doublerulesepcolor"
+          [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                            "Color model"
+                                            nil nil "/" "/"]
+          (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+              (TeX-arg-xcolor)
+            ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                      "Color name")))))
+     ;; color.sty
+     (TeX-run-style-hooks "color")
+     (TeX-add-symbols
+      '("columncolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name")))
+        [TeX-arg-length "Left overhang"] [TeX-arg-length "Right overhang"])
+
+      '("rowcolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name")))
+        [TeX-arg-length "Left overhang"] [TeX-arg-length "Right overhang"])
+
+      '("cellcolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name")))
+        [TeX-arg-length "Left overhang"] [TeX-arg-length "Right overhang"] )
+
+      '("arrayrulecolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name"))))
+
+      '("doublerulesepcolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+            (TeX-arg-color)
+          ((TeX-arg-completing-read (LaTeX-color-available-colors)
+                                    "Color name"))))))
 
    (LaTeX-add-lengths "minrowclearance")
 
@@ -91,8 +158,8 @@
                               'function)))
  TeX-dialect)
 
-;; colortbl.sty has one option `debugshow'.  I ignore that since it
-;; would only take more time during insertation in a buffer and I
+;; colortbl.sty has one option `debugshow'.  We ignore that since it
+;; would only take more time during insertation in a buffer and we
 ;; presume that not many users use it anyway.
 (defvar LaTeX-colortbl-package-options nil
   "Package option for the colortbl package.")
diff --git a/style/dinbrief.el b/style/dinbrief.el
index c3108466..2e2ad933 100644
--- a/style/dinbrief.el
+++ b/style/dinbrief.el
@@ -1,6 +1,6 @@
 ;;; dinbrief.el --- Special code for LaTeX-Style dinbrief.  -*- 
lexical-binding: t; -*-
 
-;; Copyright (C) 1994-2023  Free Software Foundation, Inc.
+;; Copyright (C) 1994-2024  Free Software Foundation, Inc.
 
 ;; Author: Werner Fink <wer...@suse.de>
 ;; Maintainer: auctex-devel@gnu.org
@@ -32,14 +32,26 @@
 (require 'tex)
 (require 'latex)
 
+;; Silence the compiler:
+(declare-function font-latex-add-keywords
+                  "font-latex"
+                  (keywords class))
+
+(defvar LaTeX-dinbrief-class-options
+  '("10pt" "11pt" "12pt" "norm" "a4paper" "a5paper" "b5paper"
+    "letterpaper" "legalpaper" "executivepaper" "twoside"
+    "addresshigh" "addressstd" "onecolumn" "twocolumn")
+  "Class options for the dinbrief class.")
+
 (TeX-add-style-hook
  "dinbrief"
  (lambda ()
-   (add-hook 'LaTeX-document-style-hook
-             #'LaTeX-dinbrief-style)
    (LaTeX-add-environments
     '("letter" LaTeX-dinbrief-env-recipient)
     "dinquote")
+   (add-hook 'LaTeX-document-style-hook
+             #'LaTeX-dinbrief-style)
+   (setq LaTeX-default-document-environment "letter")
    (TeX-add-symbols
     '("address" "Absender")
     '("postremark" "Postvermerk")
@@ -61,12 +73,28 @@
     '("backaddress" "Retouradresse")
     '("signature" "Unterschrift")
     '("opening" "Anrede")
-    '("closing" "Schluss")))
+    '("closing" "Schluss"))
+
+   ;; Fontification
+   (when (and (featurep 'font-latex)
+              (eq TeX-install-font-lock 'font-latex-setup))
+     (font-latex-add-keywords '(("subject" "{")
+                                ("address" "{")
+                                ("signature" "{")
+                                ("opening" "{")
+                                ("closing" "{")
+                                ("location" "{")
+                                ("handling" "{")
+                                ("cc" "{")
+                                ("encl" "{")
+                                ("ps" "{"))
+                              'function)))
  TeX-dialect)
 
 (defmacro LaTeX-dinbrief-insert (&rest args)
   "Insert text ignoring active markers."
-  `(progn (if mark-active (deactivate-mark))
+  `(progn
+     (if (TeX-active-mark) (deactivate-mark))
      (insert ,@args)))
 
 (defun LaTeX-dinbrief-style ()
@@ -77,17 +105,14 @@
         (beginning-of-line 1))
     (open-line 2)
     (indent-relative-first-indent-point)
-    (LaTeX-dinbrief-insert TeX-esc "usepackage"
-                           LaTeX-optop "latin1,utf8" LaTeX-optcl
-                           TeX-grop "inputenc" TeX-grcl)
-    (newline-and-indent)
     (LaTeX-dinbrief-insert TeX-esc "usepackage"
                            LaTeX-optop "T1" LaTeX-optcl
                            TeX-grop "fontenc" TeX-grcl)
-    (indent-relative-first-indent-point)
+    (newline-and-indent)
     (LaTeX-dinbrief-insert TeX-esc "usepackage"
-                           TeX-grop "ngerman" TeX-grcl))
-  (TeX-run-style-hooks "inputenc" "fontenc" "ngerman"))
+                           LaTeX-optop "ngerman" LaTeX-optcl
+                           TeX-grop "babel" TeX-grcl))
+  (TeX-run-style-hooks "fontenc" "babel"))
 
 (defun LaTeX-dinbrief-env-recipient (environment)
   "Insert ENVIRONMENT and prompt for recipient and address."
@@ -118,8 +143,10 @@
             (newline-and-indent)
             (if (not (zerop (length retouradr)))
                 (progn
-                  (if mark-active (deactivate-mark))
-                  (LaTeX-dinbrief-insert TeX-esc "backaddress" TeX-grop 
retouradr TeX-grcl)
+                  (if (TeX-active-mark) (deactivate-mark))
+                  (LaTeX-dinbrief-insert TeX-esc
+                                         "backaddress"
+                                         TeX-grop retouradr TeX-grcl)
                   (newline-and-indent)))))
       (LaTeX-dinbrief-insert TeX-esc "enabledraftstandard")
       (newline-and-indent)
@@ -205,8 +232,8 @@
   "Read and write the senders address."
   (interactive)
   (let ((name (TeX-read-string "Absender: " (user-full-name)))
-        (str  (TeX-read-string "Meine Strasse:  "))
-        (ort  (TeX-read-string "Mein Wohnort:  ")))
+        (str  (TeX-read-string "Meine Strasse: "))
+        (ort  (TeX-read-string "Mein Wohnort: ")))
     (if (not (zerop (length name)))
         (progn
           (goto-char (point-min)) ; insert before \end{document}
@@ -231,8 +258,8 @@
 (defun LaTeX-dinbrief-recipient ()
   "Read and return the recipient address."
   (interactive)
-  (let ((str  (TeX-read-string "Wohnhaft in Strasse:  "))
-        (ort  (TeX-read-string "Aus der Ortschaft:  ")))
+  (let ((str  (TeX-read-string "Wohnhaft in Strasse: "))
+        (ort  (TeX-read-string "Aus der Ortschaft: ")))
     (if (not (zerop (length str)))
         (if (not (zerop (length ort)))
             (concat str " " TeX-esc TeX-esc " " ort)
@@ -246,7 +273,7 @@
   (let ((ctime-string (current-time-string))
         (month-alist '(("Jan" . "Januar")
                        ("Feb" . "Februar")
-                       ("Mar" . "M\\\"arz")
+                       ("Mar" . "März")
                        ("Apr" . "April")
                        ("May" . "Mai")
                        ("Jun" . "Juni")
@@ -270,4 +297,8 @@
                 (setq day (concat "0" day)))))
       (format "%s, den %s. %s %s" place day month year))))
 
+;; Local Variables:
+;; coding: utf-8-unix
+;; End:
+
 ;;; dinbrief.el ends here
diff --git a/style/floatrow.el b/style/floatrow.el
index 00c2a4be..c0023687 100644
--- a/style/floatrow.el
+++ b/style/floatrow.el
@@ -1,6 +1,6 @@
 ;;; floatrow.el --- AUCTeX style for `floatrow.sty' (v0.3b)  -*- 
lexical-binding: t; -*-
 
-;; Copyright (C) 2017--2022 Free Software Foundation, Inc.
+;; Copyright (C) 2017--2024 Free Software Foundation, Inc.
 
 ;; Author: Arash Esbati <ar...@gnu.org>
 ;; Maintainer: auctex-devel@gnu.org
@@ -62,11 +62,8 @@
 (eval-when-compile
   (require 'cl-lib))
 
-;; Needed for compiling `LaTeX-check-insert-macro-default-style':
-(require 'latex)
-
-;; Needed for auto-parsing:
 (require 'tex)
+(require 'latex)
 
 ;; Silence the compiler:
 (declare-function font-latex-add-keywords
diff --git a/style/paracol.el b/style/paracol.el
index 86a47a26..bc9b4ded 100644
--- a/style/paracol.el
+++ b/style/paracol.el
@@ -1,6 +1,6 @@
 ;;; paracol.el --- AUCTeX style for `paracol.sty' (v1.35)  -*- 
lexical-binding: t; -*-
 
-;; Copyright (C) 2016--2022 Free Software Foundation, Inc.
+;; Copyright (C) 2016--2024 Free Software Foundation, Inc.
 
 ;; Author: Arash Esbati <ar...@gnu.org>
 ;; Maintainer: auctex-devel@gnu.org
@@ -64,6 +64,21 @@ If OPTIONAL is non-nil, insert the result in square 
brackets."
         (backward-char 1)
         (TeX-argument-insert col optional)))))
 
+(defun LaTeX-paracol--used-model (&optional xcolor)
+  "Seach for \\backgroundcolor and return the optional used color model.
+If XCOLOR is non-nil, store the returned value in the variable
+`LaTeX-xcolor-used-type-model', otherwise in the variable
+`LaTeX-color-used-model'."
+  (save-excursion
+    (and (re-search-backward (concat (regexp-quote TeX-esc)
+                                     "backgroundcolor"
+                                     "\\(?:{[^}]*}\\)"
+                                     "\\(?:\\[\\([^]]+\\)\\]\\)?")
+                             (line-beginning-position) t)
+         (set (if xcolor 'LaTeX-xcolor-used-type-model 'LaTeX-color-used-model)
+              (match-string-no-properties 1))
+         (not (string= "named" (match-string-no-properties 1))))))
+
 (TeX-add-style-hook
  "paracol"
  (lambda ()
@@ -176,47 +191,20 @@ If OPTIONAL is non-nil, insert the result in square 
brackets."
     '("nofncounteradjustment" 0)
 
     ;; 7.7 Commands for Coloring Texts and Column-Separating Rules
-    ;; \columncolor[mode]{color}[col]
-    ;;
-    ;; This clashes if colortbl.el is loaded since it provides a
-    ;; command with the same name but different arguments.  We add
-    ;; the command only here but not for fontification
-    '("columncolor" (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                                         (TeX-arg-xcolor)
-                                         (TeX-arg-color))
-      [ "Column" ] )
-
     ;; \normalcolumncolor[col]
     '("normalcolumncolor" [ "Column" ] )
     '("coloredwordhyphenated" 0)
     '("nocoloredwordhyphenated" 0)
 
-    ;; \colseprulecolor[mode]{color}[col]
     ;; \normalcolseprulecolor[col]
-    '("colseprulecolor" (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                                             (TeX-arg-xcolor)
-                                             (TeX-arg-color))
-      [ "Column" ] )
     '("normalcolseprulecolor" [ "Column" ] )
 
     ;; 7.8 Commands for Background Painting
-    ;; \backgroundcolor{region}[mode]{color}
-    ;; \backgroundcolor{region(x0,y0)}[mode]{color}
-    ;; \backgroundcolor{region(x0,y0)(x1,y1)}[mode]{color}
-    '("backgroundcolor"
-      (TeX-arg-completing-read ("c" "g" "s" "f" "n" "p" "t" "b" "l" "r"
-                                "C" "G" "S" "F" "N" "P" "T" "B" "L" "R")
-                               "Region")
-      (TeX-arg-conditional (member "xcolor" (TeX-style-list))
-                           (TeX-arg-xcolor)
-                           (TeX-arg-color)))
-
     ;; \nobackgroundcolor{region}
     '("nobackgroundcolor"
       (TeX-arg-completing-read ("c" "g" "s" "f" "n" "p" "t" "b" "l" "r"
                                 "C" "G" "S" "F" "N" "P" "T" "B" "L" "R")
                                "Region"))
-
     ;; \resetbackgroundcolor
     '("resetbackgroundcolor" 0)
 
@@ -229,6 +217,90 @@ If OPTIONAL is non-nil, insert the result in square 
brackets."
     ;; 7.10 Page Flushing Commands
     '("flushpage" 0))
 
+   ;; xcolor.el
+   (when (member "xcolor" (TeX-style-list))
+     ;; 7.7 Commands for Coloring Texts and Column-Separating Rules
+     ;; \columncolor[model]{color}[col]
+     ;;
+     ;; This clashes if colortbl.el is loaded since it provides a
+     ;; command with the same name but different arguments.  We add
+     ;; the command only here but not for fontification
+     (TeX-add-symbols
+      '("columncolor"
+        [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                          "Color model"
+                                          nil nil "/" "/"]
+        (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+                             (TeX-arg-xcolor)
+                             ((TeX-arg-completing-read 
(LaTeX-xcolor-definecolor-list)
+                                                       "Color name")))
+        [ "Column" ] )
+
+      ;; \colseprulecolor[model]{color}[col]
+      '("colseprulecolor"
+        [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                          "Color model"
+                                          nil nil "/" "/"]
+        (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+                             (TeX-arg-xcolor)
+                             ((TeX-arg-completing-read 
(LaTeX-xcolor-definecolor-list)
+                                                       "Color name")))
+        [ "Column" ] )
+
+      ;; 7.8 Commands for Background Painting
+      ;; \backgroundcolor{region}[mode]{color}
+      ;; \backgroundcolor{region(x0,y0)}[mode]{color}
+      ;; \backgroundcolor{region(x0,y0)(x1,y1)}[mode]{color}
+      '("backgroundcolor"
+        (TeX-arg-completing-read ("c" "g" "s" "f" "n" "p" "t" "b" "l" "r"
+                                  "C" "G" "S" "F" "N" "P" "T" "B" "L" "R")
+                                 "Region")
+        [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                          "Color model"
+                                          nil nil "/" "/"]
+        (TeX-arg-conditional (LaTeX-paracol--used-model t)
+                             (TeX-arg-xcolor)
+                             ((TeX-arg-completing-read 
(LaTeX-xcolor-definecolor-list)
+                                                       "Color name"))))))
+
+   ;; color.el: Always prefer xcolor.sty over color.sty
+   (when (and (member "color" (TeX-style-list))
+              (not (member "xcolor" TeX-active-styles)))
+     (TeX-add-symbols
+      '("columncolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+                             (TeX-arg-color)
+                             ((TeX-arg-completing-read 
(LaTeX-color-available-colors)
+                                                       "Color name")))
+        [ "Column" ] )
+
+      ;; \colseprulecolor[mode]{color}[col]
+      '("colseprulecolor"
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-color-used-model-requires-spec-p)
+                             (TeX-arg-color)
+                             ((TeX-arg-completing-read 
(LaTeX-color-available-colors)
+                                                       "Color name")))
+        [ "Column" ] )
+
+      ;; 7.8 Commands for Background Painting
+      ;; \backgroundcolor{region}[mode]{color}
+      ;; \backgroundcolor{region(x0,y0)}[mode]{color}
+      ;; \backgroundcolor{region(x0,y0)(x1,y1)}[mode]{color}
+      '("backgroundcolor"
+        (TeX-arg-completing-read ("c" "g" "s" "f" "n" "p" "t" "b" "l" "r"
+                                  "C" "G" "S" "F" "N" "P" "T" "B" "L" "R")
+                                 "Region")
+        [TeX-arg-completing-read (LaTeX-color-available-models)
+                                 "Color model"]
+        (TeX-arg-conditional (LaTeX-paracol--used-model)
+                             (TeX-arg-color)
+                             ((TeX-arg-completing-read 
(LaTeX-color-available-colors)
+                                                       "Color name"))))))
+
    ;; \belowfootnoteskip is a length:
    (LaTeX-add-lengths "belowfootnoteskip")
 
diff --git a/style/xcolor.el b/style/xcolor.el
index b0bc74fb..440d7d35 100644
--- a/style/xcolor.el
+++ b/style/xcolor.el
@@ -1,6 +1,6 @@
-;; xcolor.el --- AUCTeX style for `xcolor.sty' (v2.12)  -*- lexical-binding: 
t; -*-
+;; xcolor.el --- AUCTeX style for `xcolor.sty' (v3.01)  -*- lexical-binding: 
t; -*-
 
-;; Copyright (C) 2016--2023 Free Software Foundation, Inc.
+;; Copyright (C) 2016--2024 Free Software Foundation, Inc.
 
 ;; Author: Arash Esbati <ar...@gnu.org>
 ;; Maintainer: auctex-devel@gnu.org
@@ -26,7 +26,7 @@
 
 ;;; Commentary:
 
-;; This file adds support for `xcolor.sty' (v2.13) from 2021/10/31.
+;; This file adds support for `xcolor.sty' (v3.01) from 2023/11/15.
 ;; `xcolor.sty' is part of TeXLive.
 
 ;; `xcolor.sty' and `color.sty' share many command namens, but the
@@ -44,7 +44,7 @@
 
 ;;; Code:
 
-;; Needed for compiling `LaTeX-check-insert-macro-default-style':
+(require 'tex)
 (require 'latex)
 
 ;; Silence the compiler:
@@ -52,22 +52,6 @@
                   "font-latex"
                   (keywords class))
 
-(defvar LaTeX-xcolor-core-color-models
-  '("rgb" "cmy" "cmyk" "hsb" "gray")
-  "List of core color models provided by xcolor.sty.")
-
-(defvar LaTeX-xcolor-num-color-models
-  '("RGB" "HTML" "HSB" "Gray" "HsB" "tHsB" "wave")
-  "List of integer and decimal color models provided by xcolor.sty.")
-
-(defvar LaTeX-xcolor-pseudo-color-models
-  '("named")
-  "List of pseudo color models provided by xcolor.sty.")
-
-(defvar LaTeX-xcolor-type-color-models
-  '("named" "ps")
-  "List of type color models provided by xcolor.sty.")
-
 (defvar LaTeX-xcolor-base-colors
   '("red"    "green" "blue"     "cyan"      "magenta" "yellow" "black"
     "gray"   "white" "darkgray" "lightgray" "brown"   "lime"   "olive"
@@ -218,11 +202,28 @@
     "DeepPink4"         "LightSteelBlue4" "RosyBrown4")
   "List of colors defined by package option x11names from xcolor.sty.")
 
+(defvar LaTeX-xcolor-core-color-models
+  '("rgb" "cmy" "cmyk" "hsb" "gray")
+  "List of core color models provided by xcolor.sty.")
+
+(defvar LaTeX-xcolor-num-color-models
+  '("RGB" "HTML" "HSB" "Gray" "HsB" "tHsB" "wave")
+  "List of integer and decimal color models provided by xcolor.sty.")
+
+(defvar LaTeX-xcolor-pseudo-color-models
+  '("named")
+  "List of pseudo color models provided by xcolor.sty.")
+
+(defvar LaTeX-xcolor-color-types
+  '("named" "ps")
+  "List of color types provided by xcolor.sty.")
+
 (defvar LaTeX-xcolor-color-models
   (append LaTeX-xcolor-core-color-models
           LaTeX-xcolor-num-color-models
           LaTeX-xcolor-pseudo-color-models)
-  "Combine three variables `LaTeX-xcolor-core-color-models',
+  "Combine three variables containing color model.
+These are `LaTeX-xcolor-core-color-models',
 `LaTeX-xcolor-num-color-models' and `LaTeX-xcolor-pseudo-color-models'.")
 
 (defun LaTeX-xcolor-color-models (&optional no-named)
@@ -233,9 +234,6 @@ remainder."
       (remove "named" LaTeX-xcolor-color-models)
     LaTeX-xcolor-color-models))
 
-;; Needed for auto-parsing.
-(require 'tex)
-
 ;; Setup AUCTeX parser for \definecolor(set):
 (TeX-auto-add-type "xcolor-definecolor" "LaTeX")
 (TeX-auto-add-type "xcolor-definecolorset" "LaTeX")
@@ -245,7 +243,7 @@ remainder."
     `(,(concat "\\\\"
                (regexp-opt '("definecolor"  "providecolor"
                              "preparecolor" "colorlet"))
-               "\\(?:\\[\\(?:[^]]*\\)\\]\\)?{\\([^}]+\\)}")
+               "\\(?:\\[[^]]*\\]\\)?{\\([^}]+\\)}")
       1 LaTeX-auto-xcolor-definecolor))
   "Match the argument of various color defining macros from xcolor package.")
 
@@ -281,106 +279,84 @@ xcolor package.")
 (add-hook 'TeX-auto-cleanup-hook #'LaTeX-xcolor-auto-cleanup t)
 (add-hook 'TeX-update-style-hook #'TeX-auto-parse t)
 
-(defun TeX-arg-xcolor-definecolor (optional)
-  "Insert arguments of \\definecolor and similar macros from xcolor.sty."
-  ;; \definecolor[<type>]{<name>}{<model-list>}{<spec-list>}
-  (let* ((TeX-last-optional-rejected nil)
-         (xcoltype  (LaTeX-check-insert-macro-default-style
-                     (completing-read
-                      (TeX-argument-prompt t nil "Type")
-                      LaTeX-xcolor-type-color-models)))
-         (xcolname  (TeX-read-string
-                     (TeX-argument-prompt optional nil "Color name")))
-         (xcolmodel (completing-read
-                     (TeX-argument-prompt optional nil "Model (list)")
-                     (if (string= xcoltype "named")
-                         (LaTeX-xcolor-color-models t)
-                       LaTeX-xcolor-color-models)))
-         (xcolspec  (if (string= xcolmodel "named")
-                        (completing-read
-                         (TeX-argument-prompt optional nil "Color")
-                         (LaTeX-xcolor-definecolor-list))
-                      (TeX-read-string
-                       (TeX-argument-prompt optional nil (concat xcolmodel " 
spec (list)"))))))
-    (when (and xcoltype (not (string= xcoltype "")))
-      (insert (format "[%s]" xcoltype)))
-    (TeX-argument-insert xcolname optional)
-    (LaTeX-add-xcolor-definecolors xcolname)
-    (TeX-argument-insert xcolmodel optional)
-    (TeX-argument-insert xcolspec optional)))
-
-(defun TeX-arg-xcolor-definecolorset (optional)
-  "Insert arguments of \\definecolorset and similar macros from xcolor.sty."
-  (let* ((TeX-last-optional-rejected nil)
-         (xcoltype (LaTeX-check-insert-macro-default-style
-                    (completing-read
-                     (TeX-argument-prompt t nil "Type")
-                     LaTeX-xcolor-type-color-models)))
-         (xcolmodel (completing-read
-                     (TeX-argument-prompt optional nil "Model")
-                     (LaTeX-xcolor-color-models t))))
-    (when (and xcoltype (not (string= xcoltype "")))
-      (insert (format "[%s]" xcoltype)))
-    (TeX-argument-insert xcolmodel optional)))
+(defconst LaTeX-xcolor-color-cmds-regexp
+  (concat (regexp-quote TeX-esc)
+          (regexp-opt '("color" "textcolor"
+                        "mathcolor" "pagecolor"
+                        "colorbox" "fcolorbox"
+                        ;; changebar.el
+                        "cbcolor"
+                        ;; colortbl.el
+                        "columncolor" "rowcolor" "cellcolor"
+                        "arrayrulecolor" "doublerulesepcolor"
+                        ;; paracol.el also provides a columncolor which
+                        ;; we don't repeat:
+                        "colseprulecolor"))
+          "\\(?:\\[\\([^]]*\\)\\]\\)?")
+  "Regexp for matching the optional argument of color macros.")
+
+(defconst LaTeX-xcolor-defcolor-cmds-regexp
+  (concat (regexp-quote TeX-esc)
+          (regexp-opt '("definecolor" "providecolor" "colorlet"
+                        "preparecolor"))
+          "\\(?:\\[\\([^]]*\\)\\]\\)?"
+          "\\(?:{[^}]+}\\)?"
+          "\\(?:{\\([^}]+\\)}\\)?")
+  "Regexp matching the type and model argument of color defining macros.")
+
+(defvar-local LaTeX-xcolor-used-type-model nil
+  "Variable containing the color type or model from last search.
+It is set by the function `LaTeX-xcolor-cmd-requires-spec-p'.")
+
+(defun LaTeX-xcolor-cmd-requires-spec-p (what &optional which)
+  "Search backward for type or model of color commands.
+WHAT determines the regexp for color commands to search for where:
+WHAT      Variable
+-------   -----------------------------------
+\\='col      `LaTeX-xcolor-color-cmds-regexp'
+\\='defcol   `LaTeX-xcolor-defcolor-cmds-regexp'
+\\='colbox   Calculated inside this function.
+
+If WHICH is non-nil, the second grouped argument from the search is
+returned instead of the first."
+  (let ((regexp (pcase what
+                  ('col LaTeX-xcolor-color-cmds-regexp)
+                  ('defcol LaTeX-xcolor-defcolor-cmds-regexp)
+                  ('colbox "\\\\fcolorbox\\(?:\\[\\([^]]*\\)\\]\\)?")))
+        (regexp-add "{[^}]*}\\(?:\\[\\([^]]*\\)\\]\\)?"))
+    (when (and which (eq what 'colbox))
+      (setq regexp (concat regexp regexp-add)))
+    (save-excursion
+      (re-search-backward regexp (line-beginning-position) t))
+    (setq LaTeX-xcolor-used-type-model
+          (unless (string-empty-p (match-string-no-properties (if which 2 1)))
+            (match-string-no-properties (if which 2 1)))))
+  (if (and LaTeX-xcolor-used-type-model
+           (not (string= LaTeX-xcolor-used-type-model "named")))
+      t
+    nil))
 
 (defun TeX-arg-xcolor (optional)
-  "Insert arguments of various color commands from xcolor.sty."
+  "Insert mandatory argument of various color commands from xcolor.sty.
+If OPTIONAL is non-nil, insert the result only when non-empty and in
+brackets."
   ;; \color{<name>} or \color[<model-list>]{<spec-list>}
-  (let* ((TeX-last-optional-rejected nil)
-         (xcolmodel (LaTeX-check-insert-macro-default-style
-                     (completing-read
-                      (TeX-argument-prompt t nil "Model (list)")
-                      (LaTeX-xcolor-color-models t))))
-         (xcolor (if (and xcolmodel (not (string= xcolmodel "")))
-                     (TeX-read-string
-                      (TeX-argument-prompt optional nil (concat xcolmodel " 
spec (list)")))
-                   (completing-read
-                    (TeX-argument-prompt optional nil "Color")
-                    (LaTeX-xcolor-definecolor-list)))))
-    (when (and xcolmodel (not (string= xcolmodel "")))
-      (insert (format "[%s]" xcolmodel)))
-    (TeX-argument-insert xcolor optional)))
-
-(defun TeX-arg-xcolor-fcolorbox (optional)
-  "Insert arguments of \\fcolorbox from xcolor.sty."
-  ;;\fcolorbox[<frame model>]{<frame spec>}[<background model>]{<background 
spec>}{<text>}
-  (let* ((TeX-last-optional-rejected nil)
-         (xfrmodel (LaTeX-check-insert-macro-default-style
-                    (completing-read
-                     (TeX-argument-prompt t nil "(Frame) Color model")
-                     LaTeX-xcolor-color-models)))
-         ;; Set `TeX-last-optional-rejected' acc. to `xfrmodel'
-         (TeX-last-optional-rejected (or (not xfrmodel)
-                                         (and xfrmodel (string= xfrmodel ""))))
-         (xfrspec  (if (or (null xfrmodel)
-                           (string= xfrmodel "")
-                           (string= xfrmodel "named"))
-                       (completing-read
-                        (TeX-argument-prompt optional nil "Frame color spec")
-                        (LaTeX-xcolor-definecolor-list))
-                     (TeX-read-string
-                      (TeX-argument-prompt optional nil "Frame color spec"))))
-         (xbgmodel (LaTeX-check-insert-macro-default-style
-                    (completing-read
-                     (TeX-argument-prompt t nil "Background Color model")
-                     LaTeX-xcolor-color-models)))
-         (xbgspec  (if (or (null xfrmodel)
-                           (string= xfrmodel "")
-                           (string= xfrmodel "named")
-                           (null xbgmodel)
-                           (string= xbgmodel "")
-                           (string= xbgmodel "named"))
-                       (completing-read
-                        (TeX-argument-prompt optional nil "Background color 
spec")
-                        (LaTeX-xcolor-definecolor-list))
-                     (TeX-read-string
-                      (TeX-argument-prompt optional nil "Background color 
spec")))))
-    (when (and xfrmodel (not (string= xfrmodel "")))
-      (insert (format "[%s]" xfrmodel)))
-    (TeX-argument-insert xfrspec optional)
-    (when (and xbgmodel (not (string= xbgmodel "")))
-      (insert (format "[%s]" xbgmodel)))
-    (TeX-argument-insert xbgspec optional)))
+  (TeX-argument-insert
+   (TeX-read-string
+    (TeX-argument-prompt optional nil (concat LaTeX-xcolor-used-type-model
+                                              " spec (list)")))
+   optional))
+
+(defun TeX-arg-xcolor-definecolor (optional &optional prompt)
+  "Insert first mandatory argument of color defining macros.
+If OPTIONAL is non-nil, insert the result only when non-empty and in
+brackets.  PROMPT replaces the standard one."
+  ;; \definecolor[<type>]{<name>}{<model-list>}{<spec-list>}
+  (let ((name-spec (TeX-read-string
+                    (TeX-argument-prompt optional prompt "Color name"))))
+    (unless (string-empty-p name-spec)
+      (LaTeX-add-xcolor-definecolors name-spec))
+    (TeX-argument-insert name-spec optional)))
 
 (TeX-add-style-hook
  "xcolor"
@@ -410,37 +386,84 @@ xcolor package.")
    (TeX-add-symbols
     ;; 2.5.2 Color definition in xcolor
     ;; \definecolor[<type>]{<name>}{<model-list>}{<spec-list>}
-    '("definecolor" TeX-arg-xcolor-definecolor)
+    '("definecolor"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types
+                               "Type"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'defcol)
+          ((TeX-arg-xcolor-definecolor))
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      (TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Model (list)" nil nil "/" "/")
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'defcol t)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name"))))
 
     ;; \providecolor[<type>]{<name>}{<model-list>}{<spec-list>}
-    '("providecolor" TeX-arg-xcolor-definecolor)
+    '("providecolor"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types
+                               "Type"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'defcol)
+          ((TeX-arg-xcolor-definecolor))
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      (TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Model (list)" nil nil "/" "/")
+      (TeX-arg-conditional (LaTeX-xcolor-used-type-model-requires-spec-p 
'model)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name"))))
 
     ;; \colorlet[<type>]{<name>}[<num model>]{<color>}
-    `("colorlet"
-      [TeX-arg-completing-read LaTeX-xcolor-type-color-models "Type"]
-      ,(lambda (optional)
-         (let ((xcolor (TeX-read-string
-                        (TeX-argument-prompt optional nil "Color"))))
-           (LaTeX-add-xcolor-definecolors xcolor)
-           (TeX-argument-insert xcolor optional)))
-      [TeX-arg-completing-read ,(lambda ()
-                                  (LaTeX-xcolor-color-models t))
+    '("colorlet"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types "Type"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'defcol)
+          ((TeX-arg-xcolor-definecolor))
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      [TeX-arg-completing-read (lambda ()
+                                 (LaTeX-xcolor-color-models t))
                                "Model"]
       (TeX-arg-completing-read (LaTeX-xcolor-definecolor-list) "Color"))
 
     ;; 2.5.3 Defining sets of colors
     ;; \definecolorset[<type>]{<model-list>}{<head>}{<tail>}{<set spec>}
-    '("definecolorset" TeX-arg-xcolor-definecolorset "Head" "Tail" t)
+    '("definecolorset"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types "Type"]
+      (TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Model (list)" nil nil "/" "/")
+      "Head" "Tail" t)
 
     ;; \providecolorset[<type>]{<model-list>}{<head>}{<tail>}{<set spec>}
-    '("providecolorset" TeX-arg-xcolor-definecolorset "Head" "Tail" t)
+    '("providecolorset"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types "Type"]
+      (TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Model (list)" nil nil "/" "/")
+      "Head" "Tail" t)
 
     ;; 2.5.4 Immediate and deferred definitions
     ;; \preparecolor[<type>]{<name>}{<model-list>}{<spec-list>}
-    '("preparecolor" TeX-arg-xcolor-definecolor)
+    '("preparecolor"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types
+                               "Type"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'defcol)
+          ((TeX-arg-xcolor-definecolor))
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      (TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Model (list)" nil nil "/" "/")
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'defcol t)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name"))))
 
     ;; \preparecolorset[<type>]{<model-list>}{<head>}{<tail>}{<set spec>}
-    '("preparecolorset" TeX-arg-xcolor-definecolorset "Head" "Tail" t)
+    '("preparecolorset"
+      [TeX-arg-completing-read LaTeX-xcolor-color-types "Type"]
+      (TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Model (list)" nil nil "/" "/")
+      "Head" "Tail" t)
 
     ;; \definecolors{<id-list>}
     '("definecolors" t)
@@ -452,19 +475,49 @@ xcolor package.")
     ;; 2.6.1 Standard color commands
 
     ;; \color{<name>} or \color[<model>]{<color spec>}
-    '("color" TeX-arg-xcolor)
+    '("color"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name"))))
 
     ;; \textcolor{<name>}{<text>} or
     ;; \textcolor[<model>]{<color spec>}{<text>}
-    '("textcolor" TeX-arg-xcolor "Text")
+    '("textcolor"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      "Text")
 
     ;; \mathcolor{<name>}{<math>} or
     ;; \mathcolor[<model>]{<color spec>}{<math>}
-    '("mathcolor" TeX-arg-xcolor "Math")
+    '("mathcolor"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      "Math")
 
     ;; \pagecolor{<name>} or
     ;; \pagecolor[<model>]{<color spec>}
-    '("pagecolor" TeX-arg-xcolor)
+    '("pagecolor"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name"))))
 
     ;; \nopagecolor
     '("nopagecolor" 0)
@@ -472,17 +525,47 @@ xcolor package.")
     ;; 2.6.2 Colored boxes
     ;; \colorbox{<name>}{<text>} or
     ;; \colorbox[<model>]{<color spec>}{<text>}
-    '("colorbox" TeX-arg-xcolor "Text")
+    '("colorbox"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name")))
+      "Text")
 
     ;; \fcolorbox{<frame color>}{<box color>}{<text>} or
     ;; \fcolorbox[<model>]{<frame spec>}{<background spec>}{<text>} or
     ;; \fcolorbox[<frame model>]{<frame spec>}[<background model>]{<background 
spec>}{<text>}
-    '("fcolorbox" TeX-arg-xcolor-fcolorbox "Text")
+    '("fcolorbox"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Frame color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'colbox)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Frame color name")))
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Background color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'colbox t)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Background color name")))
+      "Text")
 
     ;; 2.6.4 Color testing
     ;; \testcolor{<name>} or
     ;; \testcolor[<model>]{<color spec>}
-    '("testcolor" TeX-arg-xcolor)
+    '("testcolor"
+      [TeX-arg-completing-read-multiple (LaTeX-xcolor-color-models)
+                                        "Color model"
+                                        nil nil "/" "/"]
+      (TeX-arg-conditional (LaTeX-xcolor-cmd-requires-spec-p 'col)
+          (TeX-arg-xcolor)
+        ((TeX-arg-completing-read (LaTeX-xcolor-definecolor-list)
+                                  "Color name"))))
 
     ;; 2.7 Color blending
     '("blendcolors"
@@ -491,8 +574,8 @@ xcolor package.")
       (TeX-arg-completing-read (LaTeX-xcolor-definecolor-list) "Mix expr"))
 
     ;; 2.8 Color masks and separation
-    `("maskcolors"
-      [TeX-arg-completing-read ,(lambda () (LaTeX-xcolor-color-models t)) 
"Model"]
+    '("maskcolors"
+      [TeX-arg-completing-read (lambda () (LaTeX-xcolor-color-models t)) 
"Model"]
       (TeX-arg-completing-read (LaTeX-xcolor-definecolor-list) "Color"))
 
     ;; 2.9 Color series
@@ -522,10 +605,10 @@ xcolor package.")
 
     ;; 2.14 Color conversion
     ;; \convertcolorspec{<model>}{<spec>}{<target model>}{cmd>}
-    `("convertcolorspec"
+    '("convertcolorspec"
       (TeX-arg-completing-read (LaTeX-xcolor-color-models) "Model")
-      (TeX-arg-string "Spec")
-      (TeX-arg-completing-read ,(lambda () (LaTeX-xcolor-color-models t))
+      "Spec"
+      (TeX-arg-completing-read (lambda () (LaTeX-xcolor-color-models t))
                                "Target model")
       (TeX-arg-define-macro "Macro: \\")) ) ; close TeX-add-symbols
 
@@ -609,7 +692,10 @@ xcolor package.")
     "dvipsnames" "dvipsnames*" "svgnames" "svgnames*" "x11names" "x11names*"
 
     ;; options that determine which other packages to load
-    "table" "fixpdftex" "hyperref"
+    "table"
+
+    ;; obsolete options
+    ;; "fixpdftex" "hyperref"
 
     ;; options that influence the behaviour of other commands
     "prologue" "kernelfbox" "xcdraw" "noxcdraw" "fixinclude"
diff --git a/tex.el b/tex.el
index 749037b5..0795e602 100644
--- a/tex.el
+++ b/tex.el
@@ -1621,7 +1621,7 @@ where an entry with the same car exists in the 
user-defined part."
   (TeX-delete-dups-by-car (append TeX-engine-alist TeX-engine-alist-builtin)))
 
 (defun TeX-engine-in-engine-alist (engine)
-  "Return the `engine' entry in `TeX-engine-alist'.
+  "Return entry ENGINE in `TeX-engine-alist'.
 
 Throw an error if `engine' is not present in the alist."
   (or
@@ -1723,7 +1723,7 @@ as a string.")
   "Keep track if question about server start search was asked.")
 
 (defvar TeX-source-correlate-start-server-flag nil
-  "If non-nil, `TeX-source-correlate-start-server-maybe' will start a server.
+  "Non-nil means `TeX-source-correlate-start-server-maybe' will start a server.
 Code related to features requiring a server, for example, for inverse
 search, can set the variable.")
 
@@ -5091,6 +5091,48 @@ affected.  See `TeX-electric-macro' for detail."
                  (const reindent-then-newline-and-indent)
                  (sexp :tag "Other")))
 
+(defun TeX--put-electric-delete-selection (symbol electricp)
+  "Set appropriate `delete-selection' property for electric functions.
+
+When the function bound to SYMBOL has «electric» behaviour, as
+determined by predicate ELECTRICP, `delete-selection' is set to
+nil.  In the other case, `delete-selection' is delegated to that
+of the `self-insert-command'.
+
+Note, that it is assumed that SYMBOL uses `self-insert-command'
+to insert symbols on its non-electric path.
+
+The backstory.
+
+When a function bound to SYMBOL has optional «electric»
+behaviour, it might interfere with other «electric» modes,
+e.g. `electric-pair-mode', `smartparens-mode'; see bug#47936.
+
+As a way to «override» those modes, we use raw `insert' instead
+of `self-insert-command'.  That prevents those electric modes
+from running their hooks tied to `self-insert-command'.
+
+However, when /our/ electric behaviour is disabled (ELECTRICP
+returns nil), we want other electric modes to operate freely.
+That means, on the non-electric path, we should use
+`self-insert-command' instead of `insert'.
+
+Now, there arises an issue of `delete-selection'.  The electric
+path usually doesn't want to delete selection, it wants to
+operate some electricity on it; see bug#36385, bug#23177.  Now,
+we could think that `delete-selection' for the non-electric path
+should be t.  That would disable other electric modes from
+working, as they also need to operate on selection.  The decision
+is to inherit `delete-selection' from `self-insert-command',
+which queries hooks from other electric modes to determine
+whether deletion is necessary.
+
+This function implements the idea from the last paragraph."
+  (put symbol 'delete-selection
+       (lambda ()
+         (unless (funcall electricp)
+           (get #'self-insert-command 'delete-selection)))))
+
 (defun TeX-insert-backslash (arg)
   "Either insert typed key ARG times or call `TeX-electric-macro'.
 `TeX-electric-macro' will be called if `TeX-electric-escape' is non-nil."
@@ -5099,6 +5141,9 @@ affected.  See `TeX-electric-macro' for detail."
       (TeX-electric-macro)
     (self-insert-command arg)))
 
+(TeX--put-electric-delete-selection
+ #'TeX-insert-backslash (lambda () TeX-electric-escape))
+
 (defun TeX-insert-sub-or-superscript (arg)
   "Insert typed key ARG times and possibly a pair of braces.
 Brace insertion is only done if point is in a math construct and
@@ -5113,6 +5158,8 @@ Brace insertion is only done if point is in a math 
construct and
   "Call the function specified by the variable `TeX-newline-function'."
   (interactive) (call-interactively TeX-newline-function))
 
+(put #'TeX-newline 'delete-selection t)
+
 (progn
   (let ((map TeX-mode-map))
     ;; Standard
@@ -6107,18 +6154,14 @@ See `TeX-math-input-method-off-regexp'."
   :type 'boolean)
 
 (defcustom TeX-electric-math nil
-  "If non-nil, when outside math mode `TeX-insert-dollar' will
-insert symbols for opening and closing inline equation and put
-the point between them.  If there is an active region,
-`TeX-insert-dollar' will put around it symbols for opening and
-closing inline equation and keep the region active, with point
-after closing symbol.  If you press `$' again, you can toggle
+  "Math mode delimiters inserted by `TeX-insert-dollar'.
+If non-nil, `TeX-insert-dollar' will insert symbols for opening and
+closing inline equation and put the point between them.  If there is an
+active region, `TeX-insert-dollar' will put around it symbols for
+opening and closing inline equation and keep the region active, with
+point after closing symbol.  If you press `$' again, you can toggle
 between inline equation, display equation, and no equation.
 
-If non-nil and point is inside math mode right between a couple
-of single dollars, pressing `$' will insert another pair of
-dollar signs and leave the point between them.
-
 If nil, `TeX-insert-dollar' will simply insert \"$\" at point,
 this is the default.
 
@@ -6135,129 +6178,133 @@ point.  You can choose between \"$...$\" and 
\"\\(...\\)\"."
 
 (defcustom TeX-refuse-unmatched-dollar nil
   "When non-nil, don't insert unmatched dollar sign.
-That is, `TeX-insert-dollar' refuses to insert \"$\" when
-`texmathp' tells that the current position is in math mode which
-didn't start with dollar(s).
+That is, `TeX-insert-dollar' refuses to insert \"$\" when `texmathp'
+tells that the current position is in math mode which didn't start with
+dollar(s).  Doesn't have an effect when `TeX-electric-math' is non-nil.
 
-When nil, `TeX-insert-dollar' assumes the user knows that the
-current position is not in math mode actually and behaves in the
-same way as non-math mode."
+When nil, `TeX-insert-dollar' assumes the user knows that the current
+position is not in math mode actually and behaves in the same way as
+non-math mode."
   :group 'TeX-macro
   :type 'boolean)
 
-(defun TeX-insert-dollar (&optional arg)
+(defun TeX-insert-dollar-electric-region ()
+  "Perform electric math delimiter insertion on a region.
+See `TeX-electric-math'."
+  (when (> (point) (mark))
+    (exchange-point-and-mark))
+  (cond
+   ;; Strip \[...\] or $$...$$
+   ((and (eq last-command #'TeX-insert-dollar)
+         (or (re-search-forward "\\=\\\\\\[\\([^z-a]*\\)\\\\\\]" (mark) t)
+             (re-search-forward "\\=\\$\\$\\([^z-a]*\\)\\$\\$" (mark) t)))
+    (replace-match "\\1" t)
+    (set-mark (match-beginning 0)))
+   ;; $...$ to $$...$$
+   ((and (eq last-command #'TeX-insert-dollar)
+         (re-search-forward "\\=\\$\\([^z-a]*\\)\\$" (mark) t))
+    (replace-match "$$\\1$$" t)
+    (set-mark (match-beginning 0)))
+   ;; \(...\) to \[...\]
+   ((and (eq last-command #'TeX-insert-dollar)
+         (re-search-forward "\\=\\\\(\\([^z-a]*\\)\\\\)" (mark) t))
+    (replace-match "\\\\[\\1\\\\]" t)
+    (set-mark (match-beginning 0)))
+   (t
+    ;; We use `save-excursion' because point must be situated
+    ;; before opening symbol.
+    (save-excursion (insert (car TeX-electric-math)))
+    (exchange-point-and-mark)
+    (insert (cdr TeX-electric-math))))
+  (TeX-activate-region))
+
+(defun TeX-insert-dollar-electric ()
+  "Perform electric math symbol insertion.
+See `TeX-electric-math'."
+  (if (and (TeX-active-mark) (/= (point) (mark)))
+      (TeX-insert-dollar-electric-region)
+    (insert (car TeX-electric-math))
+    (save-excursion (insert (cdr TeX-electric-math)))
+    (TeX-math-input-method-off)))
+
+(defun TeX--blink-matching-dollar ()
+  "Blink the matching $, when appropriate.
+Assume that `texmathp' has been called."
+  (when (and blink-matching-paren
+             (or (string= (car texmathp-why) "$")
+                 (zerop (mod (save-excursion
+                               (skip-chars-backward "$")) 2))))
+    (save-excursion
+      (goto-char (cdr texmathp-why))
+      (if (pos-visible-in-window-p)
+          (sit-for blink-matching-delay)
+        (message "Matches %s"
+                 (buffer-substring
+                  (point) (line-end-position)))))))
+
+(defun TeX-insert-dollar-action (arg)
+  "Determine the action for `TeX-insert-dollar'.
+
+Returns one of the following possible symbols that determine the
+behavior of `TeX-insert-dollar':
+ `just-insert'
+     Just insert a literal $ ARG times.  For example, if you need
+     exactly one $, you can use `C-1 $'.
+ `electric'
+     Behave according to `TeX-electric-math'.
+ `begin-math'
+     Insert a $ that starts the math mode.
+ `end-math'
+     Insert a $ that ends the math mode.
+ `refuse'
+     Refuse to insert a $ (or do anything else)."
+  (cond
+   ((or arg (TeX-escaped-p) (TeX-verbatim-p))
+    'just-insert)
+   (TeX-electric-math
+    'electric)
+   ((not (texmathp))
+    'begin-math)
+   ((member (car texmathp-why) '("$" "$$"))
+    'end-math)
+   ;; Math mode was not entered with dollar according to `texmathp'.
+   (TeX-refuse-unmatched-dollar
+    'refuse)
+   ;; We assume that `texmathp' was wrong and behave as if not in
+   ;; math mode. (bug#57626)
+   ('begin-math)))
+
+(defun TeX-insert-dollar (arg)
   "Insert dollar sign.
 
-If current math mode was not entered with a dollar, refuse to
-insert one when `TeX-refuse-unmatched-dollar' is non-nil.
+See `TeX-insert-dollar-action' for more information on the
+behavior, as well as the role of ARG.
 
 Show matching dollar sign if this dollar sign ends the TeX math
-mode and `blink-matching-paren' is non-nil.
-
-When outside math mode, the behavior is controlled by the variable
-`TeX-electric-math'.
-
-With raw \\[universal-argument] prefix, insert exactly one dollar sign.
-With optional ARG, insert that many dollar signs."
+mode and `blink-matching-paren' is non-nil."
   (interactive "*P")
-  (cond
-   ((and arg (listp arg))
-    ;; C-u always inserts one
-    (insert "$"))
-   (arg
-    ;; Numerical arg inserts that many
-    (insert-char ?\$ (prefix-numeric-value arg)))
-   ((or (TeX-escaped-p) (TeX-verbatim-p))
-    ;; Point is escaped with `\' or is in a verbatim-like construct,
-    ;; so just insert one $.
-    (insert "$"))
-   ((texmathp)
-    ;; We are inside math mode
-    (cond
-     ((and TeX-electric-math
-           (eq (preceding-char) ?\$)
-           (eq (following-char) ?\$))
-      ;; Point is between "$$" and `TeX-electric-math' is non-nil -
-      ;; insert another pair of dollar signs and leave point between
-      ;; them.
-      (insert "$$")
-      (backward-char))
-     ((and (stringp (car texmathp-why))
-           (string-equal (substring (car texmathp-why) 0 1) "\$"))
-      ;; Math mode was turned on with $ or $$ - insert a single $.
-      (insert "$")
-      ;; Compatibility, `TeX-math-close-double-dollar' has been
-      ;; removed after AUCTeX 11.87.
-      (if (boundp 'TeX-math-close-double-dollar)
-          (message
-           (concat "`TeX-math-close-double-dollar' has been removed,"
-                   "\nplease use `TeX-electric-math' instead.")))
-      (when (and blink-matching-paren
-                 (or (string= (car texmathp-why) "$")
-                     (zerop (mod (save-excursion
-                                   (skip-chars-backward "$")) 2))))
-        (save-excursion
-          (goto-char (cdr texmathp-why))
-          (if (pos-visible-in-window-p)
-              (sit-for blink-matching-delay)
-            (message "Matches %s"
-                     (buffer-substring
-                      (point) (progn (end-of-line) (point))))))))
-
-     ;; Math mode was not entered with dollar according to `texmathp'.
-     (TeX-refuse-unmatched-dollar
-      ;; We trust `texmathp' and refuse to finish it with one.
-      (message "Math mode started with `%s' cannot be closed with dollar"
-               (car texmathp-why)))
-     (t
-      ;; We assume that `texmathp' was wrong and behave as if not in
-      ;; math mode. (bug#57626)
-      (TeX--insert-dollar-1))))
-   (t
-    ;; Just somewhere in the text.
-    (TeX--insert-dollar-1))))
-
-(defun TeX--insert-dollar-1 ()
-  "Do the job of `TeX-insert-dollar' in non-math mode."
-  (cond
-   ((and TeX-electric-math (TeX-active-mark)
-         (/= (point) (mark)))
-    (if (> (point) (mark))
-        (exchange-point-and-mark))
-    (cond
-     ;; $...$ to $$...$$
-     ((and (eq last-command #'TeX-insert-dollar)
-           (re-search-forward "\\=\\$\\([^$][^z-a]*[^$]\\)\\$" (mark) t))
-      (replace-match "$$\\1$$" t)
-      (set-mark (match-beginning 0)))
-     ;; \(...\) to \[...\]
-     ((and (eq last-command #'TeX-insert-dollar)
-           (re-search-forward "\\=\\\\(\\([^z-a]*\\)\\\\)" (mark) t))
-      (replace-match "\\\\[\\1\\\\]" t)
-      (set-mark (match-beginning 0)))
-     ;; Strip \[...\] or $$...$$
-     ((and (eq last-command #'TeX-insert-dollar)
-           (or (re-search-forward "\\=\\\\\\[\\([^z-a]*\\)\\\\\\]" (mark) t)
-               (re-search-forward "\\=\\$\\$\\([^z-a]*\\)\\$\\$" (mark) t)))
-      (replace-match "\\1" t)
-      (set-mark (match-beginning 0)))
-     (t
-      ;; We use `save-excursion' because point must be situated
-      ;; before opening symbol.
-      (save-excursion (insert (car TeX-electric-math)))
-      (exchange-point-and-mark)
-      (insert (cdr TeX-electric-math))))
-    (TeX-activate-region))
-   (TeX-electric-math
-    (insert (car TeX-electric-math))
-    (save-excursion (insert (cdr TeX-electric-math)))
-    (if blink-matching-paren
-        (save-excursion
-          (backward-char)
-          (sit-for blink-matching-delay))))
-   ;; In any other case just insert a single $.
-   ((insert "$")))
-  (TeX-math-input-method-off))
+  (pcase (TeX-insert-dollar-action arg)
+    ('just-insert
+     (self-insert-command (prefix-numeric-value arg)))
+    ('begin-math
+     (self-insert-command (prefix-numeric-value arg))
+     (TeX-math-input-method-off))
+    ('end-math                        ; Assume texmathp's been called.
+     (self-insert-command (prefix-numeric-value arg))
+     (TeX--blink-matching-dollar))
+    ('refuse
+     (message "Math mode started with `%s' cannot be closed with dollar"
+              (car texmathp-why)))
+    ('electric
+     (TeX-insert-dollar-electric))
+    (action (error "Unknown `TeX-insert-dollar' action: `%s'" action))))
+
+(put #'TeX-insert-dollar 'delete-selection
+     (lambda ()
+       (pcase (TeX-insert-dollar-action current-prefix-arg)
+         ('refuse nil)
+         ('electric nil)
+         (_else (get #'self-insert-command 'delete-selection)))))
 
 (defcustom TeX-math-input-method-off-regexp
   (concat "^" (regexp-opt '("chinese" "japanese" "korean" "bulgarian" 
"russian") t))
@@ -6360,6 +6407,10 @@ the settings of style files.  Style files should 
therefore check
 if this symbol is present and not alter `TeX-quote-language' if
 it is.")
 
+;; TODO: rework according to the slogan from
+;; `TeX--put-electric-delete-selection'. That entails splitting off the
+;; «electric» part that tries to do smart things and the plain part that
+;; just inserts a quote.
 (defun TeX-insert-quote (force)
   "Insert the appropriate quotation marks for TeX.
 Inserts the value of `TeX-open-quote' (normally \\=`\\=`) or `TeX-close-quote'
@@ -6445,6 +6496,8 @@ With prefix argument FORCE, always inserts \" characters."
                       (t
                        close-quote)))))))
 
+(put 'TeX-insert-quote 'delete-selection t)
+
 (defun TeX-insert-punctuation ()
   "Insert point or comma, cleaning up preceding space."
   (interactive)
@@ -6895,18 +6948,6 @@ The table inherits from USERTABLE if it is a valid 
abbrev table."
      (add-hook 'desktop-after-read-hook (lambda ()
                                           (TeX-set-mode-name t)))))
 
-;; delsel.el, `delete-selection-mode'
-(put 'TeX-newline 'delete-selection t)
-(put 'TeX-insert-quote 'delete-selection t)
-(put 'TeX-insert-backslash 'delete-selection t)
-;; When `TeX-electric-math' is non-nil, `TeX-insert-dollar' interferes with
-;; `delete-selection-mode', but when it's nil users may want to be able to
-;; delete active region if `delete-selection-mode' is active, see bug#23177.  
We
-;; can dynamically determine the behavior of `delete-selection' with
-;; `TeX-insert-dollar' based on the value of `TeX-electric-math'.
-(put 'TeX-insert-dollar 'delete-selection
-     (lambda () (null TeX-electric-math)))
-
 (defun TeX--list-of-string-p (lst)
   "Return non-nil if LST is a list of strings.
 Used as function for validating a variable's `safe-local-variable' property."

Reply via email to