The issue is mostly caused by autoloads.
In julia-mode.el you can see that (add-to-list 'auto-mode-alist '("\\.jl\\'" . julia-mode))
is marked as to be autoloaded. If you were to look at ~/.emacs.d/elpa/julia-mode-${version}/julia-mode-autoloads.el
(which is automatically generated from julia-mode.el
when you initially install the package), you would indeed see that line.
Crucially, the -autoloads.el
files in all the elpa/xx/
subdirectories are, themselves, loaded automatically† and at the very beginning of start-up — their purpose is to defer loading of the "real" files until they're necessary, but in order for that to be possible, they have to be loaded at start-up). Indeed, if you were to comment out your entire init-file, but without deleting any of the installed packages, auto-mode-alist
would still contain ("\\.jl\\'" . julia-mode)
.
† well, unless you set package-enable-at-startup
to nil
In contrast, ess-autoloads.el
only adds '("\\.R$" . R-mode)
to the auto-mode-alist (see here — yes, in the case of ess
, the autoloads file is present at the source, rather than being generated at installation, but that doesn't really matter). The .jl
association is, as you noted, only added in ess-julia.el
.
add-to-list
adds the given element to the top of the list, but only if it's not already present (see the docstring of the function). Hence, the order of operations regarding the .jl
association is:
("\\.jl\\'" . julia-mode)
is added from julia-mode-autoloads.el
When you (require 'ess-site)
, which in turn require
s ess-julia.el
, auto-mode-alist
has ("\\.jl\\'" . ess-julia-mode)
added to its beginning, effectively "overriding"‡ ("\\.jl\\'" . julia-mode)
:mode "\\.jl\\'"
expands to (add-to-list 'auto-mode-alist '("\\.jl\\'" . julia-mode))
, but since ("\\.jl\\'" . julia-mode)
is already an element of auto-mode-alist
, it does nothing.
‡ when opening a file, parsing of auto-mode-alist
is in order, and (sort-of) stops when you find a match, so later occurrences of the same pattern have no effect
Hack-ish solution
Change the use-package block dedicated to julia-mode
:
(use-package julia-mode
:init
(push '("\\.jl\\'" . julia-mode) auto-mode-alist)
(delete-dups auto-mode-alist))
push
, unlike add-to-list
does not try to be clever and just adds the element to the beginning of the list. delete-dups
removes duplicates, leaving the first occurrence (it's not strictly necessary, but I've added it for neatness's sake). As a result, ("\\.jl\\'" . julia-mode)
is now before ("\\.jl\\'" . ess-julia-mode)
.
Why does assq-delete-all
not work?
assq-delete-all
uses eq
rather than equal
for comparison (see the docstring), but eq
does not work in the "expected" way for string — e.g. (eq "a" "a")
evaluates to nil.