Function: find-function-search-for-symbol
find-function-search-for-symbol is an autoloaded and byte-compiled
function defined in find-func.el.gz.
Signature
(find-function-search-for-symbol SYMBOL TYPE LIBRARY)
Documentation
Search for SYMBOL's definition of type TYPE in LIBRARY.
Visit the library in a buffer, and return a cons cell (BUFFER . POSITION), or just (BUFFER . nil) if the definition can't be found in the file.
If TYPE is nil, look for a function definition,
otherwise, TYPE specifies the kind of definition.
TYPE is looked up in SYMBOL's property find-function-type-alist
(which can be maintained with find-function-update-type-alist)
or the variable find-function-regexp-alist.
The search is done in the source for library LIBRARY.
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/find-func.el.gz
;;;###autoload
(defun find-function-search-for-symbol (symbol type library)
"Search for SYMBOL's definition of type TYPE in LIBRARY.
Visit the library in a buffer, and return a cons cell (BUFFER . POSITION),
or just (BUFFER . nil) if the definition can't be found in the file.
If TYPE is nil, look for a function definition,
otherwise, TYPE specifies the kind of definition.
TYPE is looked up in SYMBOL's property `find-function-type-alist'
(which can be maintained with `find-function-update-type-alist')
or the variable `find-function-regexp-alist'.
The search is done in the source for library LIBRARY."
(if (null library)
(error "Don't know where `%s' is defined" symbol))
;; Some functions are defined as part of the construct
;; that defines something else.
(while (and (symbolp symbol) (get symbol 'definition-name))
(setq symbol (get symbol 'definition-name)))
(if (string-match "\\`src/\\(.*\\.\\(c\\|m\\)\\)\\'" library)
(find-function-C-source symbol (match-string 1 library) type)
(when (string-match "\\.el\\(c\\)\\'" library)
(setq library (substring library 0 (match-beginning 1))))
;; Strip extension from .emacs.el to make sure symbol is searched in
;; .emacs too.
(when (string-match "\\.emacs\\(.el\\)\\'" library)
(setq library (substring library 0 (match-beginning 1))))
(let* ((filename (find-library-name library))
(regexp-symbol
(or (and (symbolp symbol)
(alist-get type (get symbol 'find-function-type-alist)))
(alist-get type find-function-regexp-alist)))
(form-matcher-factory
(and (functionp (cdr-safe regexp-symbol))
(cdr regexp-symbol)))
(regexp-symbol (if form-matcher-factory
(car regexp-symbol)
regexp-symbol)))
(with-current-buffer (find-file-noselect filename)
(let ((case-fold-search))
(save-restriction
(widen)
(with-syntax-table emacs-lisp-mode-syntax-table
(goto-char (point-min))
(if (if (functionp regexp-symbol)
(funcall regexp-symbol symbol)
(let ((regexp-of-symbol
(find-func--regexp-of-symbol-name symbol)))
(or (re-search-forward
(format (symbol-value regexp-symbol)
regexp-of-symbol)
nil t)
;; `regexp' matches definitions using known forms
;; like `defun', or `defvar'.
;; But some functions/variables are defined using
;; special macros (or functions), so if `regexp'
;; can't find the definition, we look for
;; something of the form "(SOMETHING <symbol> ...)".
;; This doesn't pay attention to TYPE (or even
;; distinguish definitions from uses),
;; but is a good pragmatic fallback.
(re-search-forward
(concat "^([^ ]+" find-function-space-re "['(]?"
regexp-of-symbol
"\\_>")
nil t))))
(progn
(beginning-of-line)
(cons (current-buffer) (point)))
;; If the regexp search didn't find the location of
;; the symbol (for example, because it is generated by
;; a macro), try a slightly more expensive search that
;; expands macros until it finds the symbol. Since
;; macro-expansion involves arbitrary code execution,
;; only attempt it in trusted buffers.
(cons (current-buffer)
(when (trusted-content-p)
(find-function--search-by-expanding-macros
(current-buffer) symbol type
form-matcher-factory)))))))))))