1 DrRacket support for #lang-based Languages
The simplest and best way to extend DrRacket with support for a new language is to implement the language via #lang (see Defining new #lang Languages for more details). DrRacket will then use read-language to find code and values that it uses to customize itself to the language.
If the call to read-language raises an error, DrRacket logs the error at the debug level to a logger with the name 'drracket-language (see Logging for more about how to follow specific loggers).
With the exception of the 'definitions-text-surrogate, if there is an error during a use of one of these extensions, DrRacket notices the error and removes all of the extensions for the language. It also shows the error at the bottom of the DrRacket frame (prefixed by #lang). Note that this applies only to errors that occur during the dynamic extent of a use of one of these extensions. If an extension were to, for example, create a new thread that (eventually) caused an error, DrRacket would not notice that error and would not remove the extensions.
When experimenting with changes to these extensions, use the Racket|Reload #lang extensions menu item to cause DrRacket to remove the extensions and reload the implementations from the files on disk.
DrRacket calls the language’s read-language’s get-info procedure with the following key arguments:
1.1 Syntax Coloring
When a language’s get-info procedure responds to 'color-lexer, it is expected to return a procedure suitable to pass as the get-token argument to start-colorer.
1.2 Indentation
Added in version 1.3 of package drracket.
1.3 Keystrokes
The procedure’s first argument will be the definitions text, the second will be the event object supplied from the GUI system and the result of the procedure is ignored.
1.4 Filename Extensions
When a language’s get-info procedure responds to 'drracket:default-filters, it is expected to return (listof (list/c string? string?)).
`(["Racket Sources" "*.rkt;*.scrbl;*.rktl;*.rktd;*.ss;*.scm"] ["Any" "*.*"])
Added in version 1.2 of package drracket.
When a language’s get-info procedure responds to 'drracket:default-extension, it is expected to return (and/c string? (not/c #rx"[.]")); the result is used as the default extension when saving files by setting finder:default-extension.
Added in version 1.2 of package drracket.
1.5 REPL Submit Predicate
For backwards compatibility reasons, DrRacket also queries the result of module->language-info for 'drracket:submit-predicate. It does this during the evaluation of the definitions (so the Racket|Reload #lang extensions menu item does not trigger a re-load). If the submit predicate is specified both ways, then the predicate supplied via read-language takes precedence.
Changed in version 1.5 of package drracket: Look for drracket:submit-predicate via read-language.
1.6 Show big “Definitions” and “Interactions” labels
If the read-language predicate returns #t for 'drracket:show-big-defs/ints-labels, then DrRacket shows the words “Definitions” and “Interactions” in a large font in the corresponding windows. This is intended as a help for students who are reading instructions about where to type their programs but might not have internalized this particular bit of DrRacket terminology.
1.7 Opting out of Standard Toolbar Buttons
Some of the built-in buttons in the DrRacket button bar at the top of the window can be disabled on a per-language basis. DrRacket will invoke the get-info proc returned by read-language with 'drracket:opt-out-toolbar-buttons (and 'drscheme:opt-out-toolbar-buttons for backwards compatibility).
If the result is a list of symbols, the listed symbols are opted out. If the result is #f, all buttons are opted out. The default is the empty list, meaning that all opt-out buttons appear.
The Check Syntax button uses the symbol 'drracket:syncheck; the debugger uses the symbol 'debug-tool and the macro stepper uses 'macro-stepper.
Plugins may add more opt-out buttons via drracket:module-language-tools:add-opt-out-toolbar-button.
1.8 Opting in to Language-Specific Toolbar Buttons
Like drracket:opt-out-toolbar-buttons, but for languages to opt in to buttons that are not enabled by default.
Added in version 1.6 of package drracket.
1.9 Adding New Toolbar Buttons
DrRacket queries the result of read-language to determine if there are any new toolbar buttons to be used when editing files in this language.
(or/c (listof (list/c string? (is-a?/c bitmap%) (-> (is-a?/c drracket:unit:frame<%>) any) (or/c real? #f))) #f)
If the result is #f, then no toolbar buttons are created.
To implement functionality similar to the Run button, call the execute-callback method. You may also want to use the drracket:rep:after-expression parameter.
If 'drracket:toolbar-buttons is not recognized, DrRacket will also pass 'drscheme:toolbar-buttons; this is for backwards compatibility and new code should not use it. Similarly, if the fourth element from the list (the argument to #:number) is not present, then it is treated as #f.
1.10 Definitions Text Surrogate
Using a #lang-specific definitions text surrogate is a very powerful way to flexibly control DrRacket’s behavior when a new language is installed. It is also easy to cause DrRacket to completely misbehave with this form of extension. It is here only when one of the other forms of extension listed above are not sufficient for the kind of extension your language requires. And even in that case, it is preferable to add something to this list that is more easily controlled in the case of errors, using the definitions text surrogate only until that more easily controlled extension has been added to DrRacket.
DrRacket calls read-language’s get-info procedure with 'definitions-text-surrogate and expects it to return a value matching the contract (or/c #f module-path?), which is then passed to dynamic-require together with 'surrogate%. The result is expected to be a class implementing the interface racket:text-mode<%> (presumably derived from racket:text-mode%. That mode is installed into the definitions text, where it can change its behavior by changing how is responds to any of the methods in the mode.
One consequence of this power is that errors that happen during the dynamic extent of calls into the mode are not trapped (much as errors that occur on newly created threads are not trapped, as described in the introduction to this section).