# Autocomplete environments like in TeXStudio

TeXStudio autocompletes environments. How can I get AUCTeX to do the same?

I can begin typing an environment name (say myenvironment) and, after entering a part of it (my, myenv, etc.), I hit Control-Alt-Space, and TeXStudio autocompletes the environment (asking if there are multiple possibilities), and sets the point between \begin{myenvironment} and \end{myenvironment}.

I tried yasnippet mode, but this works only for predefined snippets. So I have, for example, to define a keyword myenv and it will only autocomplete the snippet for the environment if myenv + TAB is entered and not when only my + TAB is entered (with a list of possible completions) or if I type myenvi + TAB.

I also tried predictive-mode which seems to complete only words.

EDIT: I know the AUCTeX way to do this via C-c C-e. The difference to the desired TeXStudio approach is that you have to give a key sequence first and then input a few letters of the environment name, whereas in TeXStudio it is the other way around (which is what I am asking here).

• Both company-mode and auto-complete-mode offer integration for yasnippet, perhaps that's what you're looking for. – wasamasa Dec 21 '14 at 23:24

Auctex provides environment completion with the function M-x LaTeX-environment by default bound to C-c C-e. The details are provided in the fine manual.

• Thanks. But that's not exactly what I asked for. See my edit above. – student Dec 21 '14 at 22:08

@Tyler's answer (C-c C-e) is the simplest and most straightforward way to get environments insofar as it's the built-in way to use AUCTeX's functionality. Since it gets you 99% of the way there, it seems like the way to go unless you really need to do it auto-complete style.

If you really wanted to, you could wrap that command in a snippet so that you could invoke it while typing (here, as ,env TAB):

# -*- mode: snippet -*-
# name: environment
# key: ,env
# type: command
# --
(call-interactively #'LaTeX-environment)


Of course, that's little more than a change of keybindings. (I use the snippet to minimize use of the Control key, but YMMV.) If, however, you're using ido-mode (and particularly ido-vertical-mode), it'll make the completion experience much more pleasant in either the stock (C-c C-e) or snippet version.

The command LaTeX-insert-environment-at-point defined below tries to complete an environment name at point. If the prefix is ambiguous, it pulls up the same list of completions as C-x C-e does. If AUCTeX knows about the environment, you may be prompted for parameters (same as with C-x C-e). As a bonus, if the name is preceded by a backslash, insert a command instead. Bind it to the key of your choice.

(defvar LaTeX-environment-name-characters
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*")
(defun LaTeX-insert-environment-at-point ()
"Insert \begin{ENVIRONMENT}...\end{ENVIRONMENT}, completing the word at point.
If the word at point is preceded by a backslash, complete a macro name instead,
like \\[TeX-insert-macro].
The customization possibilities are the same as \\[LaTeX-environment]."
(interactive "@*")
(save-match-data
(let* ((prefix-start (save-excursion
(skip-chars-backward LaTeX-environment-name-characters)
(point)))
(backslash (and (> prefix-start (point-min))
(= (char-after (1- prefix-start)) ?\\)))
(completions (if backslash
(TeX-symbol-list)
(LaTeX-environment-list)))
(prefix (buffer-substring-no-properties prefix-start (point)))
(matches (remove-if-not (lambda (entry)
(string-prefix-p prefix entry))
(mapcar #'car completions)))
(name (case (length matches)
((0)
(error "No environment name begins with %s" prefix))
((1)
(car matches))
(t
;; Gross hack: arrange to show the list of completions,
;; by pushing a minibuffer-complete' event (assuming
;; default key bindings).
"Environment type: ")
completions
nil
nil
prefix
(if backslash
'TeX-macro-history
'LaTeX-environment-history))))))
(delete-region prefix-start (point))
(funcall (if backslash #'TeX-insert-macro #'LaTeX-environment-menu) name))))

• Thanks, I tried it but, I got the following error message: Mark set completing-read-default: Command attempted to use minibuffer while in minibuffer Quit [2 times] Mark set Mark saved where search started let*: Symbol's function definition is void: remove-if-not – student Dec 28 '14 at 19:57

To get such behaviour, you an use helm-c-yasnippet. Using the command helm-yas-complete in you case, it will do exactly what you want: gives a list of candidates available in yasnippet that start with the supplied prefix.

By default, yasnippet is bundled with common snippets. You can load more snippets with yasnippets-latex.

• Interesting. Would this not require you to have all of the snippets pre-defined, however? – Dan Dec 22 '14 at 12:46
• Yes. Here are the default predefined templates in yasnippet. At least you have all the standard environments. Maybe if someone creates helm-auctex-environment, then we will have something similar to helm-yas-complete` without predefining templates. – Tu Do Dec 22 '14 at 14:56