3

The first time I create a new LaTeX document* in a new instance of Emacs AUCTeX scans my TeXLive installation to find all the available document classes .

This scanning, due to the complexity and dimensions of a typical TeXLive, takes (much less than the time I spend writing this question but nonetheless) a considerable amount of time but after that the available classes are cached and creating a second new document is instantaneous.

I wonder if it is possible to have AUCTeX cache the classes to disk, possibly with a mechanism to enforce a fresh scan of the TeXLive tree.

[*] Strictly speaking scanning happens when I create a document environment but I create a document environment every time a create a new LaTeX document.

3

Thank you for asking this question! This has been bothering me for a long time, but I never did anything about it until your question gave me a little extra motivation.

Turns out it's pretty simple to make the cache by hand. You just need to arrange to assign values to two variables after AUCTeX is loaded:

(setq LaTeX-global-class-files '("List of document classes"))
(setq TeX-global-input-files '("List of packages"))

(Those, of course, are placeholders: I'll explain one way to get the correct lists below.)

So, if in your init file you have some configuration for AUCTeX, just stick in those assignments (for example, I have a (use-package 'latex :ensure auctex ...) form in my init file and I put the assignments after :config). If you currently don't have any configuration for AUCTeX, you can wrap those assignments in a with-eval-after-load form, just be aware that the feature AUCTeX provides is called latex (and not auctex or something like that), so you'd do:

(with-eval-after-load 'latex
  (setq LaTeX-global-class-files '("List of document classes"))
  (setq TeX-global-input-files '("List of packages")))

OK, so to generate the lists what I did was simply start a new LaTeX file, insert a document environment and a package, and then use describe-variable (bound to C-h v) to see the help for those variables. The help buffer that pops up also includes the current value of the variable and you can yank it from there to the proper place in your init file (don't forget to add the single quote at the beginning).

And, to be honest, I didn't want to clutter my init file with those huge lists (I have 185 document classes and 2934 packages), so I put the assignments in their own file that I load from my init file.

| improve this answer | |
  • A more robust solution would provide an easy way to update the cache, but since I don't forsee installing new document classes or packages very often, I'll just update my cache manually. – Omar Jun 6 '19 at 13:03
  • 185 document classes and 2934 packages Oh yes, this is the root of the problem... Omar, tonight (Italy) I will look into the merits of your answer, for now it's just a resounding THANK YOU – gboffi Jun 6 '19 at 13:10
  • @gboffi I just checked on my office computer and there I have 441 document classes and 3965 packages (which do include all the ones I have at home, according to cl-set-difference)! – Omar Jun 6 '19 at 17:34
2

Starting from Omar's answer I've put together an interactive function, dump-auctex-globals, that writes to the standard user's Emacs directory a (very simple) Emacs Lisp file that sets the two global variables

(defun dump-auctex-globals ()
  "Write global LaTeX class and TeX input files to auctex-globals.el."
  (interactive)
  (let ((filename (expand-file-name "auctex-globals.el" user-emacs-directory)))
    (if (and (file-directory-p user-emacs-directory)
             (file-writable-p user-emacs-directory)
             LaTeX-global-class-files
             TeX-global-input-files)
        (with-temp-file filename
          (insert
           (format "(setq LaTeX-global-class-files '%S
      TeX-global-input-files '%S)"
               LaTeX-global-class-files
               TeX-global-input-files))
              nil))))

The function above does nothing if it is called before the two global variables are initialized, its intended use is after AUCTeX has somehow initialized them.

Another useful function is

(defun clear-auctex-globals ()
  (interactive)
  (setq LaTeX-global-class-files nil)
  (setq TeX-global-input-files nil))

that can be evaluated when we want to force AUCTeX to parse the TeXLive/whatever tree.

After we have cached the variables values we just need to load-file their disk image

(defun possibly-load-auctex-globals ()
  (let ((filename (expand-file-name "auctex-globals.el" user-emacs-directory)))
    (if (and (file-exists-p filename)
             (file-readable-p filename))
        (load-file filename))))

and have in our ~/.emacs a mechanism to perform the loading.

(with-eval-after-load 'latex
  (possibly-load-auctex-globals))

Note that if the file does not exist/is not readable nothing happens...


Note: I'm not sure to have written robust/elegant Emacs Lisp code (I suspect the opposite is true...) and I'm very open to your edits.

| improve this answer | |
  • I've edited dump-auctex-globals a bit as requested. Please test. – Tobias Jun 6 '19 at 21:18
  • 1
    @Tobias It's much nicer w/o the prin1, terpri etc, also emacs-user-directory is an enhancement. You missed that the filename had an underscore when written and a dash when loaded, but I have corrected that 😆. – gboffi Jun 6 '19 at 21:46

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.