Function: elisp--xref-infer-namespace
elisp--xref-infer-namespace is a byte-compiled function defined in
elisp-mode.el.gz.
Signature
(elisp--xref-infer-namespace POS)
Documentation
Find the likely namespace of the identifier at POS.
Return one of function, variable maybe-variable, feature, face, or
any (indicating any namespace). maybe-variable indicates a variable
namespace but with lower confidence.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/elisp-mode.el.gz
(defun elisp--xref-infer-namespace (pos)
"Find the likely namespace of the identifier at POS.
Return one of `function', `variable' `maybe-variable', `feature', `face', or
`any' (indicating any namespace). `maybe-variable' indicates a variable
namespace but with lower confidence."
(save-excursion
(goto-char pos)
(cl-flet ((looking-at-sym ()
(let ((val (save-excursion
(ignore-errors (read (current-buffer))))))
(and (symbolp val) val))))
(cond
((and (eq (char-before pos) ?\')
(eq (char-before (1- pos)) ?#))
;; #'IDENT
'function)
((memq (char-before pos) '(?\' ?`))
;; 'IDENT or `IDENT -- try to disambiguate.
(backward-char) ; Step over '
(let ((i (elisp--xref-list-index))
(sym (looking-at-sym)))
(cond
((eql i 1)
(cond
((memq sym '( featurep require provide))
'feature)
((memq sym
'(
;; We are mostly interested in functions that take a
;; function symbol as argument:
fboundp symbol-function fset
;; ... but we include some common higher-order functions
;; as well, even though the argument really should
;; be #'-quoted:
function-get function-put
func-arity functionp
funcall funcall-interactively
apply mapcar mapc mapcan mapconcat
apply-partially
substitute-key-definition))
'function)
((memq sym
'(
;; Functions taking a variable symbol as first argument.
;; More of these could be added for greater precision.
boundp set symbol-value
special-variable-p local-variable-p
local-variable-if-set-p
make-variable-buffer-local
default-value set-default make-local-variable
buffer-local-value))
'variable)
((memq sym
'(
;; FIXME: Add more functions taking a face
;; symbol for greater precision.
facep face-name face-id))
'face)
(t 'any)))
((and (eql i 2)
(memq sym '( global-set-key local-set-key
substitute-key-definition
add-hook)))
'function)
((and (eql i 3)
(memq sym '( define-key add-function)))
'function)
(t 'any))))
((or (and (eq (char-before (1- pos)) ?,)
(eq (char-before pos) ?@))
(eq (char-before pos) ?,))
;; ,IDENT or ,@IDENT
'variable)
(t
;; Unquoted name -- look at the context. General scheme:
;; (K-HEAD ... (J-HEAD ... (I-HEAD ... IDENT
;; ^ index K ^ index J ^ index I
(let* ((i (elisp--xref-list-index))
(i-head (looking-at-sym))
(i-paren (and i (eq (char-before) ?\()
(progn (backward-char) t)))
(i-quoted (and i-paren (memq (char-before) '(?\' ?`))))
(j (and i-paren (elisp--xref-list-index)))
(j-head (and j (looking-at-sym)))
(j-paren (and j (eq (char-before) ?\()
(progn (backward-char) t)))
(j-quoted (and j-paren (memq (char-before) '(?\' ?`))))
(k (and j-paren (elisp--xref-list-index)))
(k-head (and k (looking-at-sym)))
(k-paren (and k (eq (char-before) ?\()
(progn (backward-char) t)))
(k-quoted (and k-paren (memq (char-before) '(?\' ?`)))))
(cond
((or i-quoted j-quoted k-quoted)
;; '(... IDENT or '(... (... IDENT or '(... (... (... IDENT
'any)
((and (eql j 1)
(memq j-head '( let let* letrec dlet lambda)))
;; (let (... IDENT
'variable)
((and (eql j 2)
(memq j-head '( defun defmacro defsubst
define-inline declare-function
defadvice
cl-defmethod cl-defgeneric)))
;; (defun FUNC (... IDENT
'variable)
((and (eql j 2)
(eq j-head 'defclass))
;; (defclass CLASS (... IDENT
'function)
((eq j-head 'cond)
;; (cond ... (... IDENT
'variable)
((and (eql k 1)
(memq k-head '( let let* letrec dlet )))
;; (let (... (... IDENT
'variable)
((eql i 0)
;; (IDENT ...
'function)
((functionp i-head)
;; (FUNC ... IDENT
'variable)
((and (eql i 1)
(cond
((memq i-head '( function
defun defmacro defsubst
define-inline declare-function
defadvice
cl-defmethod cl-defgeneric))
'function)
((memq i-head '( defvar defvar-local defconst defcustom))
'variable)
((eq i-head 'defface)
'face))))
((memq i-head '( if while and or when unless progn prog1
let let* lambda defun defsubst defvar defconst))
;; arg to some common non-function forms
'variable)
;; Anything else: probably a variable, but since i-head may be
;; a macro we cannot be sure.
(t 'maybe-variable))))))))