aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Leake2015-08-13 12:54:39 -0500
committerStephen Leake2015-08-13 13:16:47 -0500
commit0382fd42c6979bbedc9230b789503258a5e963eb (patch)
tree989b157edeb659f5e0b2b3e8b884ec143dcbe3fd
parent9c13a81a9e1aa74901cd958d7adb3ca71966dbef (diff)
downloademacs-0382fd42c6979bbedc9230b789503258a5e963eb.tar.gz
emacs-0382fd42c6979bbedc9230b789503258a5e963eb.zip
xref-find-definitions: Exclude more generic function items.
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method): Add doc string. (cl--generic-find-defgeneric-regexp): New. (find-function-regexp-alist): Add it. * lisp/emacs-lisp/find-func.el (find-feature-regexp): Move here from elisp-mode.el, change to search for ";;; Code:" (find-alias-regexp): Move here from elisp-mode.el, cleaned up. (find-function-regexp-alist): Add them. * lisp/progmodes/elisp-mode.el: (elisp--xref-format, elisp--xref-format-extra): Change back to defvar due to bug#21237. (elisp--xref-find-definitions): Exclude co-located default methods for generic functions. Also exclude implicitly declared defgeneric. (elisp--xref-find-definitions): Handle C source properly. Exclude minor mode variables defined by 'define-minor-mode'. * test/automated/elisp-mode-tests.el: Declare generic functions, add tests for them. (xref-elisp-test-run): Fix bug. (emacs-test-dir): Improve initial value. (find-defs-defun-defvar-el): Don't expect defvar. (find-defs-feature-el): Match change to find-feature-regexp.
-rw-r--r--lisp/emacs-lisp/cl-generic.el8
-rw-r--r--lisp/emacs-lisp/find-func.el26
-rw-r--r--lisp/progmodes/elisp-mode.el115
-rw-r--r--test/automated/elisp-mode-tests.el170
4 files changed, 264 insertions, 55 deletions
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 63cd9108410..a138697a18b 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -791,6 +791,8 @@ Can only be used from within the lexical body of a primary or around method."
791;;; Add support for describe-function 791;;; Add support for describe-function
792 792
793(defun cl--generic-search-method (met-name) 793(defun cl--generic-search-method (met-name)
794 "For `find-function-regexp-alist'. Searches for a cl-defmethod.
795MET-NAME is a cons (SYMBOL . SPECIALIZERS)."
794 (let ((base-re (concat "(\\(?:cl-\\)?defmethod[ \t]+" 796 (let ((base-re (concat "(\\(?:cl-\\)?defmethod[ \t]+"
795 (regexp-quote (format "%s" (car met-name))) 797 (regexp-quote (format "%s" (car met-name)))
796 "\\_>"))) 798 "\\_>")))
@@ -806,11 +808,15 @@ Can only be used from within the lexical body of a primary or around method."
806 nil t) 808 nil t)
807 (re-search-forward base-re nil t)))) 809 (re-search-forward base-re nil t))))
808 810
811;; WORKAROUND: This can't be a defconst due to bug#21237.
812(defvar cl--generic-find-defgeneric-regexp "(\\(?:cl-\\)?defgeneric[ \t]+%s\\>")
809 813
810(with-eval-after-load 'find-func 814(with-eval-after-load 'find-func
811 (defvar find-function-regexp-alist) 815 (defvar find-function-regexp-alist)
812 (add-to-list 'find-function-regexp-alist 816 (add-to-list 'find-function-regexp-alist
813 `(cl-defmethod . ,#'cl--generic-search-method))) 817 `(cl-defmethod . ,#'cl--generic-search-method))
818 (add-to-list 'find-function-regexp-alist
819 `(cl-defgeneric . cl--generic-find-defgeneric-regexp)))
814 820
815(defun cl--generic-method-info (method) 821(defun cl--generic-method-info (method)
816 (let* ((specializers (cl--generic-method-specializers method)) 822 (let* ((specializers (cl--generic-method-specializers method))
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index cd23cd77f4a..4dc0596de66 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -100,10 +100,34 @@ Please send improvements and fixes to the maintainer."
100 :group 'find-function 100 :group 'find-function
101 :version "22.1") 101 :version "22.1")
102 102
103(defcustom find-feature-regexp
104 (concat ";;; Code:")
105 "The regexp used by `xref-find-definitions' when searching for a feature definition.
106Note it must contain a `%s' at the place where `format'
107should insert the feature name."
108 ;; We search for ";;; Code" rather than (feature '%s) because the
109 ;; former is near the start of the code, and the latter is very
110 ;; uninteresting. If the regexp is not found, just goes to
111 ;; (point-min), which is acceptable in this case.
112 :type 'regexp
113 :group 'xref
114 :version "25.0")
115
116(defcustom find-alias-regexp
117 "(defalias +'%s"
118 "The regexp used by `xref-find-definitions' to search for an alias definition.
119Note it must contain a `%s' at the place where `format'
120should insert the feature name."
121 :type 'regexp
122 :group 'xref
123 :version "25.0")
124
103(defvar find-function-regexp-alist 125(defvar find-function-regexp-alist
104 '((nil . find-function-regexp) 126 '((nil . find-function-regexp)
105 (defvar . find-variable-regexp) 127 (defvar . find-variable-regexp)
106 (defface . find-face-regexp)) 128 (defface . find-face-regexp)
129 (feature . find-feature-regexp)
130 (defalias . find-alias-regexp))
107 "Alist mapping definition types into regexp variables. 131 "Alist mapping definition types into regexp variables.
108Each regexp variable's value should actually be a format string 132Each regexp variable's value should actually be a format string
109to be used to substitute the desired symbol name into the regexp. 133to be used to substitute the desired symbol name into the regexp.
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 7ac5a5cb778..81314574672 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -604,40 +604,23 @@ It can be quoted, or be inside a quoted form."
604 (`apropos 604 (`apropos
605 (elisp--xref-find-apropos id)))) 605 (elisp--xref-find-apropos id))))
606 606
607(defconst elisp--xref-format 607;; WORKAROUND: This is nominally a constant, but the text properities
608;; are not preserved thru dump if use defconst. See bug#21237
609(defvar elisp--xref-format
608 (let ((str "(%s %s)")) 610 (let ((str "(%s %s)"))
609 (put-text-property 1 3 'face 'font-lock-keyword-face str) 611 (put-text-property 1 3 'face 'font-lock-keyword-face str)
610 (put-text-property 4 6 'face 'font-lock-function-name-face str) 612 (put-text-property 4 6 'face 'font-lock-function-name-face str)
611 str)) 613 str))
612 614
613(defconst elisp--xref-format-extra 615;; WORKAROUND: This is nominally a constant, but the text properities
616;; are not preserved thru dump if use defconst. See bug#21237
617(defvar elisp--xref-format-extra
614 (let ((str "(%s %s %s)")) 618 (let ((str "(%s %s %s)"))
615 (put-text-property 1 3 'face 'font-lock-keyword-face str) 619 (put-text-property 1 3 'face 'font-lock-keyword-face str)
616 (put-text-property 4 6 'face 'font-lock-function-name-face str) 620 (put-text-property 4 6 'face 'font-lock-function-name-face str)
617 str)) 621 str))
618 622
619(defcustom find-feature-regexp 623(defvar find-feature-regexp)
620 (concat "(provide +'%s)")
621 "The regexp used by `xref-find-definitions' to search for a feature definition.
622Note it must contain a `%s' at the place where `format'
623should insert the feature name."
624 :type 'regexp
625 :group 'xref
626 :version "25.0")
627
628(defcustom find-alias-regexp
629 "(\\(defalias +'\\|def\\(const\\|face\\) +\\)%s"
630 "The regexp used by `xref-find-definitions' to search for an alias definition.
631Note it must contain a `%s' at the place where `format'
632should insert the feature name."
633 :type 'regexp
634 :group 'xref
635 :version "25.0")
636
637(with-eval-after-load 'find-func
638 (defvar find-function-regexp-alist)
639 (add-to-list 'find-function-regexp-alist (cons 'feature 'find-feature-regexp))
640 (add-to-list 'find-function-regexp-alist (cons 'defalias 'find-alias-regexp)))
641 624
642(defun elisp--xref-make-xref (type symbol file &optional summary) 625(defun elisp--xref-make-xref (type symbol file &optional summary)
643 "Return an xref for TYPE SYMBOL in FILE. 626 "Return an xref for TYPE SYMBOL in FILE.
@@ -683,9 +666,10 @@ otherwise build the summary from TYPE and SYMBOL."
683 (when file 666 (when file
684 (cond 667 (cond
685 ((eq file 'C-source) 668 ((eq file 'C-source)
686 ;; First call to find-lisp-object-file-name (for this 669 ;; First call to find-lisp-object-file-name for an object
687 ;; symbol?); C-source has not been cached yet. 670 ;; defined in C; the doc strings from the C source have
688 ;; Second call will return "src/*.c" in file; handled by 't' case below. 671 ;; not been loaded yet. Second call will return "src/*.c"
672 ;; in file; handled by 't' case below.
689 (push (elisp--xref-make-xref nil symbol (help-C-file-name (symbol-function symbol) 'subr)) xrefs)) 673 (push (elisp--xref-make-xref nil symbol (help-C-file-name (symbol-function symbol) 'subr)) xrefs))
690 674
691 ((and (setq doc (documentation symbol t)) 675 ((and (setq doc (documentation symbol t))
@@ -704,17 +688,42 @@ otherwise build the summary from TYPE and SYMBOL."
704 )) 688 ))
705 689
706 ((setq generic (cl--generic symbol)) 690 ((setq generic (cl--generic symbol))
691 ;; A generic function. If there is a default method, it
692 ;; will appear in the method table, with no
693 ;; specializers.
694 ;;
695 ;; If the default method is declared by the cl-defgeneric
696 ;; declaration, it will have the same location as teh
697 ;; cl-defgeneric, so we want to exclude it from the
698 ;; result. In this case, it will have a null doc
699 ;; string. User declarations of default methods may also
700 ;; have null doc strings, but we hope that is
701 ;; rare. Perhaps this hueristic will discourage that.
707 (dolist (method (cl--generic-method-table generic)) 702 (dolist (method (cl--generic-method-table generic))
708 (let* ((info (cl--generic-method-info method)) 703 (let* ((info (cl--generic-method-info method));; qual-string combined-args doconly
709 (met-name (cons symbol (cl--generic-method-specializers method))) 704 (specializers (cl--generic-method-specializers method))
710 (descr (format elisp--xref-format-extra 'cl-defmethod symbol (nth 1 info))) 705 (met-name (cons symbol specializers))
711 (file (find-lisp-object-file-name met-name 'cl-defmethod))) 706 (file (find-lisp-object-file-name met-name 'cl-defmethod)))
712 (when file 707 (when (and file
713 (push (elisp--xref-make-xref 'cl-defmethod met-name file descr) xrefs)) 708 (or specializers ;; default method has null specializers
709 (nth 2 info))) ;; assuming only co-located default has null doc string
710 (if specializers
711 (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol (nth 1 info))))
712 (push (elisp--xref-make-xref 'cl-defmethod met-name file summary) xrefs))
713
714 (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol "()")))
715 (push (elisp--xref-make-xref 'cl-defmethod met-name file summary) xrefs))))
714 )) 716 ))
715 717
716 (let ((descr (format elisp--xref-format 'cl-defgeneric symbol))) 718 (if (and (setq doc (documentation symbol t))
717 (push (elisp--xref-make-xref nil symbol file descr) xrefs)) 719 ;; This doc string is created somewhere in
720 ;; cl--generic-make-function for an implicit
721 ;; defgeneric.
722 (string-match "\n\n(fn ARG &rest ARGS)" doc))
723 ;; This symbol is an implicitly defined defgeneric, so
724 ;; don't return it.
725 nil
726 (push (elisp--xref-make-xref 'cl-defgeneric symbol file) xrefs))
718 ) 727 )
719 728
720 (t 729 (t
@@ -722,11 +731,43 @@ otherwise build the summary from TYPE and SYMBOL."
722 )))) 731 ))))
723 732
724 (when (boundp symbol) 733 (when (boundp symbol)
734 ;; A variable
725 (let ((file (find-lisp-object-file-name symbol 'defvar))) 735 (let ((file (find-lisp-object-file-name symbol 'defvar)))
726 (when file 736 (when file
727 (when (eq file 'C-source) 737 (cond
728 (setq file (help-C-file-name symbol 'var))) 738 ((eq file 'C-source)
729 (push (elisp--xref-make-xref 'defvar symbol file) xrefs)))) 739 ;; The doc strings from the C source have not been loaded
740 ;; yet; help-C-file-name does that. Second call will
741 ;; return "src/*.c" in file; handled below.
742 (push (elisp--xref-make-xref 'defvar symbol (help-C-file-name symbol 'var)) xrefs))
743
744 ((string= "src/" (substring file 0 4))
745 ;; The variable is defined in a C source file; don't check
746 ;; for define-minor-mode.
747 (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
748
749 ((memq symbol minor-mode-list)
750 ;; The symbol is a minor mode. These should be defined by
751 ;; "define-minor-mode", which means the variable and the
752 ;; function are declared in the same place. So we return only
753 ;; the function, arbitrarily.
754 ;;
755 ;; There is an exception, when the variable is defined in C
756 ;; code, as for abbrev-mode.
757 ;;
758 ;; IMPROVEME: If the user is searching for the identifier at
759 ;; point, we can determine whether it is a variable or
760 ;; function by looking at the source code near point.
761 ;;
762 ;; IMPROVEME: The user may actually be asking "do any
763 ;; variables by this name exist"; we need a way to specify
764 ;; that.
765 nil)
766
767 (t
768 (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
769
770 ))))
730 771
731 (when (featurep symbol) 772 (when (featurep symbol)
732 (let ((file (ignore-errors 773 (let ((file (ignore-errors
diff --git a/test/automated/elisp-mode-tests.el b/test/automated/elisp-mode-tests.el
index 9b4014a8a55..47212e919c6 100644
--- a/test/automated/elisp-mode-tests.el
+++ b/test/automated/elisp-mode-tests.el
@@ -177,8 +177,8 @@
177 177
178 178
179(defun xref-elisp-test-run (xrefs expecteds) 179(defun xref-elisp-test-run (xrefs expecteds)
180 (should (= (length xrefs) (length expecteds)))
180 (while xrefs 181 (while xrefs
181 (should (= (length xrefs) (length expecteds)))
182 (let ((xref (pop xrefs)) 182 (let ((xref (pop xrefs))
183 (expected (pop expecteds))) 183 (expected (pop expecteds)))
184 184
@@ -204,8 +204,9 @@ to (xref-elisp-test-descr-to-target xref)."
204 204
205;; When tests are run from the Makefile, 'default-directory' is $HOME, 205;; When tests are run from the Makefile, 'default-directory' is $HOME,
206;; so we must provide this dir to expand-file-name in the expected 206;; so we must provide this dir to expand-file-name in the expected
207;; results. The Makefile sets EMACS_TEST_DIRECTORY. 207;; results. This also allows running these tests from other
208(defconst emacs-test-dir (getenv "EMACS_TEST_DIRECTORY")) 208;; directories.
209(defconst emacs-test-dir (file-name-directory (or load-file-name (buffer-file-name))))
209 210
210;; alphabetical by test name 211;; alphabetical by test name
211 212
@@ -244,12 +245,144 @@ to (xref-elisp-test-descr-to-target xref)."
244 245
245;; FIXME: defconst 246;; FIXME: defconst
246 247
248;; FIXME: eieio defclass
249
250;; Possible ways of defining the default method implementation for a
251;; generic function. We declare these here, so we know we cover all
252;; cases, and we don't rely on other code not changing.
253;;
254;; When the generic and default method are declared in the same place,
255;; elisp--xref-find-definitions only returns one.
256
257(cl-defstruct (xref-elisp-root-type)
258 slot-1)
259
260(cl-defgeneric xref-elisp-generic-no-methods ()
261 "doc string no-methods"
262 ;; No default implementation, no methods, but fboundp is true for
263 ;; this symbol; it calls cl-no-applicable-method
264 )
265
266(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type))
267 "doc string no-default xref-elisp-root-type"
268 "non-default for no-default")
269
270;; defgeneric after defmethod in file to ensure the fallback search
271;; method of just looking for the function name will fail.
272(cl-defgeneric xref-elisp-generic-no-default ()
273 "doc string no-default generic"
274 ;; No default implementation; this function calls the cl-generic
275 ;; dispatching code.
276 )
277
278(cl-defgeneric xref-elisp-generic-co-located-default ()
279 "doc string co-located-default generic"
280 "co-located default")
281
282(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type))
283 "doc string co-located-default xref-elisp-root-type"
284 "non-default for co-located-default")
285
286(cl-defgeneric xref-elisp-generic-separate-default ()
287 "doc string separate-default generic"
288 ;; default implementation provided separately
289 )
290
291(cl-defmethod xref-elisp-generic-separate-default ()
292 "doc string separate-default default"
293 "separate default")
294
295(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type))
296 "doc string separate-default xref-elisp-root-type"
297 "non-default for separate-default")
298
299(cl-defmethod xref-elisp-generic-implicit-generic ()
300 "doc string implict-generic default"
301 "default for implicit generic")
302
303(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type))
304 "doc string implict-generic xref-elisp-root-type"
305 "non-default for implicit generic")
306
307
308(xref-elisp-deftest find-defs-defgeneric-no-methods
309 (elisp--xref-find-definitions 'xref-elisp-generic-no-methods)
310 (list
311 (xref-make "(cl-defgeneric xref-elisp-generic-no-methods)"
312 (xref-make-elisp-location
313 'xref-elisp-generic-no-methods 'cl-defgeneric
314 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
315 ))
316
317(xref-elisp-deftest find-defs-defgeneric-no-default
318 (elisp--xref-find-definitions 'xref-elisp-generic-no-default)
319 (list
320 (xref-make "(cl-defgeneric xref-elisp-generic-no-default)"
321 (xref-make-elisp-location
322 'xref-elisp-generic-no-default 'cl-defgeneric
323 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
324 (xref-make "(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type)))"
325 (xref-make-elisp-location
326 '(xref-elisp-generic-no-default xref-elisp-root-type) 'cl-defmethod
327 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
328 ))
329
330(xref-elisp-deftest find-defs-defgeneric-co-located-default
331 (elisp--xref-find-definitions 'xref-elisp-generic-co-located-default)
332 (list
333 (xref-make "(cl-defgeneric xref-elisp-generic-co-located-default)"
334 (xref-make-elisp-location
335 'xref-elisp-generic-co-located-default 'cl-defgeneric
336 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
337 (xref-make "(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type)))"
338 (xref-make-elisp-location
339 '(xref-elisp-generic-co-located-default xref-elisp-root-type) 'cl-defmethod
340 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
341 ))
342
343(xref-elisp-deftest find-defs-defgeneric-separate-default
344 (elisp--xref-find-definitions 'xref-elisp-generic-separate-default)
345 (list
346 (xref-make "(cl-defgeneric xref-elisp-generic-separate-default)"
347 (xref-make-elisp-location
348 'xref-elisp-generic-separate-default 'cl-defgeneric
349 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
350 (xref-make "(cl-defmethod xref-elisp-generic-separate-default ())"
351 (xref-make-elisp-location
352 '(xref-elisp-generic-separate-default) 'cl-defmethod
353 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
354
355 (xref-make "(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type)))"
356 (xref-make-elisp-location
357 '(xref-elisp-generic-separate-default xref-elisp-root-type) 'cl-defmethod
358 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
359 ))
360
361(xref-elisp-deftest find-defs-defgeneric-implicit-generic
362 (elisp--xref-find-definitions 'xref-elisp-generic-implicit-generic)
363 (list
364 (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ())"
365 (xref-make-elisp-location
366 '(xref-elisp-generic-implicit-generic) 'cl-defmethod
367 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
368 (xref-make "(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type)))"
369 (xref-make-elisp-location
370 '(xref-elisp-generic-implicit-generic xref-elisp-root-type) 'cl-defmethod
371 (expand-file-name "elisp-mode-tests.el" emacs-test-dir)))
372 ))
373
374;; Test that we handle more than one method
375
376;; When run from the Makefile, etags is not loaded at compile time,
377;; but it is by the time this test is run. interactively; don't fail
378;; for that.
379(require 'etags)
247(xref-elisp-deftest find-defs-defgeneric-el 380(xref-elisp-deftest find-defs-defgeneric-el
248 (elisp--xref-find-definitions 'xref-location-marker) 381 (elisp--xref-find-definitions 'xref-location-marker)
249 (list 382 (list
250 (xref-make "(cl-defgeneric xref-location-marker)" 383 (xref-make "(cl-defgeneric xref-location-marker)"
251 (xref-make-elisp-location 384 (xref-make-elisp-location
252 'xref-location-marker nil 385 'xref-location-marker 'cl-defgeneric
253 (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) 386 (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir)))
254 (xref-make "(cl-defmethod xref-location-marker ((l xref-elisp-location)))" 387 (xref-make "(cl-defmethod xref-location-marker ((l xref-elisp-location)))"
255 (xref-make-elisp-location 388 (xref-make-elisp-location
@@ -267,7 +400,10 @@ to (xref-elisp-test-descr-to-target xref)."
267 (xref-make-elisp-location 400 (xref-make-elisp-location
268 '(xref-location-marker xref-bogus-location) 'cl-defmethod 401 '(xref-location-marker xref-bogus-location) 'cl-defmethod
269 (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))) 402 (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir)))
270 ;; etags is not loaded at test time 403 (xref-make "(cl-defmethod xref-location-marker ((l xref-etags-location)))"
404 (xref-make-elisp-location
405 '(xref-location-marker xref-etags-location) 'cl-defmethod
406 (expand-file-name "../../lisp/progmodes/etags.el" emacs-test-dir)))
271 )) 407 ))
272 408
273(xref-elisp-deftest find-defs-defgeneric-eval 409(xref-elisp-deftest find-defs-defgeneric-eval
@@ -318,20 +454,19 @@ to (xref-elisp-test-descr-to-target xref)."
318 ) 454 )
319 455
320;; Source for both variable and defun is "(define-minor-mode 456;; Source for both variable and defun is "(define-minor-mode
321;; compilation-minor-mode". There is no way to tell that from the 457;; compilation-minor-mode". There is no way to tell that directly from
322;; symbol. find-function-regexp-alist uses find-function-regexp for 458;; the symbol, but we can use (memq sym minor-mode-list) to detect
323;; this, but that matches too many things for use in this test. 459;; that the symbol is a minor mode. See `elisp--xref-find-definitions'
460;; for more comments.
461;;
462;; IMPROVEME: return defvar instead of defun if source near starting
463;; point indicates the user is searching for a varible, not a
464;; function.
324(require 'compile) ;; not loaded by default at test time 465(require 'compile) ;; not loaded by default at test time
325(xref-elisp-deftest find-defs-defun-defvar-el 466(xref-elisp-deftest find-defs-defun-defvar-el
326 (elisp--xref-find-definitions 'compilation-minor-mode) 467 (elisp--xref-find-definitions 'compilation-minor-mode)
327 (list 468 (list
328 (cons 469 (cons
329 (xref-make "(defvar compilation-minor-mode)"
330 (xref-make-elisp-location
331 'compilation-minor-mode 'defvar
332 (expand-file-name "../../lisp/progmodes/compile.el" emacs-test-dir)))
333 "(define-minor-mode compilation-minor-mode")
334 (cons
335 (xref-make "(defun compilation-minor-mode)" 470 (xref-make "(defun compilation-minor-mode)"
336 (xref-make-elisp-location 471 (xref-make-elisp-location
337 'compilation-minor-mode nil 472 'compilation-minor-mode nil
@@ -382,10 +517,13 @@ to (xref-elisp-test-descr-to-target xref)."
382(xref-elisp-deftest find-defs-feature-el 517(xref-elisp-deftest find-defs-feature-el
383 (elisp--xref-find-definitions 'xref) 518 (elisp--xref-find-definitions 'xref)
384 (list 519 (list
385 (xref-make "(feature xref)" 520 (cons
521 (xref-make "(feature xref)"
386 (xref-make-elisp-location 522 (xref-make-elisp-location
387 'xref 'feature 523 'xref 'feature
388 (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir))))) 524 (expand-file-name "../../lisp/progmodes/xref.el" emacs-test-dir)))
525 ";;; Code:")
526 ))
389 527
390(xref-elisp-deftest find-defs-feature-eval 528(xref-elisp-deftest find-defs-feature-eval
391 (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature))) 529 (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature)))