Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Many enhancements to racket-describe and racket-describe-search
This commit is a squash of a branch with many dozens of commits. === racket-describe === 1. Build/massage shr dom for docs on front end Previously the back end would read a Racket documentation HTML file, create an xexpr, convert that to HTML text, and return it to the front end... which would use libxml-parse-html-region to convert to a shr "dom", and use shr-insert to add that to the Emacs buffer. The silly part there is the extra conversion to HTML text and back again. (It probably made sense in the early days of Racket mode, when command responses were written into the REPL buffer, and it was more reliable to handle a single string literal.) In an interim commit I had the back end directly build the shr dom needed by the front end. Better. Then I took it a step further: Emacs is perfectly capable of reading an HTML file to a shr dom, and doing the same kind of massaging that the back end was doing. (Although Emacs Lisp pcase is not quite as elegant as Racket match, for the massaging, it's capable, and the massaging is mostly a non-elegant pile of hacks, anyway.) In the common case where we already know the doc path and anchor from racket-xp-mode having annotated that, this avoids needing to send a back end command at all. In my testing so far it seems faster; certainly not slower. In the remaining cases, we still need to do a back end describe command. In the case where doc is found, it can simply return the path and anchor, and the front end loads the same way. Otherwise describe returns a shr dom describing the signature, type, and/or contract, or nil if none of those can be found. 2. Render entire doc pages Previously we would try to return just an excerpt of the HTML -- given some anchor, return the heading/bluebox for that anchor, up until another heading/bluebox. The justification of the excerpt approach was that it could be faster. Although this worked well for most documentation, it wasn't ideal for things with very brief descriptions, where the author expected users could scroll up or down for more context. Furthermore, racket-describe-search now supports searching any term in the documentation index (not just exports; see below), and we are now supporting intra-doc links and anchors (see below). As a result, sometimes we're returning documentation for things like a techdef. Here again, sometimes a short section is intended to be understood in the context of a complete doc page. As a result, this commit takes the approach of always returning complete documentation pages. Although this can be slower for very large doc pages, overall and on balance I think the experience is better. Certainly it presents the documentation more closely to how authors expect readers to be able to use it. Related: - Show path/anchor in header-line. - Support extracting the navsettop (top, up, prev, next) links as a `racket-nav` element to be used as info-mode style navigation commands. 3. Improve rendering of Racket doc pages Handle code block tables with single td per row, which is a weird thing Scribble does, and which shr handles weirdly, by instead converting them to simple divs. This avoids problems with the initial line or two of code blocks being indented too much. Inspect span elements for classes like RktSym, RktVal, and so on, and use various faces like font-lock-keyword-face and so on. 4. Support intra-doc links Back end: - Supply custom HTML tags `racket-anchor`, `racket-doc-link`, and `racket-ext-link` and for the front end to use. - Handle all three flavors of local-redirect links. Front end: - Support visiting links to other documentation. - Support forward/back navigation history, including restoring point. - Add faces to let users customize internal and external links. === racket-describe-search === 1. Name, keybindings Rename from racket-search-describe to be consistent with e.g. racket-documentation-search. Give it a C-c C-s binding in various modes like racket-xp-mode and racket-repl-mode, as well as racket-describe-mode and racket-describe-search-mode themselves. 2. Use "streaming" elisp-writeln and thunk for doc index response. Rather than converting an entire value from Racket to Elisp and writing that, elisp-writeln now writes the value piece by piece directly to the current output port. Furthermore, when a value is a thunk, it calls the thunk which can elisp-writeln one by one directly out. Use this capability in the doc-index-names command, which responds with a very long list of strings. This reduces peak memory use. Also, refine the front-end UX for racket-search-describe, to wait about 5 seconds for doc-index-names to respond, otherwise it proceeds with an empty list of completion candidates. This is a sort of warm bowl of porridge, in between racket--cmd/async and racket--cmd/await. Effectively it is a bespoke variation of the latter. (I think this is probably a good strategy for eliminating the few remaining uses of racket--cmd/await: Use a timeout amount and default value that is appropriate for each specific situation -- as opposed to the extremes of waiting forever or giving a "command timeout" error.) 3. Use xref entry-words This handles things like for example entries where exported-index-desc-name is "drracket:unit:frame%" and where entry-words is a class method name like "add-show-menu-items". 4. Handle all doc index terms, not just exports.
- Loading branch information