Declaring a Module
Each dynamic module must have an initialization function, marked by the attribute macro #[emacs::module]
. The function's type must be fn(&Env) -> Result<()>
.
In addition, in order to be loadable by Emacs, the module must be declared GPL-compatible.
# #![allow(unused_variables)] #fn main() { emacs::plugin_is_GPL_compatible!(); #[emacs::module] fn init(env: &Env) -> Result<()> { // This is run when Emacs loads the module. // More concretely, it is run after all the functions it defines are exported, // but before `(provide 'feature-name)` is (automatically) called. Ok(()) } #}
Options
-
name
: By default, the name of the feature provided by the module is the crate's name (with_
replaced by-
). There is no need to explicitly callprovide
inside the initialization function. This option allows the function's name, or a string, to be used instead.# #![allow(unused_variables)] #fn main() { // Putting `rs` in crate's name is discouraged so we use the function's name // instead. The feature will be `rs-module-helper`. #[emacs::module(name(fn))] fn rs_module_helper(_: &Env) -> Result<()> { Ok(()) } #}
-
defun_prefix
andseparator
: Function names in Emacs are conventionally prefixed with the feature name followed by-
. These 2 options allow a different prefix and separator to be used.# #![allow(unused_variables)] #fn main() { // Use `/` as the separator that goes after feature name, like some other packages. #[emacs::module(separator = "/")] fn init(_: &Env) -> Result<()> { Ok(()) } #}
# #![allow(unused_variables)] #fn main() { // The whole package contains other Lisp files, so the module is named // `tree-sitter-dyn`. But we want functions to be `tree-sitter-something`, // not `tree-sitter-dyn-something`. #[emacs::module(name = "tree-sitter-dyn", defun_prefix = "tree-sitter")] fn init(_: &Env) -> Result<()> { Ok(()) } #}
-
mod_in_name
: Whether to put module path in function names. Default totrue
. This can also be overridden for each individual function, by an option of the same name on#[defun]
.
Note: Often time, there's no initialization logic needed. A future version of this crate will support putting #![emacs::module]
on the crate, without having to define a no-op function. See Rust's issue #54726.