Skip to content

Commit 5ecbb45

Browse files
Improve racket-describe-search
- Use exported-index-desc* and index-desc structs when available from a sufficiently new scribble-lib. Among other things, these enable better "kind" descriptions, and add the concept of "language families". - Replace the racket-describe-search-mode "disambiguation" buffer with a completing-read that shows search metadata as completion annotations. (The buffers were an annoying intermediate step, and tended to remain around as litter.) - Change dynamic-require wrappers. - Now that we make an affixation-function in four places, add a racket--make-affix helper. - Change the Racket package status "manual" to "installed", for a package that wasn't installed just as a dependency. In testing describe-racket-package using the new racket--make-affix, I found "manual" to be ambiguous (it implies "documentation" as well as "manually installed vs. automatically installed as a dependency"). Furthermore "installed" matches the term used by Emacs' list-packages and describe-package.
1 parent 1203449 commit 5ecbb45

21 files changed

+584
-345
lines changed

doc/generate.el

+2
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@
216216
racket-pretty-print
217217
racket-repl-command-file
218218
"Other variables"
219+
racket-doc-index-directory
220+
racket-doc-index-predicate-function
219221
racket-indent-curly-as-sequence
220222
racket-indent-sequence-depth
221223
racket-pretty-lambda

doc/racket-mode.texi

+24-15
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ REPL variables
243243
244244
Other variables
245245
246+
* racket-doc-index-directory::
247+
* racket-doc-index-predicate-function::
246248
* racket-indent-curly-as-sequence::
247249
* racket-indent-sequence-depth::
248250
* racket-pretty-lambda::
@@ -2144,21 +2146,6 @@ the Racket ``Search Manuals'' page.
21442146

21452147
Search installed documentation; view using @code{racket-describe-mode}.
21462148

2147-
Always prompts you to enter a symbol, defaulting to the symbol at
2148-
point if any.
2149-
2150-
@itemize
2151-
@item
2152-
If just one module exports the name, you go directly to a
2153-
Racket Describe buffer with its documentation.
2154-
2155-
@item
2156-
If multiple modules export the name, you go first to a
2157-
``disambiguation'' buffer similar to the Racket ``Search
2158-
Manuals'' web page. You may press RET on any item to get a
2159-
Racket Describe buffer for that module's version of the thing.
2160-
@end itemize
2161-
21622149
@node Run
21632150
@section Run
21642151

@@ -3581,6 +3568,8 @@ Name of the file used by @ref{racket-repl}.
35813568
@section Other variables
35823569

35833570
@menu
3571+
* racket-doc-index-directory::
3572+
* racket-doc-index-predicate-function::
35843573
* racket-indent-curly-as-sequence::
35853574
* racket-indent-sequence-depth::
35863575
* racket-pretty-lambda::
@@ -3591,6 +3580,26 @@ Name of the file used by @ref{racket-repl}.
35913580
* racket-sexp-comment-fade::
35923581
@end menu
35933582

3583+
@node racket-doc-index-directory
3584+
@subsection racket-doc-index-directory
3585+
3586+
Directory for @ref{racket-describe-search} doc index files.
3587+
3588+
@node racket-doc-index-predicate-function
3589+
@subsection racket-doc-index-predicate-function
3590+
3591+
A function used by @ref{racket-describe-search} to filter results.
3592+
3593+
The default value, the @code{always} function, filters nothing.
3594+
3595+
The function is given four string arguments -- TERM, WHAT,
3596+
FROM-LIBS, and FAMILIES -- and should return whether to include
3597+
the item in the list of completion candidates. An example that
3598+
limits candidates to the ``Rhombus'' family:
3599+
3600+
(lambda (@math{_term} _what _from-libs families)
3601+
(string-equal families ``Rhombus'')
3602+
35943603
@node racket-indent-curly-as-sequence
35953604
@subsection racket-indent-curly-as-sequence
35963605

racket-complete.el

+92
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,98 @@ displaying inappropriate annotations."
8989
(_
9090
(complete-with-action action completions prefix predicate)))))
9191

