Function: so-long--check-header-modes

so-long--check-header-modes is a byte-compiled function defined in so-long.el.gz.

Signature

(so-long--check-header-modes)

Documentation

Handle the header-comments processing in set-auto-mode.

set-auto-mode has some special-case code to handle the mode pseudo-variable when set in the header comment. This runs outside of hack-local-variables and cannot be conveniently intercepted, so we are forced to replicate it here.

This special-case code will ultimately be removed from Emacs, as it exists to deal with a deprecated feature; but until then we need to replicate it in order to inhibit our own behavior in the presence of a header comment mode declaration.

If a file-local mode is detected in the header comment, then we call the function defined by so-long-file-local-mode-function.

Source Code

;; Defined in /usr/src/emacs/lisp/so-long.el.gz
(defun so-long--check-header-modes ()
  ;; See also "Files with a file-local 'mode'" in the Commentary.
  "Handle the header-comments processing in `set-auto-mode'.

`set-auto-mode' has some special-case code to handle the `mode' pseudo-variable
when set in the header comment.  This runs outside of `hack-local-variables'
and cannot be conveniently intercepted, so we are forced to replicate it here.

This special-case code will ultimately be removed from Emacs, as it exists to
deal with a deprecated feature; but until then we need to replicate it in order
to inhibit our own behavior in the presence of a header comment `mode'
declaration.

If a file-local mode is detected in the header comment, then we call the
function defined by `so-long-file-local-mode-function'."
  ;; The following code for processing MODE declarations in the header
  ;; comments is copied verbatim from `set-auto-mode', because we have
  ;; no way of intercepting it.
  ;;
  (let ((try-locals (not (inhibit-local-variables-p)))
        end _done _mode modes)
    ;; Once we drop the deprecated feature where mode: is also allowed to
    ;; specify minor-modes (ie, there can be more than one "mode:"), we can
    ;; remove this section and just let (hack-local-variables t) handle it.
    ;; Find a -*- mode tag.
    (save-excursion
      (goto-char (point-min))
      (skip-chars-forward " \t\n")
      ;; Note by design local-enable-local-variables does not matter here.
      (and enable-local-variables
           try-locals
           (setq end (set-auto-mode-1))
           (if (save-excursion (search-forward ":" end t))
               ;; Find all specifications for the `mode:' variable
               ;; and execute them left to right.
               (while (let ((case-fold-search t))
                        (or (and (looking-at "mode:")
                                 (goto-char (match-end 0)))
                            (re-search-forward "[ \t;]mode:" end t)))
                 (skip-chars-forward " \t")
                 (let ((beg (point)))
                   (if (search-forward ";" end t)
                       (forward-char -1)
                     (goto-char end))
                   (skip-chars-backward " \t")
                   (push (intern (concat (downcase (buffer-substring
                                                    beg (point)))
                                         "-mode"))
                         modes)))
             ;; Simple -*-MODE-*- case.
             (push (intern (concat (downcase (buffer-substring (point) end))
                                   "-mode"))
                   modes))))

    ;; Now process the resulting mode list for `so-long--set-auto-mode'.
    ;; If any modes were listed, we assume that one of them is a major mode.
    ;; It's possible that this isn't true, but the buffer would remain in
    ;; fundamental-mode if that were the case, so it is very unlikely.
    ;; For the purposes of passing a value to `so-long-handle-file-local-mode'
    ;; we assume the major mode was the first mode specified (in which case it
    ;; is the last in the list).
    (when modes
      (so-long-handle-file-local-mode (car (last modes))))))