Function: hack-local-variables--find-variables
hack-local-variables--find-variables is a byte-compiled function
defined in files.el.gz.
Signature
(hack-local-variables--find-variables &optional HANDLE-MODE)
Documentation
Return all local variables in the current buffer.
If HANDLE-MODE is nil, we gather all the specified local
variables. If HANDLE-MODE is neither nil nor t, we do the same,
except that any settings of mode are ignored.
If HANDLE-MODE is t, all we do is check whether a "mode:" is specified, and return the corresponding mode symbol, or nil. In this case, we try to ignore minor-modes, and return only a major-mode.
Source Code
;; Defined in /usr/src/emacs/lisp/files.el.gz
(defun hack-local-variables--find-variables (&optional handle-mode)
"Return all local variables in the current buffer.
If HANDLE-MODE is nil, we gather all the specified local
variables. If HANDLE-MODE is neither nil nor t, we do the same,
except that any settings of `mode' are ignored.
If HANDLE-MODE is t, all we do is check whether a \"mode:\"
is specified, and return the corresponding mode symbol, or nil.
In this case, we try to ignore minor-modes, and return only a
major-mode."
(let ((result nil))
;; Look for "Local variables:" line in last page.
(save-excursion
(goto-char (point-max))
(search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
'move)
(when (let ((case-fold-search t))
(search-forward "Local Variables:" nil t))
(skip-chars-forward " \t")
;; suffix is what comes after "local variables:" in its line.
;; prefix is what comes before "local variables:" in its line.
(let ((suffix
(concat
(regexp-quote (buffer-substring (point)
(line-end-position)))
"$"))
(prefix
(concat "^" (regexp-quote
(buffer-substring (line-beginning-position)
(match-beginning 0))))))
(forward-line 1)
(let ((startpos (point))
endpos
(selective-p (eq selective-display t))
(thisbuf (current-buffer)))
(save-excursion
(unless (let ((case-fold-search t))
(re-search-forward
(concat prefix "[ \t]*End:[ \t]*" suffix)
nil t))
;; This used to be an error, but really all it means is
;; that this may simply not be a local-variables section,
;; so just ignore it.
(message "Local variables list is not properly terminated"))
(beginning-of-line)
(setq endpos (point)))
(with-temp-buffer
(insert-buffer-substring thisbuf startpos endpos)
(goto-char (point-min))
(if selective-p
(subst-char-in-region (point) (point-max) ?\r ?\n))
(while (not (eobp))
;; Discard the prefix.
(if (looking-at prefix)
(delete-region (point) (match-end 0))
(user-error "Local variables entry is missing the prefix"))
(end-of-line)
;; Discard the suffix.
(if (looking-back suffix (line-beginning-position))
(delete-region (match-beginning 0) (point))
(user-error "Local variables entry is missing the suffix"))
(forward-line 1))
(goto-char (point-min))
(while (not (eobp))
;; Find the variable name;
(unless (looking-at hack-local-variable-regexp)
(user-error "Malformed local variable line: %S"
(buffer-substring-no-properties
(point) (line-end-position))))
(goto-char (match-end 1))
(let* ((str (match-string 1))
(var (intern str))
val val2)
(and (equal (downcase (symbol-name var)) "mode")
(setq var 'mode))
;; Read the variable value.
(skip-chars-forward "^:")
(forward-char 1)
;; As a defensive measure, we do not allow
;; circular data in the file-local data.
(let ((read-circle nil))
(setq val (read (current-buffer))))
(if (eq handle-mode t)
(and (eq var 'mode)
;; Specifying minor-modes via mode: is
;; deprecated, but try to reject them anyway.
(not (string-match
"-minor\\'"
(setq val2 (downcase (symbol-name val)))))
(let ((mode (intern (concat val2 "-mode"))))
(when (fboundp (major-mode-remap mode))
(setq result mode))))
(cond ((eq var 'coding))
((eq var 'lexical-binding)
(unless hack-local-variables--warned-lexical
(setq hack-local-variables--warned-lexical t)
(display-warning
'files
(format-message
"%s: `lexical-binding' at end of file unreliable"
(file-name-nondirectory
;; We are called from
;; 'with-temp-buffer', so we need
;; to use 'thisbuf's name in the
;; warning message.
(or (buffer-file-name thisbuf) ""))))))
((eq var 'read-symbol-shorthands)
;; Sort automatically by shorthand length
;; in descending order.
(setq val (sort val
(lambda (sh1 sh2) (> (length (car sh1))
(length (car sh2))))))
(push (cons 'read-symbol-shorthands val) result))
((and (eq var 'mode) handle-mode))
(t
(ignore-errors
(push (cons (if (eq var 'eval)
'eval
(indirect-variable var))
val)
result))))))
(forward-line 1)))))))
result))