-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adapt gambdoc to use the new TSV index #698
Open
lassik
wants to merge
2
commits into
gambit:master
Choose a base branch
from
lassik:lassik/gambdoc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
(define (make-browser name available? open) | ||
(vector name available? open)) | ||
|
||
(define (browser-name b) (vector-ref b 0)) | ||
(define (browser-available? b) ((vector-ref b 1))) | ||
(define (browser-open b url) ((vector-ref b 2) url)) | ||
|
||
(define (check-exit exit-status) | ||
(or (##fx= exit-status 0) | ||
(##raise-error-exception "failed to start web browser"))) | ||
|
||
(define (text-browser command) | ||
(make-browser | ||
command | ||
(lambda () (executable? command)) | ||
(lambda (url) | ||
(##tty-mode-reset) ;; reset tty (in case subprocess needs to read tty) | ||
(check-exit | ||
(##run-subprocess | ||
command | ||
'() ;; no arguments | ||
#f ;; don't capture output | ||
#f ;; don't redirect stdin | ||
#f ;; run in current directory | ||
(list url)))))) | ||
|
||
(define (gui-browser command) | ||
(make-browser | ||
command | ||
(lambda () (executable? command)) | ||
(lambda (url) | ||
(check-exit | ||
(##run-subprocess | ||
command | ||
'() ;; no arguments | ||
#f ;; don't capture output | ||
#f ;; don't redirect stdin | ||
#f ;; run in current directory | ||
(list url)))))) | ||
|
||
(define (gui-browser-osascript url) | ||
(let ((command "osascript")) | ||
(make-browser | ||
command | ||
(lambda () (executable? command)) | ||
(lambda (url) | ||
(let ((stdin (string-append "tell application \"Safari\"\n" | ||
" open location \"" url "\"\n" | ||
"end tell\n"))) | ||
(check-exit | ||
(##run-subprocess | ||
command | ||
'() ;; no arguments | ||
#f ;; don't capture output | ||
stdin ;; don't redirect stdin | ||
#f ;; run in current directory | ||
'()))))))) | ||
|
||
(define (gui-browser-js url) | ||
(##inline-host-statement "window.open(@scm2host@(@1@));" url)) | ||
|
||
;;; | ||
|
||
(define ##help-browsers | ||
(##make-parameter | ||
(append | ||
(if (equal? "" "@HELP_BROWSER@") | ||
'() | ||
(list (text-browser "@HELP_BROWSER@"))) | ||
(list gui-browser-js | ||
(text-browser "lynx") | ||
(gui-browser "firefox") | ||
(gui-browser "mozilla") | ||
(gui-browser "netscape") | ||
gui-browser-osascript | ||
(gui-browser "chrome") | ||
(gui-browser "chromium") | ||
(gui-browser "chromium-browser"))) | ||
(lambda (val) | ||
val))) | ||
|
||
(define help-browsers | ||
##help-browsers) | ||
|
||
(define (help-browse-url url) | ||
(let ((browsers (help-browsers))) | ||
(let loop ((tail browsers)) | ||
(if (null? tail) | ||
(begin (display "*** WARNING -- none of these browsers") | ||
(display " can be found to view the documentation:") | ||
(display "*** " (string-join browsers " "))) | ||
(let ((browser (car tail))) | ||
(if (browser-available? browser) | ||
(browser-open browser url) | ||
(loop (cdr tail)))))))) | ||
|
||
;;; | ||
|
||
(define help-root "~~doc/") | ||
(define help-index "gambit.tsv") | ||
|
||
(define (tsv-lookup path subject index) | ||
(let ((suffix (string-append "\t" index "\t" subject))) | ||
(call-with-input-file path | ||
(lambda (port) | ||
(let loop () | ||
(let ((line (read-line port))) | ||
(if (string? line) | ||
(if (##string-suffix=? line suffix) | ||
(let ((fields (##string-split-at-char line #\tab))) | ||
(url-join help-root (car fields))) | ||
(loop)) | ||
#f))))))) | ||
|
||
(define-prim (##show-help subject index) | ||
(define path-append string-append) | ||
(let* ((tsv-file (path-append help-root help-index)) | ||
(relative-url (tsv-lookup tsv-file subject index))) | ||
(if (not relative-url) | ||
(##raise-error-exception "no help found for" (##list subject)) | ||
(help-browse-url (path-append help-root relative-url))))) | ||
|
||
(define-prim (##show-documentation-of object) | ||
(##show-help (if (##string? object) | ||
object | ||
(##object->string (if (##procedure? object) | ||
(##procedure-name object) | ||
object))) | ||
"fn")) | ||
|
||
(define-prim (##default-help object) | ||
(##show-documentation-of object)) | ||
|
||
(define ##help-hook ##default-help) | ||
|
||
(define-prim (##help-hook-set! x) | ||
(set! ##help-hook x)) | ||
|
||
(define-prim (##help subject) | ||
(##help-hook subject)) | ||
|
||
(define-prim (help #!optional (subject (macro-absent-obj))) | ||
(macro-force-vars (subject) | ||
(##help (if (##eq? subject (macro-absent-obj)) help subject)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that this depends on so many things...
tr
,grep
,head
,cut
... It will be hard to port to another OS (e.g. Windows).Here's a wild idea (which I think you've had previously)... how about doing that processing in Scheme using the Gambit interpreter, which we know is installed? The only part of the script that is difficult is launching the browser (because the Gambit runtime system may not have a working implementation of
open-process
).However there is
(##os-shell-command cmd)
which uses the Csystem
function in the usual C-based runtime system. Seelib/gambit/process/process.scm
for details. This can be relied on to work on all operating systems with a shell (even Gambit compiled to Python and JavaScript, but only on top of nodejs, have an implementation of##os-shell-command
).Come to think of it I may be overly paranoid because
gambdoc.bat
is itself launched usingopen-process
.And at that point maybe the whole logic should be encapsulated in a Scheme module. I'm not sure how the "find browser" part would be implemented (and portably). There's still an argument to be made to launch a subprocess so that it doesn't interfere with the running Scheme process too much. On the other hand I think it is more valuable to do everything "in process" to minimize external dependencies (in particular it would be easy to get working with the web REPL that runs in an environment where subprocesses are not available, but opening a new web page is easy).
Would you like to prototype this? Perhaps a Scheme module called
_doc
or_help
that is builtin. The .tsv file could have been preprocessed to be an s-expression. It is best to read the file every timehelp
is called (i.e. not cache the database) so that the heap doesn't bloat permanently.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
How about
(gambit help)
?I chose the
.tsv
format because it's standard (emitted bymakeinfo
) while still being very simple. All you need to get the data as Scheme vectors isread-line
and thenstring-split
on tabs, 5-10 lines of code altogether.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note:
string-split
is in SRFI 13 which we'll be implementing anyway, andread-line
is in R7RS.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait,
string-split
is not actually in SRFI 13. It's in two of the newer string SRFIs. Might be good to add to(gambit string)
in any case.Here's a complete parser:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standard way of doing this in Gambit is
With SRFI 13 it is probably faster to do (untested code):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can work on adding an implementation of
string-split
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The following each define
string-split
, seemingly with mutually compatible signatures: