]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/find-func.el
Don't require loadhist.
[gnu-emacs] / lisp / emacs-lisp / find-func.el
index 4c218263a625b561f82fa1dce8329a8a88d51896..20b91b10547a0694093390e5cece95e467efc237 100644 (file)
@@ -1,7 +1,7 @@
 ;;; find-func.el --- find the definition of the Emacs Lisp function near point
 
 ;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004,
 ;;; find-func.el --- find the definition of the Emacs Lisp function near point
 
 ;; Copyright (C) 1997, 1999, 2001, 2002, 2003, 2004,
-;;   2005 Free Software Foundation, Inc.
+;;   2005, 2006, 2007 Free Software Foundation, Inc.
 
 ;; Author: Jens Petersen <petersen@kurims.kyoto-u.ac.jp>
 ;; Maintainer: petersen@kurims.kyoto-u.ac.jp
 
 ;; Author: Jens Petersen <petersen@kurims.kyoto-u.ac.jp>
 ;; Maintainer: petersen@kurims.kyoto-u.ac.jp
@@ -12,7 +12,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -46,8 +46,6 @@
 
 ;;; Code:
 
 
 ;;; Code:
 
-(require 'loadhist)
-
 ;;; User variables:
 
 (defgroup find-function nil
 ;;; User variables:
 
 (defgroup find-function nil
@@ -64,7 +62,7 @@
   (concat
    "^\\s-*(\\(def\\(ine-skeleton\\|ine-generic-mode\\|ine-derived-mode\\|\
 ine\\(?:-global\\)?-minor-mode\\|ine-compilation-mode\\|un-cvs-mode\\|\
   (concat
    "^\\s-*(\\(def\\(ine-skeleton\\|ine-generic-mode\\|ine-derived-mode\\|\
 ine\\(?:-global\\)?-minor-mode\\|ine-compilation-mode\\|un-cvs-mode\\|\
-foo\\|[^cfgv]\\w+\\*?\\)\\|easy-mmode-define-[a-z-]+\\|easy-menu-define\\|\
+foo\\|[^icfgv]\\(\\w\\|\\s_\\)+\\*?\\)\\|easy-mmode-define-[a-z-]+\\|easy-menu-define\\|\
 menu-bar-make-toggle\\)"
    find-function-space-re
    "\\('\\|\(quote \\)?%s\\(\\s-\\|$\\|\(\\|\)\\)")
 menu-bar-make-toggle\\)"
    find-function-space-re
    "\\('\\|\(quote \\)?%s\\(\\s-\\|$\\|\(\\|\)\\)")
@@ -142,18 +140,18 @@ See the functions `find-function' and `find-variable'."
 
 (defun find-library-suffixes ()
   (let ((suffixes nil))
 
 (defun find-library-suffixes ()
   (let ((suffixes nil))
-    (dolist (suffix load-suffixes (nreverse suffixes))
+    (dolist (suffix (get-load-suffixes) (nreverse suffixes))
       (unless (string-match "elc" suffix) (push suffix suffixes)))))
 
 (defun find-library-name (library)
   "Return the absolute file name of the Lisp source of LIBRARY."
       (unless (string-match "elc" suffix) (push suffix suffixes)))))
 
 (defun find-library-name (library)
   "Return the absolute file name of the Lisp source of LIBRARY."
-  ;; Strip off the extension to take advantage of library suffixes in
-  ;; the call to `locate-file'.
-  (if (string-match "\\.el\\(c\\(\\..*\\)?\\)?\\'" library)
+  ;; If the library is byte-compiled, try to find a source library by
+  ;; the same name.
+  (if (string-match "\\.el\\(c\\(\\..*\\)?\\)\\'" library)
       (setq library (replace-match "" t t library)))
   (or (locate-file library
                   (or find-function-source-path load-path)
       (setq library (replace-match "" t t library)))
   (or (locate-file library
                   (or find-function-source-path load-path)
-                  (append (find-library-suffixes) '("")))
+                  (append (find-library-suffixes) load-file-rep-suffixes))
       (error "Can't find library %s" library)))
 
 (defvar find-function-C-source-directory
       (error "Can't find library %s" library)))
 
 (defvar find-function-C-source-directory
@@ -205,6 +203,9 @@ TYPE should be nil to find a function, or `defvar' to find a variable."
 ;;;###autoload
 (defun find-function-search-for-symbol (symbol type library)
   "Search for SYMBOL's definition of type TYPE in LIBRARY.
 ;;;###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,
 and it is interpreted via `find-function-regexp-alist'.
 If TYPE is nil, look for a function definition.
 Otherwise, TYPE specifies the kind of definition,
 and it is interpreted via `find-function-regexp-alist'.
@@ -223,21 +224,33 @@ The search is done in the source for library LIBRARY."
           (regexp-symbol (cdr (assq type find-function-regexp-alist))))
       (with-current-buffer (find-file-noselect filename)
        (let ((regexp (format (symbol-value regexp-symbol)
           (regexp-symbol (cdr (assq type find-function-regexp-alist))))
       (with-current-buffer (find-file-noselect filename)
        (let ((regexp (format (symbol-value regexp-symbol)
-                             (regexp-quote (symbol-name symbol))))
+                             ;; Entry for ` (backquote) macro in loaddefs.el,
+                             ;; (defalias (quote \`)..., has a \ but
+                             ;; (symbol-name symbol) doesn't.  Add an
+                             ;; optional \ to catch this.
+                             (concat "\\\\?"
+                                     (regexp-quote (symbol-name symbol)))))
              (case-fold-search))
          (with-syntax-table emacs-lisp-mode-syntax-table
            (goto-char (point-min))
            (if (or (re-search-forward regexp nil t)
              (case-fold-search))
          (with-syntax-table emacs-lisp-mode-syntax-table
            (goto-char (point-min))
            (if (or (re-search-forward regexp 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 fails to distinguish function definitions from
+                    ;; variable declarations (or even uses thereof), but is
+                    ;; a good pragmatic fallback.
                    (re-search-forward
                    (re-search-forward
-                    (concat "^([^ ]+" find-function-space-re "['(]"
+                    (concat "^([^ ]+" find-function-space-re "['(]?"
                             (regexp-quote (symbol-name symbol))
                             "\\_>")
                     nil t))
                (progn
                  (beginning-of-line)
                  (cons (current-buffer) (point)))
                             (regexp-quote (symbol-name symbol))
                             "\\_>")
                     nil t))
                (progn
                  (beginning-of-line)
                  (cons (current-buffer) (point)))
-             (error "Cannot find definition of `%s' in library `%s'"
-                    symbol library))))))))
+             (cons (current-buffer) nil))))))))
 
 ;;;###autoload
 (defun find-function-noselect (function)
 
 ;;;###autoload
 (defun find-function-noselect (function)
@@ -245,10 +258,11 @@ The search is done in the source for library LIBRARY."
 
 Finds the source file containing the definition of FUNCTION
 in a buffer and the point of the definition.  The buffer is
 
 Finds the source file containing the definition of FUNCTION
 in a buffer and the point of the definition.  The buffer is
-not selected.
+not selected.  If the function definition can't be found in
+the buffer, returns (BUFFER).
 
 If the file where FUNCTION is defined is not known, then it is
 
 If the file where FUNCTION is defined is not known, then it is
-searched for in `find-function-source-path' if non nil, otherwise
+searched for in `find-function-source-path' if non-nil, otherwise
 in `load-path'."
   (if (not function)
       (error "You didn't specify a function"))
 in `load-path'."
   (if (not function)
       (error "You didn't specify a function"))
@@ -327,7 +341,7 @@ Set mark before moving, if the buffer already existed."
       (when (memq new-buf orig-buffers)
        (push-mark orig-point))
       (funcall switch-fn new-buf)
       (when (memq new-buf orig-buffers)
        (push-mark orig-point))
       (funcall switch-fn new-buf)
-      (goto-char new-point)
+      (when new-point (goto-char new-point))
       (recenter find-function-recenter-line)
       (run-hooks 'find-function-after-hook))))
 
       (recenter find-function-recenter-line)
       (run-hooks 'find-function-after-hook))))
 
@@ -341,7 +355,7 @@ places point before the definition.
 Set mark before moving, if the buffer already existed.
 
 The library where FUNCTION is defined is searched for in
 Set mark before moving, if the buffer already existed.
 
 The library where FUNCTION is defined is searched for in
-`find-function-source-path', if non nil, otherwise in `load-path'.
+`find-function-source-path', if non-nil, otherwise in `load-path'.
 See also `find-function-recenter-line' and `find-function-after-hook'."
   (interactive (find-function-read))
   (find-function-do-it function nil 'switch-to-buffer))
 See also `find-function-recenter-line' and `find-function-after-hook'."
   (interactive (find-function-read))
   (find-function-do-it function nil 'switch-to-buffer))
@@ -368,9 +382,10 @@ See `find-function' for more details."
 
 Finds the library containing the definition of VARIABLE in a buffer and
 the point of the definition.  The buffer is not selected.
 
 Finds the library containing the definition of VARIABLE in a buffer and
 the point of the definition.  The buffer is not selected.
+If the variable's definition can't be found in the buffer, return (BUFFER).
 
 The library where VARIABLE is defined is searched for in FILE or
 
 The library where VARIABLE is defined is searched for in FILE or
-`find-function-source-path', if non nil, otherwise in `load-path'."
+`find-function-source-path', if non-nil, otherwise in `load-path'."
   (if (not variable)
       (error "You didn't specify a variable")
     (let ((library (or file
   (if (not variable)
       (error "You didn't specify a variable")
     (let ((library (or file
@@ -380,7 +395,7 @@ The library where VARIABLE is defined is searched for in FILE or
 
 ;;;###autoload
 (defun find-variable (variable)
 
 ;;;###autoload
 (defun find-variable (variable)
-  "Find the definition of the VARIABLE near point.
+  "Find the definition of the VARIABLE at or before point.
 
 Finds the library containing the definition of the variable
 near point (selected by `variable-at-point') in a buffer and
 
 Finds the library containing the definition of the variable
 near point (selected by `variable-at-point') in a buffer and
@@ -389,7 +404,7 @@ places point before the definition.
 Set mark before moving, if the buffer already existed.
 
 The library where VARIABLE is defined is searched for in
 Set mark before moving, if the buffer already existed.
 
 The library where VARIABLE is defined is searched for in
-`find-function-source-path', if non nil, otherwise in `load-path'.
+`find-function-source-path', if non-nil, otherwise in `load-path'.
 See also `find-function-recenter-line' and `find-function-after-hook'."
   (interactive (find-function-read 'defvar))
   (find-function-do-it variable 'defvar 'switch-to-buffer))
 See also `find-function-recenter-line' and `find-function-after-hook'."
   (interactive (find-function-read 'defvar))
   (find-function-do-it variable 'defvar 'switch-to-buffer))
@@ -413,12 +428,13 @@ See `find-variable' for more details."
 ;;;###autoload
 (defun find-definition-noselect (symbol type &optional file)
   "Return a pair `(BUFFER . POINT)' pointing to the definition of SYMBOL.
 ;;;###autoload
 (defun find-definition-noselect (symbol type &optional file)
   "Return a pair `(BUFFER . POINT)' pointing to the definition of SYMBOL.
+If the definition can't be found in the buffer, return (BUFFER).
 TYPE says what type of definition: nil for a function, `defvar' for a
 TYPE says what type of definition: nil for a function, `defvar' for a
-variabke, `defface' for a face.  This function does not switch to the
+variable, `defface' for a face.  This function does not switch to the
 buffer nor display it.
 
 The library where SYMBOL is defined is searched for in FILE or
 buffer nor display it.
 
 The library where SYMBOL is defined is searched for in FILE or
-`find-function-source-path', if non nil, otherwise in `load-path'."
+`find-function-source-path', if non-nil, otherwise in `load-path'."
   (cond
    ((not symbol)
     (error "You didn't specify a symbol"))
   (cond
    ((not symbol)
     (error "You didn't specify a symbol"))
@@ -443,7 +459,7 @@ places point before the definition.
 Set mark before moving, if the buffer already existed.
 
 The library where FACE is defined is searched for in
 Set mark before moving, if the buffer already existed.
 
 The library where FACE is defined is searched for in
-`find-function-source-path', if non nil, otherwise in `load-path'.
+`find-function-source-path', if non-nil, otherwise in `load-path'.
 See also `find-function-recenter-line' and `find-function-after-hook'."
   (interactive (find-function-read 'defface))
   (find-function-do-it face 'defface 'switch-to-buffer))
 See also `find-function-recenter-line' and `find-function-after-hook'."
   (interactive (find-function-read 'defface))
   (find-function-do-it face 'defface 'switch-to-buffer))