|
1 | 1 | ;;; racket-describe.el -*- lexical-binding: t -*-
|
2 | 2 |
|
3 |
| -;; Copyright (c) 2013-2024 by Greg Hendershott. |
| 3 | +;; Copyright (c) 2013-2025 by Greg Hendershott. |
4 | 4 | ;; Portions Copyright (C) 1985-1986, 1999-2013 Free Software Foundation, Inc.
|
5 | 5 |
|
6 | 6 | ;; Author: Greg Hendershott
|
|
28 | 28 | (defvar-local racket--describe-stack-forward nil
|
29 | 29 | "Forward navigation list. Each item is (cons path point).")
|
30 | 30 |
|
31 |
| -(defun racket--do-describe (how repl-session-id str) |
32 |
| - "Get/create, display and return a `racket-describe-mode'. |
33 |
| -
|
34 |
| -HOW is somewhat complicated, due to this function being |
35 |
| -overloaded to handle both showing documentation for an |
36 |
| -already-known path and anchor (e.g. from `racket-xp-mode') as |
37 |
| -well as seeing if STR is an identifier in a namespace for which |
38 |
| -we can find documentation, or least return a description of its |
39 |
| -signature and/or type. So: |
40 |
| -
|
41 |
| -- When HOW is (cons path anchor) we load/show that documentation, |
42 |
| - and ignore STR. We don't issue a back end command. (Earlier |
43 |
| - versions of Racket Mode used the back end to fetch the HTML or |
44 |
| - shr-dom, but these days we do it all in the front end.) |
45 |
| - REPL-SESSION-ID and STR are unused and may be nil. |
46 |
| -
|
47 |
| -- When HOW is \"namespace\" or a stringp pathname, we use that as |
48 |
| - the namespace in which to see if STR is an identifier, using |
49 |
| - the \"describe\" back end command. The command can return a few |
50 |
| - kinds of values; see the implementation below. When HOW is |
51 |
| - \"namespace\" then REPL-SESSION-ID should be |
52 |
| - `racket--repl-session-id'; else may be nil." |
| 31 | +(defun racket--call-with-describe-buffer (thunk) |
| 32 | + "Call THUNK in a blank `racket-describe-mode-buffer' and return |
| 33 | +the buffer. |
| 34 | +
|
| 35 | +A helper for use by `racket--describe-path+anchor' and |
| 36 | +`racket--describe-string'." |
53 | 37 | (let ((buf-name (format "*Racket Describe <%s>*"
|
54 | 38 | (racket-back-end-name))))
|
55 | 39 | (with-current-buffer (get-buffer-create buf-name)
|
56 | 40 | (unless (eq major-mode 'racket-describe-mode)
|
57 | 41 | (racket-describe-mode))
|
58 |
| - (racket--describe-maybe-push-here 'back) ;do before erasing buffer |
59 | 42 | (setq racket--describe-stack-forward nil)
|
| 43 | + (racket--describe-maybe-push-here 'back) ;before `erase-buffer' |
60 | 44 | (let ((buffer-read-only nil))
|
61 | 45 | (erase-buffer))
|
62 | 46 | ;; shr-insert-document needs window width for formatting, and we
|
63 | 47 | ;; set window-point, so proactively give the window a buffer.
|
64 | 48 | (pop-to-buffer (current-buffer))
|
65 |
| - (pcase how |
66 |
| - ;; If HOW is the doc path and anchor (the latter can be nil), |
67 |
| - ;; there's no need to issue a back end describe command. |
68 |
| - (`(,(and path (pred stringp)) . ,anchor) |
69 |
| - (racket--describe-insert-dom path |
70 |
| - anchor |
71 |
| - (racket--scribble-path->shr-dom path))) |
72 |
| - ;; If HOW is a string pathname or 'namspace, then we need to |
73 |
| - ;; use the back end describe command. It returns one of three |
74 |
| - ;; kinds of values. |
75 |
| - ((guard (or (stringp how) (eq how 'namespace))) |
76 |
| - (setq header-line-format |
77 |
| - (propertize (format "Getting information from back end about %s ..." str) |
78 |
| - 'face 'italic)) |
79 |
| - (racket--cmd/async |
80 |
| - repl-session-id |
81 |
| - `(describe ,(racket-how-front-to-back how) ,str) |
82 |
| - (lambda (result) |
83 |
| - (pcase result |
84 |
| - ;; STR has documentation at path and anchor. Handle like |
85 |
| - ;; the case where we knew the path and anchor up-front. |
86 |
| - (`(,(and path (pred stringp)) . ,anchor) |
87 |
| - (let ((path (racket-file-name-back-to-front path))) |
88 |
| - (racket--describe-insert-dom path |
89 |
| - anchor |
90 |
| - (racket--scribble-path->shr-dom path)))) |
91 |
| - ;; STR doesn't have documentation, but it does have a |
92 |
| - ;; signature and/or type, and here is a dom about that |
93 |
| - ;; we can insert. |
94 |
| - (`(shr-dom ,dom) |
95 |
| - (racket--describe-insert-dom nil ;path |
96 |
| - str ;anchor |
97 |
| - dom)) |
98 |
| - ;; STR doesn't seem to be an identifier we can describe. |
99 |
| - (`() |
100 |
| - (racket--describe-insert-dom nil ;path |
101 |
| - str ;anchor |
102 |
| - (racket--describe-not-found-dom str))))))) |
103 |
| - (_ (error "Bad value for `how`: %s" how))) |
| 49 | + (funcall thunk) |
104 | 50 | (current-buffer))))
|
105 | 51 |
|
| 52 | +(defun racket--describe-path+anchor (path anchor) |
| 53 | + "Display/return `racket-describe-mode' buffer for PATH and ANCHOR." |
| 54 | + (racket--call-with-describe-buffer |
| 55 | + (lambda () |
| 56 | + (racket--describe-insert-dom path |
| 57 | + anchor |
| 58 | + (racket--scribble-path->shr-dom path))))) |
| 59 | + |
| 60 | +(defun racket--describe-string (str how &optional repl-session-id) |
| 61 | + "Display/return `racket-describe-mode' buffer for STR. |
| 62 | +
|
| 63 | +Use back end \"describe\" command to try to find documentation or |
| 64 | +a description of STR, where HOW is either the source file |
| 65 | +pathname or \\='namespace. When the latter, REPL-SESSION-ID must |
| 66 | +be supplied." |
| 67 | + (racket--call-with-describe-buffer |
| 68 | + (lambda () |
| 69 | + (setq header-line-format |
| 70 | + (propertize (format "Getting information from back end about %s ..." str) |
| 71 | + 'face 'italic)) |
| 72 | + (racket--cmd/async |
| 73 | + repl-session-id |
| 74 | + `(describe ,(racket-how-front-to-back how) ,str) |
| 75 | + (lambda (result) |
| 76 | + (pcase result |
| 77 | + ;; STR has documentation at path and anchor. |
| 78 | + (`(,(and path (pred stringp)) . ,anchor) |
| 79 | + (let ((path (racket-file-name-back-to-front path))) |
| 80 | + (racket--describe-insert-dom path |
| 81 | + anchor |
| 82 | + (racket--scribble-path->shr-dom path)))) |
| 83 | + ;; STR doesn't have documentation, but it does have a |
| 84 | + ;; signature and/or type, and here is a dom about that |
| 85 | + ;; we can insert. |
| 86 | + (`(shr-dom ,dom) |
| 87 | + (racket--describe-insert-dom nil ;path |
| 88 | + str ;anchor |
| 89 | + dom)) |
| 90 | + ;; STR doesn't seem to be an identifier we can describe. |
| 91 | + (`() |
| 92 | + (racket--describe-insert-dom nil ;path |
| 93 | + str ;anchor |
| 94 | + (racket--describe-not-found-dom str))))))))) |
| 95 | + |
106 | 96 | (defun racket--describe-not-found-dom (str)
|
107 | 97 | `(div ()
|
108 | 98 | (p ()
|
@@ -512,9 +502,8 @@ current line and looking back."
|
512 | 502 |
|
513 | 503 | (defun racket-describe-bookmark-jump (bmk)
|
514 | 504 | (set-buffer
|
515 |
| - (racket--do-describe (cons (bookmark-prop-get bmk 'filename) |
516 |
| - (bookmark-prop-get bmk 'position)) |
517 |
| - nil ""))) |
| 505 | + (racket--describe-path+anchor (bookmark-prop-get bmk 'filename) |
| 506 | + (bookmark-prop-get bmk 'position)))) |
518 | 507 | (put 'racket-describe-bookmark-jump 'bookmark-handler-type "Racket docs")
|
519 | 508 |
|
520 | 509 | ;; org-link support
|
@@ -542,7 +531,8 @@ current line and looking back."
|
542 | 531 | :description (racket--describe-label-for-point))))
|
543 | 532 |
|
544 | 533 | (defun racket--describe-org-link-follow (link)
|
545 |
| - (racket--do-describe (read link) nil "")) |
| 534 | + (pcase-let ((`(,path . ,anchor) (read link))) |
| 535 | + (racket--describe-path+anchor path anchor))) |
546 | 536 |
|
547 | 537 | ;; keymap and major mode
|
548 | 538 |
|
@@ -613,11 +603,9 @@ browser program -- are given `racket-ext-link-face'.
|
613 | 603 | "Search installed documentation; view using `racket-describe-mode'."
|
614 | 604 | (interactive)
|
615 | 605 | (pcase (racket--describe-search-completing-read)
|
616 |
| - (`(,term ,path ,anchor ,_lib) |
617 |
| - (racket--do-describe (cons (racket-file-name-back-to-front path) |
618 |
| - anchor) |
619 |
| - nil |
620 |
| - term)))) |
| 606 | + (`(,_term ,path ,anchor ,_lib) |
| 607 | + (racket--describe-path+anchor (racket-file-name-back-to-front path) |
| 608 | + anchor)))) |
621 | 609 |
|
622 | 610 | (defun racket--describe-search-completing-read ()
|
623 | 611 | "A `completing-read' UX for user to pick doc index item.
|
|
0 commit comments