92+
(defun racket--make-affix (specs &optional prop)
93+
"Make an affixation-function to show completion annotations.
94+
95+
For more information about affixation-function completion
96+
metadata, see Info node `(elisp)Programmed Completion'.
97+
98+
PROP is the symbol name of a text property that must be attached
99+
to each of the completion candidate strings. The value of the
100+
property is a list of strings -- each string is a suffix column
101+
value to show as an annotation. The list length must be the same
102+
for all candidate strings. The property name defaults to
103+
\\='racket-affix.
104+
105+
SPECS is a vector of specs for each column -- one for the
106+
completion candidate string, plus the length of the list of
107+
suffix columns. Each spec may be an integer, which is a minimum
108+
width, or [WIDTH FACE]. Note: The width is N/A for the last
109+
suffix column. The face is N/A for the first column, which shows
110+
the candidate string. For suffix columns, the face defaults to
111+
completions-anntoations. An explicit nil value in the spec means
112+
not to add a face, because the string is already propertized with
113+
one.
114+
115+
The affixation-function arranges for each suffix column to be
116+
aligned, considering the minimum width and the maximum width of
117+
the previous column.
118+
119+
When a candidate string ends with text made invisible by a
120+
\\='display \"\" property -- as is done by
121+
`racket--doc-index-make-alist' -- that text is ignored for
122+
purposes of calculating widths."
123+
;; Note: Below we use `cl-loop' because `seq-do-indexed' and
124+
;; `seq-map-indexed' are unavailable in Emacs 25.
125+
(let ((min-widths (cl-loop
126+
for spec across specs
127+
collect (pcase spec
128+
(`[,width ,_face] width)
129+
((and (pred numberp) width) width)
130+
(_ 0))))
131+
(suffix-faces (cl-loop for spec across (seq-drop specs 1)
132+
collect (pcase spec
133+
(`[,_width ,face] face)
134+
(_ 'completions-annotations))))
135+
(prop (or prop 'racket-affix)))
136+
(lambda (strs)
137+
(let* ((max-widths (apply #'vector min-widths))
138+
(rows
139+
(cl-loop
140+
for str in strs
141+
collect
142+
(let ((visible-str
143+
(substring str
144+
0
145+
(text-property-any 0 (length str)
146+
'display ""
147+
str)))
148+
(suffixes (get-text-property 0 prop str)))
149+
;; Mutate `max-widths'.
150+
(cl-loop
151+
for col in (cons visible-str suffixes)
152+
for ix from 0
153+
do (aset max-widths ix
154+
(max (aref max-widths ix)
155+
(1+ (length col)))))
156+
(cons str suffixes))))
157+
(suffix-offsets
158+
(let ((offset 0))
159+
(cl-loop
160+
for max-width across max-widths
161+
collect
162+
(setq offset (+ offset max-width))))))
163+
(cl-loop
164+
for row in rows
165+
collect
166+
(pcase-let*
167+
((`(,str . ,suffixes) row)
168+
(suffixes-str
169+
(cl-loop
170+
for suffix in suffixes
171+
for offset in suffix-offsets
172+
for face in suffix-faces
173+
concat
174+
(concat
175+
(propertize " "
176+
'display
177+
`(space :align-to ,offset))
178+
(if face
179+
(propertize (or suffix "")
180+
'face face)
181+
(or suffix ""))))))
182+
(list str "" suffixes-str)))))))
183+
92184
(provide 'racket-complete)
93185

94186
;; racket-complete.el ends here

racket-custom.el

+35
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,28 @@ Scribble text, use the face `racket-hash-lang-text'."
222222
:type '(alist :key-type symbol :value-type face)
223223
:safe #'listp)
224224

225+
(defcustom racket-doc-index-directory
226+
(locate-user-emacs-file (file-name-as-directory "racket-mode"))
227+
"Directory for `racket-describe-search' doc index files."
228+
:type 'file)
229+
230+
(defcustom racket-doc-index-predicate-function
231+
'always
232+
"A function used by `racket-describe-search' to filter results.
233+
234+
The default value, the `always' function, filters nothing.
235+
236+
The function is given four string arguments -- TERM, WHAT,
237+
FROM-LIBS, and FAMILIES -- and should return whether to include
238+
the item in the list of completion candidates. An example that
239+
limits candidates to the \"Rhombus\" family:
240+
241+
(lambda (_term _what _from-libs families)
242+
(string-equal families \"Rhombus\")
243+
"
244+
:type 'function
245+
:risky t)
246+
225247
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
226248
;;; racket-repl group
227249

@@ -595,6 +617,7 @@ ignore POS. Examples: `racket-show-echo-area' and
595617
:group 'racket)
596618

597619
(defmacro defface-racket (id facespec docstr)
620+
(declare (indent defun))
598621
`(progn
599622
(defconst ,id ',id)
600623
(defface ,id
@@ -803,6 +826,18 @@ See the variable `racket-browse-url-function'.")
803826
'((t (:inherit default)))
804827
"Face `racket-hash-lang-mode' uses for text tokens.")
805828

829+
(defface-racket racket-describe-search-kind
830+
'((t (:inherit font-lock-type-face)))
831+
"Face `racket-describe-search' uses for kinds.")
832+
833+
(defface-racket racket-describe-search-from-libs
834+
'((t (:inherit font-lock-string-face)))
835+
"Face `racket-describe-search' uses for library modules.")
836+
837+
(defface-racket racket-describe-search-lang-fams
838+
'((t (:inherit font-lock-doc-face)))
839+
"Face `racket-describe-search' uses for language families.")
840+
806841
(provide 'racket-custom)
807842

808843
;;; racket-custom.el ends here

0 commit comments

Comments
 (0)