1. xemacs
  2. xemacs-devel

Source

xemacs-devel / find-func.el

Diff from to

File find-func.el

  • Ignore whitespace
 ;;; find-func.el --- find the definition of the Emacs Lisp function near point
 
-;; Copyright (C) 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1999, 2001, 2004  Free Software Foundation, Inc.
 
 ;; Author: Jens Petersen <petersen@kurims.kyoto-u.ac.jp>
 ;; Maintainer: petersen@kurims.kyoto-u.ac.jp
 ;; Keywords: emacs-lisp, functions, variables
 ;; Created: 97/07/25
-;; URL: <http://www.kurims.kyoto-u.ac.jp/~petersen/xemacs/>
-;; Version: 0.22
-
-;; $Id$
 
 ;; This file is part of XEmacs.
 
-;; XEmacs is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by
+;; XEmacs 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)
 ;; any later version.
 
-;; XEmacs is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
+;; XEmacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the 
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
+;;; Synched up with: FSF 21.3.
+
 ;;; Commentary:
 ;;
 ;; The funniest thing about this is that I can't imagine why a package
 ;; so obviously useful as this hasn't been written before!!
-;;
-;; Put this file in your `load-path', byte-compile it and add the
-;; following code in your init file:
-;;
-;; ;;; find-func
-;; (load "find-func")
-;;
-;; and away you go!  The default given keybindings as the ones
-;; protected by autoload cookies at the bottom of this file.  It does
-;; pretty much what you would expect, putting the cursor at the
-;; definition of the function or variable at point.
+;; 
+;; The default keybindings are the ones protected by autoload cookies at
+;; the bottom of this file.  It does pretty much what you would expect,
+;; putting the cursor at the definition of the function or variable at
+;; point.
 ;;
 ;; In XEmacs the source filename of every dumped or loaded Lisp symbol
 ;; definition is now recorded in `load-history'.  So in XEmacs all
