11

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?

  • 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 '15 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 '15 at 13:54
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}
  • 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 '15 at 20:27
  • I bound it to M-DEL like in TexStudio. Thanks. – doctorate Jan 6 '15 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 '15 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 '15 at 8:55
  • @giordano Any chance this will make it into AucTex? It's very useful! – Tyler Nov 1 '17 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.
  • that was a very handy piece in the documentation that I missed. Thanks. – doctorate Jan 5 '15 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 '15 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 '15 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, privacy policy and cookie policy

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