3

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
3

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.

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

@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.

1

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).
                    (setq unread-command-events (cons 'tab unread-command-events))
                    (completing-read (if backslash "Macro: "
                                       "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
0

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
  • 1
    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

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.