-;; non-primitive functions and variables can be found in principle.
-;; (I say "in principle" since the system is not perfect.  For example
-;; although it is unusual it can happen that say a variable and
-;; function of the same name are defined defined in different files,
-;; which may lead to incorrect results.)  Unfortunately in Emacs, only
-;; symbols loaded from startup can be found.  It would be nice if the
-;; location of primitive functions in the C code was also recorded!
+;; non-primitive functions and variables can be found in principle.  (I
+;; say "in principle" since the system is not perfect.  For example
+;; although it is unusual it can happen that say a variable and function
+;; of the same name are defined in different files, which may lead to
+;; incorrect results.)  Unfortunately in Emacs, only symbols loaded from
+;; startup can be found.  It would be nice if the location of primitive
+;; functions in the C code was also recorded!
 
 ;; The code started out from `describe-function', `describe-key'
 ;; ("help.el") and `fff-find-loaded-emacs-lisp-function' (Noah Friedman's
 ;;   :prefix "find-function"
   :group 'lisp)
 
+(defconst find-function-space-re "\\(?:\\s-\\|\n\\|;.*\n\\)+")
+
 (defcustom find-function-regexp
-  "^\\s-*(\\(def[^cgv\W]\\w+\\*?\\|define-function\\|define-obsolete-function-alias\\|define-compatible-function-alias\\|define-derived-mode\\)\\s-+%s\\(\\s-\\|$\\)"
-"The regexp used by `find-function' to search for a function
-definition.  Note it must contain a `%s' at the place where `format'
+  ;; Match things like (defun foo ...), (defmacro foo ...),
+  ;; (define-skeleton foo ...), (define-generic-mode 'foo ...),
+  ;;  (define-derived-mode foo ...), (define-minor-mode foo)
+  (concat
+   "^\\s-*(\\(def\\(ine-skeleton\\|ine-generic-mode\\|ine-derived-mode\\|\
+ine-function\\|ine-obsolete-function-alias\\|ine-compatible-function-alias\\|\
+\[^cgv\W]\\w+\\*?\\)\\|define-minor-mode\
+\\|easy-mmode-define-global-mode\\)" find-function-space-re
+   "\\('\\|\(quote \\)?%s\\(\\s-\\|$\\|\(\\|\)\\)")
+  "The regexp used by `find-function' to search for a function definition.
+Note it must contain a `%s' at the place where `format'
 should insert the function name.  The default value avoids `defconst',
 `defgroup', `defvar'.
 
   :group 'find-function)
 
 (defcustom find-variable-regexp
-  "^\\s-*(\\(def[^uma\W]\\w+\\*?\\|define-obsolete-variable-alias\\|define-compatible-variable-alias\\)\\s-+%s\\(\\s-\\|$\\)"
+  (concat "^\\s-*(\\(def[^umag\W]\\(\\w\\|\\s_\\)+\\*?\\|define-obsolete-variable-alias\\|define-compatible-variable-alias\\)"
+	  find-function-space-re "%s\\(\\s-\\|$\\)")
   "The regexp used by `find-variable' to search for a variable definition.
 It should match right up to the variable name.  The default value
-avoids `defun', `defmacro', `defalias', `defadvice'.
+avoids `defun', `defmacro', `defalias', `defadvice', `defgroup'.
 
 Please send improvements and fixes to the maintainer."
   :type 'regexp
   :group 'find-function)
 
 (defcustom find-function-source-path nil
-  "The default list of directories where find-function searches.
+  "The default list of directories where `find-function' searches.
 
-If this variable is `nil' then find-function searches `load-path' by
+If this variable is nil then `find-function' searches `load-path' by
 default."
   :type '(repeat directory)
   :group 'find-function)
 A value of nil implies center the beginning of the definition.
 See the function `center-to-window-line' for more information, and
 `find-function' and `find-variable'."
+  :type '(choice (const :tag "Center" nil)
+		 integer)
   :group 'find-function)
 
 (defcustom find-function-after-hook nil
 
 ;;; Functions:
 
+;; XEmacs omission: Emacs has find-library and supporting friends here.
+;; We have the equivalent in lib-complete.el in core.
+
+;;;###autoload
 (defun find-function-search-for-symbol (symbol variable-p library)
   "Search for SYMBOL in LIBRARY.
 If VARIABLE-P is nil, `find-function-regexp' is used, otherwise
 `find-variable-regexp' is used."
   (if (null library)
       (error "Don't know where `%s' is defined" symbol))
+  ;; We deviate significantly from Emacs here, due to our distinct
+  ;; find-library implementations.
   (if (string-match "\\.el\\(c\\)\\'" library)
       (setq library (substring library 0 (match-beginning 1))))
   (let* ((path find-function-source-path)
 				  find-variable-regexp
 				find-function-regexp)
 			      (regexp-quote (symbol-name symbol))))
-	      (syn-table (syntax-table)))
-	  (unwind-protect
-	      (progn
-		(set-syntax-table emacs-lisp-mode-syntax-table)
-		(goto-char (point-min))
-		(if (re-search-forward regexp nil t)
-		    (progn
-		      (beginning-of-line)
-		      (cons (current-buffer) (point)))
-		  (error "Cannot find definition of `%s' in library \"%s\"" 
-			 symbol library)))
-	    (set-syntax-table syn-table)))))))
+	      (case-fold-search))
+	  (with-syntax-table emacs-lisp-mode-syntax-table
+	    (goto-char (point-min))
+	    (if (or (re-search-forward regexp nil t)
+		    (re-search-forward
+		     (concat "^([^ ]+" find-function-space-re "['(]"
+			     (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))))))))
 
+;;;###autoload
 (defun find-function-noselect (function)
-  "Returns a pair (BUFFER . POINT) pointing to the definition of FUNCTION.
+  "Return a pair (BUFFER . POINT) pointing to the definition of FUNCTION.
 
 Finds the Emacs Lisp library containing the definition of FUNCTION
 in a buffer and the point of the definition.  The buffer is
 not selected.
 
 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"))
 				  function (symbol-name def)))))
       (setq function (symbol-function function)
 	    def (symbol-function function)))
+    ;; XEmacs difference: check for primitive functions a bit differently
     (and (subrp (symbol-function function))
          (if aliases
              (error "%s which is a primitive function" aliases)
 	   (cond ((eq (car-safe def) 'autoload)
 		  (nth 1 def))
 		 ((symbol-file function))
+		 ;; XEmacs addition: function annotations
 		 ((fboundp 'compiled-function-annotation)
 		  (cond ((compiled-function-p def)
 			 (file-name-sans-extension
 			       (compiled-function-annotation (cdr def))))))))))
       (find-function-search-for-symbol function nil library))))
 
