| title | Register your language |
|---|---|
| sidebar_position | 2 |
Start a new VScode extension for your language
We assume you have already written a ((ParsingService)) function. Now think of:
- a name for your language;
- a file extension for its files.
With the following shell commands you register your language with the IDE:
```rascal-module
module MyLanguageServer
import util::LanguageServer; // <1>
import demo::lang::Pico::Syntax; // <2>
start[Program] myParsingService(str s, loc l) { // <3>
return parse(#start[Program], s, l);
}
// highlight-start
set[LanguageService] myLanguageServices() { // <4>
parser(myParsingService);
}
// highlight-end
void main() { // <5>
// highlight-next-line
registerLanguage( // <6>
// highlight-next-line
language( // <7>
pathConfig(), // <8>
"Pico", // <9>
{"pico"}, // <10>
"MyLanguageServer", // <11>
"myLanguageServices" // <12>
)
) ;
}
- Load the LSP API we need later
- Load the ((Rascal:SyntaxDefinition)) needed for our ((ParsingService))
- Define a ((ParsingService)) (could also be already define in the imported module)
- Collect all relevant language services. The function must not have positional parameters and return a
set[LanguageService]. You can keep adding new services here to the set, and keep the other code the same. - Having a
mainfunction is not obligatory, but when you deploy the extension later as an independent extension you will need it anyway. - The call to ((registerLanguage)) does the final job of extending the current IDE with your own extension. A whole new Rascal runtime environment will be started just for your extension. Modules will be loaded, and the services will be connected to LSP callbacks, etc.
- The ((util::LanguageServer-language)) constructor provides five pieces of meta data:
- ((util::PathConfig::pathConfig)) is used to configure the Rascal runtime environment for loading your services. This comes in handy when you have third-party dependencies.
- This is the UI facing name of your language.
- These are the file extensions that activate the current IDE extension.
- This is the top module to import into the Rascal runtime environment for this extension.
- This is the name of the function in the top module which provides a
set[LanguageService]when called with no arguments.
Then you simply call main() and you can open an editor with the file extension pico.
The first time the parser will be generated and cached, and when it is finished ((SyntaxHighlighting)) will show you the success of the parse.
That's it!
Now you can continue, for example, with ((SyntaxHighlighting)) or ((HoverService)) as two of the ((LanguageServerProtocol)) features to try out.
- repeated calls to ((registerLanguage)) re-initialize your language extension from scratch
- language extensions are not refreshed automatically if you change their implementation. You have to keep calling ((registerLanguage)) for this
- (Accidental) console output, logging and unexpected error messages appear in VScode
OUTPUTtabs, but these tabs are not automatically floating to the top. It's better to debug your services in the terminal.