Important
This gist is temporary until the new documentation (docs.doomemacs.org) and community wiki (wiki.doomemacs.org) have been published.
When Emacs visits a file, it determines the major mode to activate based on:
- The file path,
- The contents of the file (shebang lines or text patterns near the beginning of the file),
- Or any file or directory-local settings for
mode.
The auto-mode-alist variable contains an association-list mapping file name patterns (regular expressions) to the function that activates a major mode. Typically, the file name patterns test for file extensions, such as .el and .c. For example, to associate *.js files with typescript-mode instead of js2-mode:
;; add to ~/.doom.d/config.el
(add-to-list 'auto-mode-alist '("\\.js\\'" . typescript-mode))Or any file in any */templates/* directory to be associated with web-mode:
;; add to ~/.doom.d/config.el
(add-to-list 'auto-mode-alist '("/templates/" . web-mode))At the top of most shell scripts you'll find a special line that looks like: #!/bin/bash.
This is a shebang line. It tells the OS what program to launch your script with.
Emacs acn determine the major mode from the shebang line, based on the rules set in interpreter-mode-alist; an association list mapping shebang line patterns (regex) to major modes (functions).
For example, to associate python3 with python-mode:
(add-to-list 'interpreter-mode-alist '("python3" . python-mode))Let's look at a more advanced example: nix-shell.
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p maim slop
...nix-shell functions as a wrapper around another program (bash, in this case). In order to handle this something more specialized is needed:
(defun +nix-shell-init-mode ()
(save-excursion
(goto-char (point-min))
(save-match-data
(if (not (re-search-forward "#! *nix-shell +-i +\\([^ \n]+\\)" 256 t))
(message "Couldn't determine mode for this script")
(let* ((interp (match-string 1))
(mode
(assoc-default
interp
(mapcar (lambda (e)
(cons (format "\\`%s\\'" (car e))
(cdr e)))
interpreter-mode-alist)
#'string-match-p)))
(when mode
(prog1 (set-auto-mode-0 mode)
(when (eq major-mode 'sh-mode)
(sh-set-shell interp)))))))))
(add-to-list 'interpreter-mode-alist '("nix-shell" . +nix-shell-init-mode))This searches for the #! nix-shell -i bash ... line, extracts the interpreter from the -i switch, and then searches for bash in interpreter-mode-alist to acquire the desired major-mode.
The major mode for files without file extensions or shebang lines may be deduced by searching for common patterns within its contents. This is where magic-mode-alist comes in; an association list mapping regex patterns to major modes (or functions). It is consulted before auto-mode-alist.
For example, to use xml-mode when the file starts with <?xml:
(add-to-list 'magic-mode-alist '("^<\\?xml" . xml-mode))There's also magic-fallback-mode-alist, which is consulted if no mode can be determined from magic-mode-alist or auto-mode-alist.
-
;; -*- mode: emacs-lisp; -*-or;; -*- emacs-lisp -*-at the top of the file, or this at the bottom:;; Local Variables: ;; mode: emacs-lisp ;; End:Will cause Emacs to open that file in
emacs-lisp-mode. -
Additionally, a
.dir-locals.elfile can be used to force all files in a directory to open in a specific major mode:((nil . ((mode . c)))
Tip
See "File and directory local settings" for more information.