12

In TeXStudio by hitting ALT+DEL in a LaTeX macro like this \macroname{content} while the cursor stands just before the first { will result in deleting all that except its content (as shown below).

enter image description here
Put the cursor (point) just before the first curly bracket:

enter image description here

Hit ALT+DEL and you get:

enter image description here

How to achieve this in Emacs?

Update
According to T.Verron's clarification there is a problem with C-c C-f C-d as it complains from error of unbalanced parenthesis when executed within some macros in LaTeX. Consider the below example:
enter image description here

throws this error: up-list: Scan error: "Unbalanced parentheses", 8074, 1. \textenglish{} belongs to polyglossia package.

How to get rid of this caveat?

2
  • Hem, the caveat with the current answer is not about whether auctex fontifies the macro or not, it is about whether the macro is a latex font specification (probably as defined by TeX-font-list) or not. For example, try with \section or \footnote, AUCTeX knows about these macros and fontifies them, but C-c C-f C-d will complain about unbalanced parentheses.
    – T. Verron
    Jan 5, 2015 at 13:38
  • Even if I can update this TeX-font-list to include my newly introduced macros, this remains a suboptimal workaround. Otherwise, I don't know what prvents having an eLISP function to deal with it!
    – doctorate
    Jan 5, 2015 at 13:54

3 Answers 3

11

Try this function:

(defun mg-TeX-delete-current-macro (&optional arg)
  "Remove the current macro.
With an optional argument ARG, delete just the ARG-th macro
starting from the innermost."
  (interactive "*p")
  (let (macro end)
    (when 
    (dotimes (i arg macro)
      (goto-char (TeX-find-macro-start))
      (setq macro (TeX-current-macro)
        end (TeX-find-macro-end))
      ;; If we need to look for an outer macro we have to "exit" from the
      ;; current one.
      (backward-char))
      ;; Return to the beginning of the macro to be deleted.
      (forward-char)
      (re-search-forward
       (concat (regexp-quote TeX-esc) macro "\\(?:\\[[^]]*\\]\\)?"
           TeX-grop "\\(\\(.\\|\n\\)*\\)")
       end t)
      (replace-match "\\1")
      ;; Delete the closing brace.
      (delete-backward-char 1))))

Limitation: doesn't work with verbatim-like macros. This function will throw an error (Wrong type argument: integer-or-marker-p, nil) if the universal argument is greater than the number of macros enclosing point.

Bind the function to your favorite shortcut. For example

(eval-after-load "tex"
  '(local-set-key (kbd "M-DEL") 'mg-TeX-delete-current-macro))

to bind it it M-DEL.

If your buffer has (! is point)

\onemacro{\anothermacro{!argument}}

then C-2 M-DEL will give you

\anothermacro{argument}
6
  • If the point inside innermost group (gr1(gr2(gr3(gr4)))) do you mean by a prefix C-u then 2 it will give me: (gr1(gr2))? if it is so, that must be brilliant. I hope you had the time to do it.
    – doctorate
    Jan 6, 2015 at 20:27
  • I bound it to M-DEL like in TexStudio. Thanks.
    – doctorate
    Jan 6, 2015 at 20:42
  • @doctorate Well, no, my idea is to delete just the second macro, gr3 in your case. See the updated answer. You can implement what you suggested by wrapping a dotimes around when of the original version of the answer.
    – giordano
    Jan 6, 2015 at 21:10
  • Great function! Now it behaves like a smart macro-pacman! one caveat though; when the argument is big and it throws an error the point jumps somewhere backward. Can you make it complain while standing in its current place?
    – doctorate
    Jan 7, 2015 at 8:55
  • @giordano Any chance this will make it into AucTex? It's very useful!
    – Tyler
    Nov 1, 2017 at 15:40
9

From the AUCTeX manual node on Changing the font:

C-c C-f C-d

Delete the innermost font specification containing point.
3
  • that was a very handy piece in the documentation that I missed. Thanks.
    – doctorate
    Jan 5, 2015 at 12:55
  • But it only works for font specifications (and the verification makes sense, for example for \emph{\randommacro{test}} it will delete the \emph).
    – T. Verron
    Jan 5, 2015 at 13:03
  • @T.Verron: good clarification. I'm not aware of a built-in way to do this for arbitrary LaTeX macros.
    – Dan
    Jan 5, 2015 at 13:08
4

Here's a simple function to remove the containing macro at point:

(defun TeX-remove-macro ()
  "Remove current macro and return `t'.  If no macro at point,
return `nil'."
  (interactive)
  (when (TeX-current-macro)
    (let ((bounds (TeX-find-macro-boundaries))
          (brace  (save-excursion
                    (goto-char (1- (TeX-find-macro-end)))
                    (TeX-find-opening-brace))))
      (delete-region (1- (cdr bounds)) (cdr bounds))
      (delete-region (car bounds) (1+ brace)))
    t))

Hence, with * as point:

\footnote{Here's a * footnote} 
  => Here's a footnote

Given the above function, it's a one-liner to remove all the macros at point:

(defun TeX-remove-all-macros ()
  "Remove all containing macros for text at point."
  (interactive)
  (while (TeX-remove-macro)))

Hence, again with * as point:

\footnote{Here's a \textbf{footnote with \emph{emphasized * text}}} 
  => Here's a footnote with emphasized text

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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