3

In my .emacs, I distinguish between two scenarios:

  • AUCTeX is not available. Then I load my customizations for the basic TeX mode — let's call that (my-tex-mode-customizations).
  • AUCTeX is available. Then I load my AUCTeX customizations — let's call that (my-auctex-customizations).

I currently check this by testing whether (require 'tex-site) succeeds. This worked fine in the good old days, and still works when AUCTeX is installed system-wide or manually with tex-site somewhere in load-path, but it fails when AUCTeX is installed through Emacs's package mechanism, because then tex-site is loaded during package initialization which happens after the init file.

If AUCTeX is available as a package, I want to load my AUCTeX customizations. Furthermore, if AUCTeX is both available as a package and provided system-wide, then tex-site is already loaded by the time my init file runs, but I'd like to unload it and load the one available through the package mechanism instead. More precisely, ideally, I'd like to use the most recent AUCTeX version in this situation.

So my code might look like this:

(defun auctex-is-available ()
  (condition-case nil
      (progn
        (require 'tex-site)
        AUCTeX-version)
    nil))
(defun use-auctex-package-p ()
  ;; Test if AUCTeX is available as a package.
  ;; Preferably, if AUCTeX is also available by loading `tex-site'
  ;; from elsewhere, only use the package if it's more recent.
  ???)
(cond
 ((use-auctex-package-p)
  (if (featurep 'tex-site) (unload-feature 'tex-site))
  (eval-after-load 'tex-site '(my-auctex-customizations)))
 ((auctex-is-available)
  (my-auctex-customizations)
 (t
  (my-tex-mode-customizations)))

But in .emacs, how do I test for available package versions? If I do that in a post-init hook, which one, keeping in mind that:

  • if AUCTeX is both present as a package and installed system-wide then the package must be used (at least if it's more recent);
  • if AUCTeX is not present as a package then an attempt must be made to load tex-site;
  • if there's no AUCTeX anywhere then my-tex-mode-customizations must get executed;
  • if AUCTeX is loaded from anywhere then my-auctex-customizations must get executed after the final tex-site has been loaded;
  • all of this must happen before desktop loads my saved session;
  • this must work on all Emacs versions that have a package facility (I'll fill in the (fboundp 'package-…) to cope with older versions).
3
  • When you say "present as a package", you mean it's installed using ELPA? List of installed packages is held in package-alist.
    – giordano
    Mar 16, 2016 at 17:34
  • @giordano Yes, I mean ELPA. package-alist isn't available from .emacs, any more than package-installed-p which looks like the right function to use. Mar 16, 2016 at 17:47
  • Ok, then you could use this hackish solution: (directory-files (concat user-emacs-directory "elpa") t "auctex-[.0-9]+")
    – giordano
    Mar 16, 2016 at 17:52

2 Answers 2

3

It is strongly recommended to initialize ELPA packages early by adding

(package-initialize)

somewhere at the beginning of your ~/.emacs file. The initialization that's done after loading the .emacs file is just a fallback behavior.

Actually in Emacs-25.1, the (package-initialize) call will be added automatically for you in some cases.

1
  • That's only part of it though, because when AUCTeX is installed system-wide, tex-site is already loaded by the time my init file starts, and I need to unload it to get the packaged AUCTeX instead. Mar 19, 2016 at 15:25
2

Calling package-initialize from .emacs is the right way to go. The only reason Emacs does it after the init file rather than before is to give the user the opportunity to customize or disable it in the init file.

To avoid mixing up the system-wide AUCTeX installation with the ELPA package when both are present, unload tex-site before initializing the package system, and load it again afterwards. This causes an unnecessary unload/load sequence if AUCTeX is installed system-wide and not as a package, but that's not a big deal.

(when (fboundp 'package-initialize)
  ;; If AUCTeX is both provided by the system and installed as a package, I
  ;; want to use the package version. If `tex-site' is already loaded, that
  ;; causes `auctex-autoloads' to depend on the system-provided `tex-site'. So
  ;; unload `tex-site'; I'll try to load it again later anyway. With
  ;; `tex-site' now unloaded, if a package is present, it gets to be ahead of
  ;; the system version in `load-path' and so the package is loaded.
  (if (featurep 'tex-site)
      (unload-feature 'tex-site))
  (package-initialize)

(if (require 'tex-site nil t)
    (my-auctex-customizations)
  (my-tex-mode-customizations))

This always prefers a package installation to a non-package installation, but that's not a real problem: the package installation is a user-level installation, so it's under my control, and it would normally be the latest stable version anyway.

If there are style files generated system-wide that I want to use, I might want to keep TeX-style-global around from the system-wide installation.

Your Answer

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

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