+;; XEmacs change: these functions are defined in help.el
+;(defalias 'function-at-point 'function-called-at-point)
+
 (defun find-function-read (&optional variable-p)
   "Read and return an interned symbol, defaulting to the one near point.
 
 If the optional VARIABLE-P is nil, then a function is gotten
-defaulting to the value of the function `function-at-point', otherwise 
+defaulting to the value of the function `function-at-point', otherwise
 a variable is asked for, with the default coming from
 `variable-at-point'."
   (let ((symb (funcall (if variable-p
 			 'function-at-point)))
 	(enable-recursive-minibuffers t)
 	val)
+    (if (equal symb 0)
+	(setq symb nil))
     (setq val (if variable-p
 		  (completing-read
 		   (concat "Find variable"
 
 Point is saved in the buffer if it is one of the current buffers."
   (let* ((orig-point (point))
-	 (orig-buf (window-buffer))
 	 (orig-buffers (buffer-list))
 	 (buffer-point (save-excursion
 			 (funcall (if variable-p
       (funcall switch-fn new-buf)
       (goto-char new-point)
       (recenter find-function-recenter-line)
-      (run-hooks find-function-after-hook))))
+      (run-hooks 'find-function-after-hook))))
 
 ;;;###autoload
 (defun find-function (function)
 it is one of the current buffers.
 
 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))
 
 ;;;###autoload
 (defun find-function-other-window (function)
-  "Find the definition of the function near point in the other window.
+  "Find the definition of the function near point in another window.
 
 See `find-function' for more details."
   (interactive (find-function-read))
 
 ;;;###autoload
 (defun find-function-other-frame (function)
-  "Find the definition of the function near point in the another frame.
+  "Find the definition of the function near point in another frame.
 
 See `find-function' for more details."
   (interactive (find-function-read))
   (find-function-do-it function nil 'switch-to-buffer-other-frame))
 
-(defun find-variable-noselect (variable)
-  "Returns a pair `(buffer . point)' pointing to the definition of SYMBOL.
+;;;###autoload
+(defun find-variable-noselect (variable &optional file)
+  "Return a pair `(BUFFER . POINT)' pointing to the definition of SYMBOL.
 
 Finds the Emacs Lisp library containing the definition of SYMBOL
 in a buffer and the point of the definition.  The buffer is
 not selected.
 
-The library where VARIABLE is defined is searched for in
-`find-function-source-path', if non `nil', otherwise in `load-path'."
+The library where VARIABLE is defined is searched for in FILE or
+`find-function-source-path', if non nil, otherwise in `load-path'."
   (if (not variable)
       (error "You didn't specify a variable"))
   (and (built-in-variable-type variable)
        (error "%s is a primitive variable" variable))
-  (let ((library (symbol-file variable)))
+  (let ((library (or file (symbol-file variable))))
     (find-function-search-for-symbol variable 'variable library)))
 
 ;;;###autoload
 it is one of the current buffers.
 
 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 'variable))
   (find-function-do-it variable t 'switch-to-buffer))
 
 ;;;###autoload
 (defun find-variable-other-window (variable)
-  "Find the definition of the variable near point in the other window.
+  "Find the definition of the variable near point in another window.
 
 See `find-variable' for more details."
   (interactive (find-function-read 'variable))
 
 ;;;###autoload
 (defun find-variable-other-frame (variable)
-  "Find the definition of the variable near point in the another frame.
+  "Find the definition of the variable near point in another frame.
 
 See `find-variable' for more details."
   (interactive (find-function-read 'variable))
   "Find the function that KEY invokes.  KEY is a string.
 Point is saved if FUNCTION is in the current buffer."
   (interactive "kFind function on key: ")
+  ;; XEmacs change: Avoid the complex menu code with key-or-menu-binding
   (let ((defn (key-or-menu-binding key))
 	(key-desc (key-description key)))
     (if (or (null defn) (integerp defn))
   "Find directly the function at point in the other window."
   (interactive)
   (let ((symb (variable-at-point)))
-    (when symb
+    (when (and symb (not (equal symb 0)))
       (find-variable-other-window symb))))
 
+;; XEmacs change: autoload instead of defining find-function-setup-keys
+;; FIXME: We do not have a default keybinding for find-function
 ;; (define-key ctl-x-map "F" 'find-function) ; conflicts with `facemenu-keymap'
 ;;;###autoload(define-key ctl-x-4-map "F" 'find-function-other-window)
 ;;;###autoload(define-key ctl-x-5-map "F" 'find-function-other-frame)
 
 (provide 'find-func)
 
+;;; arch-tag: 43ecd81c-74dc-4d9a-8f63-a61e55670d64
 ;;; find-func.el ends here