2

While using AUCTeX, the macro \frac is quite intelligent that when I just type C-c C-m frac RET, it will put the cursor in the first pair of braces, as

\frac{(cursor here)}{}

However, when I have selected some text and do the same, it will put the cursor at the end like

\frac{some text}{}(cursor here)

instead of putting the cursor in the second pair of braces as follows

\frac{some text}{(cursor here)}

The same thing happens to \stackrel{}{}. Is there a way to achieve this? Many thanks!


BTW

I later find out that putting the following code in the .emacs file helps

(add-hook 'LaTeX-mode-hook
  '(lambda ()
     (TeX-add-symbols 
               '("frac" "Numerator" "Denominator"))))

but this does involve more interaction with the minibuffer, which seems to be an overkill for frac{}{} or \stackrel{}{}. Besides Greek letter would not work in the minibuffer, and this turns out to have been a problem since 1995.

1

You can write your own argument handler for TeX-parse-macro. The macros together with their argument description are registered in TeX-symbol-list. The entries in TeX-symbol-list are style dependent and must be set with TeX-add-symbols in LaTeX-mode-hook for that reason. I've stolen the method for setting up the LaTeX macros in TeX-symbol-list from that answer to another question on stackoverflow.

The following section from the help of TeX-parse-macro is important for automatically setting point after insertion of a macro:

(TeX-parse-macro SYMBOL ARGS)

How to parse TeX macros which takes one or more arguments.

First argument SYMBOL is the name of the macro.

If ARGS is nil, insert macro with point inside braces. Otherwise, each element in ARGS should match an argument to the TeX macro. What is done depend on the type of the element:

...

other symbols: Call the symbol as a function. You can define your own hook, or use one of the predefined argument hooks. If you add new hooks, you can assume that point is placed directly after the previous argument, or after the macro name if this is the first argument. Please leave point located after the argument you are inserting. If you want point to be located somewhere else after all hooks have been processed, set the value of ‘exit-mark’. It will point nowhere, until the argument hook set it. By convention, these hooks all start with ‘TeX-arg-’.

(defvar-local TeX-arg-use-region-p nil
  "Updated in `TeX-arg-1st-of-2' with the value of `TeX-active-mark' 
and used in `TeX-arg-2nd-of-2' to detect whether to put point in between the argument braces.")

(defun TeX-arg-1st-of-2 (optional &optional prompt)
  "First of two TeX macro arguments."
  ;; Code mostly stolen from a part of `TeX-parse-macro'.
  ;; The most important modification is setting `TeX-arg-use-region-p'.
  ;; After parsing the first LaTeX-macro-argument mark is deactivated and the
  ;; information about the activation of the region is lost.
  ;; We need that information for `TeX-arg-2nd-of-2' and therefore
  ;; save it in `TeX-arg-use-region-p'.
  (if optional
      (setq TeX-group "["
        TeX-grcl "]")
    (setq TeX-group "{"
      TeX-grcl "}"))
  (insert TeX-grop)
  (if (TeX-active-mark)
      (progn
    (setq TeX-arg-use-region-p t) ;; Region is active...
    (exchange-point-and-mark)
    (insert TeX-grcl))
    (setq TeX-arg-use-region-p nil) ;; Region is not active...
    (insert TeX-grcl)
    (set-marker exit-mark (1- (point)))))

(defun TeX-arg-2nd-of-2 (optional &optional prompt)
  "Second of two TeX macro arguments."
  (insert (if optional "[]" "{}"))
  (when TeX-arg-use-region-p ;; Put mark between the braces if region was active.
    (set-marker exit-mark (1- (point)))))

;; Installation of the hack stolen from https://stackoverflow.com/a/17249399/2708138
(defun TeX-hack-macro-args ()
  "Implement special argument handlers for TeX-macros \"frac\" and \"stackrel\"
in `TeX-symbol-list'. See `TeX-parse-macro' for more information."
  (cl-loop with args
       for macro-str in '("frac" "stackrel") do
       (TeX-add-symbols (list macro-str #'TeX-arg-1st-of-2 #'TeX-arg-2nd-of-2 '(ignore)))))

(add-hook 'LaTeX-mode-hook #'TeX-hack-macro-args)
  • This is amazing! and it is not as formidable as it looks. BTW, you solution also solves the problem for \qitem{}{} from the epigraph package, where the cursor was always put between the second pair of braces. Many thanks! – davyjones Nov 13 '17 at 6:57
  • @davyjones - Thanks for pointing out the issue with epigraph.el. I've updated that file and fixed also some other issues. It will be available with next AUCTeX release. – Arash Esbati Nov 18 '17 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.