aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimen Heggestøyl2020-04-18 18:36:49 +0200
committerSimen Heggestøyl2020-04-18 18:43:23 +0200
commit45d42f81621743a96f209102464432ef2f230b0f (patch)
treed2671b98e9455f85ff03449585260e50ac5bd813
parent4819bea6900348f923e0de58995ec41760993b6c (diff)
downloademacs-45d42f81621743a96f209102464432ef2f230b0f.tar.gz
emacs-45d42f81621743a96f209102464432ef2f230b0f.zip
Use lexical-binding in apropos.el and add tests
* lisp/apropos.el: Use lexical-binding and remove redundant :group args. (apropos-words-to-regexp, apropos): Tweak docstrings. (apropos-value-internal): Replace '(if x (progn y))' with '(when x y)'. (apropos-format-plist): Add docstring and replace '(if x (progn y))' with '(when x y)'. * test/lisp/apropos-tests.el: New file with tests for apropos.el.
-rw-r--r--lisp/apropos.el52
-rw-r--r--test/lisp/apropos-tests.el133
2 files changed, 154 insertions, 31 deletions
diff --git a/lisp/apropos.el b/lisp/apropos.el
index 7277319cd89..e40f94ccb8c 100644
--- a/lisp/apropos.el
+++ b/lisp/apropos.el
@@ -1,4 +1,4 @@
1;;; apropos.el --- apropos commands for users and programmers 1;;; apropos.el --- apropos commands for users and programmers -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 1989, 1994-1995, 2001-2020 Free Software Foundation, 3;; Copyright (C) 1989, 1994-1995, 2001-2020 Free Software Foundation,
4;; Inc. 4;; Inc.
@@ -82,49 +82,41 @@ commands also has an optional argument to request a more extensive search.
82 82
83Additionally, this option makes the function `apropos-library' 83Additionally, this option makes the function `apropos-library'
84include key-binding information in its output." 84include key-binding information in its output."
85 :group 'apropos
86 :type 'boolean) 85 :type 'boolean)
87 86
88(defface apropos-symbol 87(defface apropos-symbol
89 '((t (:inherit bold))) 88 '((t (:inherit bold)))
90 "Face for the symbol name in Apropos output." 89 "Face for the symbol name in Apropos output."
91 :group 'apropos
92 :version "24.3") 90 :version "24.3")
93 91
94(defface apropos-keybinding 92(defface apropos-keybinding
95 '((t (:inherit underline))) 93 '((t (:inherit underline)))
96 "Face for lists of keybinding in Apropos output." 94 "Face for lists of keybinding in Apropos output."
97 :group 'apropos
98 :version "24.3") 95 :version "24.3")
99 96
100(defface apropos-property 97(defface apropos-property
101 '((t (:inherit font-lock-builtin-face))) 98 '((t (:inherit font-lock-builtin-face)))
102 "Face for property name in Apropos output, or nil for none." 99 "Face for property name in Apropos output, or nil for none."
103 :group 'apropos
104 :version "24.3") 100 :version "24.3")
105 101
106(defface apropos-function-button 102(defface apropos-function-button
107 '((t (:inherit (font-lock-function-name-face button)))) 103 '((t (:inherit (font-lock-function-name-face button))))
108 "Button face indicating a function, macro, or command in Apropos." 104 "Button face indicating a function, macro, or command in Apropos."
109 :group 'apropos
110 :version "24.3") 105 :version "24.3")
111 106
112(defface apropos-variable-button 107(defface apropos-variable-button
113 '((t (:inherit (font-lock-variable-name-face button)))) 108 '((t (:inherit (font-lock-variable-name-face button))))
114 "Button face indicating a variable in Apropos." 109 "Button face indicating a variable in Apropos."
115 :group 'apropos
116 :version "24.3") 110 :version "24.3")
117 111
118(defface apropos-user-option-button 112(defface apropos-user-option-button
119 '((t (:inherit (font-lock-variable-name-face button)))) 113 '((t (:inherit (font-lock-variable-name-face button))))
120 "Button face indicating a user option in Apropos." 114 "Button face indicating a user option in Apropos."
121 :group 'apropos
122 :version "24.4") 115 :version "24.4")
123 116
124(defface apropos-misc-button 117(defface apropos-misc-button
125 '((t (:inherit (font-lock-constant-face button)))) 118 '((t (:inherit (font-lock-constant-face button))))
126 "Button face indicating a miscellaneous object type in Apropos." 119 "Button face indicating a miscellaneous object type in Apropos."
127 :group 'apropos
128 :version "24.3") 120 :version "24.3")
129 121
130(defcustom apropos-match-face 'match 122(defcustom apropos-match-face 'match
@@ -132,14 +124,12 @@ include key-binding information in its output."
132This applies when you look for matches in the documentation or variable value 124This applies when you look for matches in the documentation or variable value
133for the pattern; the part that matches gets displayed in this font." 125for the pattern; the part that matches gets displayed in this font."
134 :type '(choice (const nil) face) 126 :type '(choice (const nil) face)
135 :group 'apropos
136 :version "24.3") 127 :version "24.3")
137 128
138(defcustom apropos-sort-by-scores nil 129(defcustom apropos-sort-by-scores nil
139 "Non-nil means sort matches by scores; best match is shown first. 130 "Non-nil means sort matches by scores; best match is shown first.
140This applies to all `apropos' commands except `apropos-documentation'. 131This applies to all `apropos' commands except `apropos-documentation'.
141If value is `verbose', the computed score is shown for each match." 132If value is `verbose', the computed score is shown for each match."
142 :group 'apropos
143 :type '(choice (const :tag "off" nil) 133 :type '(choice (const :tag "off" nil)
144 (const :tag "on" t) 134 (const :tag "on" t)
145 (const :tag "show scores" verbose))) 135 (const :tag "show scores" verbose)))
@@ -148,7 +138,6 @@ If value is `verbose', the computed score is shown for each match."
148 "Non-nil means sort matches by scores; best match is shown first. 138 "Non-nil means sort matches by scores; best match is shown first.
149This applies to `apropos-documentation' only. 139This applies to `apropos-documentation' only.
150If value is `verbose', the computed score is shown for each match." 140If value is `verbose', the computed score is shown for each match."
151 :group 'apropos
152 :type '(choice (const :tag "off" nil) 141 :type '(choice (const :tag "off" nil)
153 (const :tag "on" t) 142 (const :tag "on" t)
154 (const :tag "show scores" verbose))) 143 (const :tag "show scores" verbose)))
@@ -352,7 +341,7 @@ before finding a label."
352 341
353 342
354(defun apropos-words-to-regexp (words wild) 343(defun apropos-words-to-regexp (words wild)
355 "Make regexp matching any two of the words in WORDS. 344 "Return a regexp matching any two of the words in WORDS.
356WILD should be a subexpression matching wildcards between matches." 345WILD should be a subexpression matching wildcards between matches."
357 (setq words (delete-dups (copy-sequence words))) 346 (setq words (delete-dups (copy-sequence words)))
358 (if (null (cdr words)) 347 (if (null (cdr words))
@@ -644,7 +633,7 @@ search for matches for any two (or more) of those words.
644With \\[universal-argument] prefix, or if `apropos-do-all' is non-nil, 633With \\[universal-argument] prefix, or if `apropos-do-all' is non-nil,
645consider all symbols (if they match PATTERN). 634consider all symbols (if they match PATTERN).
646 635
647Returns list of symbols and documentation found." 636Return list of symbols and documentation found."
648 (interactive (list (apropos-read-pattern "symbol") 637 (interactive (list (apropos-read-pattern "symbol")
649 current-prefix-arg)) 638 current-prefix-arg))
650 (setq apropos--current (list #'apropos pattern do-all)) 639 (setq apropos--current (list #'apropos pattern do-all))
@@ -921,16 +910,14 @@ Returns list of symbols and documentation found."
921 910
922 911
923(defun apropos-value-internal (predicate symbol function) 912(defun apropos-value-internal (predicate symbol function)
924 (if (funcall predicate symbol) 913 (when (funcall predicate symbol)
925 (progn 914 (setq symbol (prin1-to-string (funcall function symbol)))
926 (setq symbol (prin1-to-string (funcall function symbol))) 915 (when (string-match apropos-regexp symbol)
927 (if (string-match apropos-regexp symbol) 916 (if apropos-match-face
928 (progn 917 (put-text-property (match-beginning 0) (match-end 0)
929 (if apropos-match-face 918 'face apropos-match-face
930 (put-text-property (match-beginning 0) (match-end 0) 919 symbol))
931 'face apropos-match-face 920 symbol)))
932 symbol))
933 symbol)))))
934 921
935(defun apropos-documentation-internal (doc) 922(defun apropos-documentation-internal (doc)
936 (cond 923 (cond
@@ -952,6 +939,10 @@ Returns list of symbols and documentation found."
952 doc)))) 939 doc))))
953 940
954(defun apropos-format-plist (pl sep &optional compare) 941(defun apropos-format-plist (pl sep &optional compare)
942 "Return a string representation of the plist PL.
943Paired elements are separated by the string SEP. Only include
944properties matching the current `apropos-regexp' when COMPARE is
945non-nil."
955 (setq pl (symbol-plist pl)) 946 (setq pl (symbol-plist pl))
956 (let (p p-out) 947 (let (p p-out)
957 (while pl 948 (while pl
@@ -960,13 +951,12 @@ Returns list of symbols and documentation found."
960 (put-text-property 0 (length (symbol-name (car pl))) 951 (put-text-property 0 (length (symbol-name (car pl)))
961 'face 'apropos-property p) 952 'face 'apropos-property p)
962 (setq p nil)) 953 (setq p nil))
963 (if p 954 (when p
964 (progn 955 (and compare apropos-match-face
965 (and compare apropos-match-face 956 (put-text-property (match-beginning 0) (match-end 0)
966 (put-text-property (match-beginning 0) (match-end 0) 957 'face apropos-match-face
967 'face apropos-match-face 958 p))
968 p)) 959 (setq p-out (concat p-out (if p-out sep) p)))
969 (setq p-out (concat p-out (if p-out sep) p))))
970 (setq pl (nthcdr 2 pl))) 960 (setq pl (nthcdr 2 pl)))
971 p-out)) 961 p-out))
972 962
diff --git a/test/lisp/apropos-tests.el b/test/lisp/apropos-tests.el
new file mode 100644
index 00000000000..4c5522d14c2
--- /dev/null
+++ b/test/lisp/apropos-tests.el
@@ -0,0 +1,133 @@
1;;; apropos-tests.el --- Tests for apropos.el -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2020 Free Software Foundation, Inc.
4
5;; Author: Simen Heggestøyl <simenheg@gmail.com>
6;; Keywords:
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;;
26
27;;; Code:
28
29(require 'apropos)
30(require 'ert)
31
32(ert-deftest apropos-tests-words-to-regexp-1 ()
33 (let ((re (apropos-words-to-regexp '("foo" "bar") "baz")))
34 (should (string-match-p re "foobazbar"))
35 (should (string-match-p re "barbazfoo"))
36 (should-not (string-match-p re "foo-bar"))
37 (should-not (string-match-p re "foobazbazbar"))))
38
39(ert-deftest apropos-tests-words-to-regexp-2 ()
40 (let ((re (apropos-words-to-regexp '("foo" "bar" "baz") "-")))
41 (should-not (string-match-p re "foo"))
42 (should-not (string-match-p re "foobar"))
43 (should (string-match-p re "foo-bar"))
44 (should (string-match-p re "foo-baz"))))
45
46(ert-deftest apropos-tests-parse-pattern-1 ()
47 (apropos-parse-pattern '("foo"))
48 (should (string-match-p apropos-regexp "foo"))
49 (should (string-match-p apropos-regexp "foo-bar"))
50 (should (string-match-p apropos-regexp "bar-foo"))
51 (should (string-match-p apropos-regexp "foo-foo"))
52 (should-not (string-match-p apropos-regexp "bar")))
53
54(ert-deftest apropos-tests-parse-pattern-2 ()
55 (apropos-parse-pattern '("foo" "bar"))
56 (should (string-match-p apropos-regexp "foo-bar"))
57 (should (string-match-p apropos-regexp "bar-foo"))
58 (should-not (string-match-p apropos-regexp "foo"))
59 (should-not (string-match-p apropos-regexp "bar"))
60 (should-not (string-match-p apropos-regexp "baz"))
61 (should-not (string-match-p apropos-regexp "foo-foo"))
62 (should-not (string-match-p apropos-regexp "bar-bar")))
63
64(ert-deftest apropos-tests-parse-pattern-3 ()
65 (apropos-parse-pattern '("foo" "bar" "baz"))
66 (should (string-match-p apropos-regexp "foo-bar"))
67 (should (string-match-p apropos-regexp "foo-baz"))
68 (should (string-match-p apropos-regexp "bar-foo"))
69 (should (string-match-p apropos-regexp "bar-baz"))
70 (should (string-match-p apropos-regexp "baz-foo"))
71 (should (string-match-p apropos-regexp "baz-bar"))
72 (should-not (string-match-p apropos-regexp "foo"))
73 (should-not (string-match-p apropos-regexp "bar"))
74 (should-not (string-match-p apropos-regexp "baz"))
75 (should-not (string-match-p apropos-regexp "foo-foo"))
76 (should-not (string-match-p apropos-regexp "bar-bar"))
77 (should-not (string-match-p apropos-regexp "baz-baz")))
78
79(ert-deftest apropos-tests-parse-pattern-single-regexp ()
80 (apropos-parse-pattern "foo+bar")
81 (should-not (string-match-p apropos-regexp "fobar"))
82 (should (string-match-p apropos-regexp "foobar"))
83 (should (string-match-p apropos-regexp "fooobar")))
84
85(ert-deftest apropos-tests-parse-pattern-synonyms ()
86 (let ((apropos-synonyms '(("find" "open" "edit"))))
87 (apropos-parse-pattern '("open"))
88 (should (string-match-p apropos-regexp "find-file"))
89 (should (string-match-p apropos-regexp "open-file"))
90 (should (string-match-p apropos-regexp "edit-file"))))
91
92(ert-deftest apropos-tests-calc-scores ()
93 (let ((str "Return apropos score for string STR."))
94 (should (equal (apropos-calc-scores str '("apr")) '(7)))
95 (should (equal (apropos-calc-scores str '("apr" "str")) '(25 7)))
96 (should (equal (apropos-calc-scores str '("appr" "str")) '(25)))
97 (should-not (apropos-calc-scores str '("appr" "strr")))))
98
99(ert-deftest apropos-tests-score-str ()
100 (apropos-parse-pattern '("foo" "bar"))
101 (should (< (apropos-score-str "baz")
102 (apropos-score-str "foo baz")
103 (apropos-score-str "foo bar baz"))))
104
105(ert-deftest apropos-tests-score-doc ()
106 (apropos-parse-pattern '("foo" "bar"))
107 (should (< (apropos-score-doc "baz")
108 (apropos-score-doc "foo baz")
109 (apropos-score-doc "foo bar baz"))))
110
111(ert-deftest apropos-tests-score-symbol ()
112 (apropos-parse-pattern '("foo" "bar"))
113 (should (< (apropos-score-symbol 'baz)
114 (apropos-score-symbol 'foo-baz)
115 (apropos-score-symbol 'foo-bar-baz))))
116
117(ert-deftest apropos-tests-true-hit ()
118 (should-not (apropos-true-hit "foo" '("foo" "bar")))
119 (should (apropos-true-hit "foo bar" '("foo" "bar")))
120 (should (apropos-true-hit "foo bar baz" '("foo" "bar"))))
121
122(ert-deftest apropos-tests-format-plist ()
123 (setplist 'foo '(a 1 b (2 3) c nil))
124 (apropos-parse-pattern '("b"))
125 (should (equal (apropos-format-plist 'foo ", ")
126 "a 1, b (2 3), c nil"))
127 (should (equal (apropos-format-plist 'foo ", " t)
128 "b (2 3)"))
129 (apropos-parse-pattern '("d"))
130 (should-not (apropos-format-plist 'foo ", " t)))
131
132(provide 'apropos-tests)
133;;; apropos-tests.el ends here