This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_engine/rhaibook/engine/metadata/definitions.md
2025-04-03 09:18:05 +02:00

185 lines
4.8 KiB
Markdown

Generate Definition Files for Language Server
=============================================
{{#include ../../links.md}}
Rhai's [language server][lsp] works with IDEs to provide integrated support for the Rhai scripting language.
Functions and [modules] registered with an [`Engine`] can output their [metadata][functions metadata]
into _definition files_ which are used by the [language server][lsp].
Definitions are generated via the `Engine::definitions` and `Engine::definitions_with_scope` API.
This API requires the [`metadata`] and [`internals`] feature.
Configurable Options
--------------------
The `Definitions` type supports the following options in a fluent method-chaining style.
| Option | Method | Default |
| ------------------------------------------------------------------- | --------------------------- | :-----: |
| Write headers in definition files? | `with_headers` | `false` |
| Include [standard packages][built-in packages] in definition files? | `include_standard_packages` | `true` |
```rust
engine
.definitions()
.with_headers(true) // write headers in all files
.include_standard_packages(false) // skip standard packages
.write_to_dir("path/to/my/definitions")
.unwrap();
```
Example
-------
```rust
use rhai::{Engine, Scope};
use rhai::plugin::*;
// Plugin module: 'general_kenobi'
#[export_module]
pub mod general_kenobi {
use std::convert::TryInto;
/// Returns a string where "hello there" is repeated 'n' times.
pub fn hello_there(n: i64) -> String {
"hello there ".repeat(n.try_into().unwrap())
}
}
// Create scripting engine
let mut engine = Engine::new();
// Create custom Scope
let mut scope = Scope::new();
// This variable will also show up in the generated definition file.
scope.push("hello_there", "hello there");
// Static module namespaces will generate independent definition files.
engine.register_static_module(
"general_kenobi",
exported_module!(general_kenobi).into()
);
// Custom operators will also show up in the generated definition file.
engine.register_custom_operator("minus", 100).unwrap();
engine.register_fn("minus", |a: i64, b: i64| a - b);
engine.run_with_scope(&mut scope,
"hello_there = general_kenobi::hello_there(4 minus 2);"
)?;
// Output definition files in the specified directory.
engine
.definitions()
.write_to_dir("path/to/my/definitions")
.unwrap();
// Output definition files in the specified directory.
// Variables in the provided 'Scope' are included.
engine
.definitions_with_scope(&scope)
.write_to_dir("path/to/my/definitions")
.unwrap();
// Output a single definition file with everything merged.
// Variables in the provided 'Scope' are included.
engine
.definitions_with_scope(&scope)
.write_to_file("path/to/my/definitions/all_in_one.d.rhai")
.unwrap();
// Output functions metadata to a JSON string.
// Functions in standard packages are skipped and not included.
let json = engine
.definitions()
.include_standard_packages(false) // skip standard packages
.unwrap();
```
Definition Files
----------------
The generated definition files will look like the following.
```rust
┌───────────────────────┐
general_kenobi.d.rhai
└───────────────────────┘
module general_kenobi;
/// Returns a string where "hello there" is repeated 'n' times.
fn hello_there(n: int) -> String;
┌──────────────────┐
__scope__.d.rhai
└──────────────────┘
module static;
let hello_there;
┌───────────────────┐
__static__.d.rhai
└───────────────────┘
module static;
op minus(int, int) -> int;
:
:
┌────────────────────┐
__builtin__.d.rhai
└────────────────────┘
module static;
:
:
┌──────────────────────────────┐
__builtin-operators__.d.rhai
└──────────────────────────────┘
module static;
:
:
```
All-in-One Definition File
--------------------------
`Definitions::write_to_file` generates a single definition file with everything merged in, like the following.
```rust
module static;
op minus(int, int) -> int;
:
:
module general_kenobi {
/// Returns a string where "hello there" is repeated 'n' times.
fn hello_there(n: int) -> String;
}
let hello_there;
```