CeleritasCelery / rune

Rust VM for Emacs
GNU General Public License v3.0
404 stars 22 forks source link

[[https://rune-rs.netlify.app/rune/][Docs]]

This project is an experimental Emacs core written in Rust. The project is still at a very early phase but has the following goals:

See the [[file:design.org][design doc]] for more details. ** Status The current goal of this project is to create an editor MVP. We have a basic elisp runtime, and we are working on adding basic editing functionality in a minimal GUI. This will include:

If you want to contribute or have ideas for things to add, please open an [[https://github.com/CeleritasCelery/rune/issues/new][issue]]. ** lisp Lisp files are currently pulled from

https://github.com/emacs-mirror/emacs/tree/emacs-29.1/lisp

Any modification for bootstrapping contain the tag ~RUNE-BOOTSTRAP~.

** Running The easiest way to run the interpreter is with ~cargo run --profile=release~. Running with the load argument (~-- --load~) will load the bootstrapped elisp and then exit. Running with the repl argument (~-- --repl~) will open an elisp repl. Running with both arguments (~-- --load --repl~) will load the elisp and then open the repl. Running with no arguments is equivalent to ~--load~.

*** MIRI Run the test suite with MIRI

+begin_src sh

MIRIFLAGS='-Zmiri-strict-provenance' cargo +nightly miri test

+end_src

** Exploring this repo The project is defined by a main package =rune=, which depends on the crates included in the =crates= directory. One of those is the =rune-macros= crate, which defines the ~defun~ proc macro for defining builtin functions. The rest of the code is contained in ~src/~. The modules are described below.

** Contributing See the [[file:architecture.org][architecture]] doc for more info on the structure of Rust Emacs internals.

This project is moved forward by trying to load new elisp files and seeing what breaks. The best way to do that is with ~cargo run~, which will load the currently bootstrapped files. The bootstrapped files are located in [[file:src/main.rs][main.rs]] as part of the ~load~ function.

Usually what is needed is to implement more primitive functions. This is done with the [[file:rune-macros/lib.rs][defun]] macro. For example, if we wanted to implement the ~substring~ function, we would first look at the lisp signature.

+begin_src lisp

(substring STRING &optional FROM TO)

+end_src

Then we would translate the types to their Rust equivalent. If the correct type is not known we can use ~Object~. In this example we would write our Rust signature as follows:

+begin_src rust

[defun]

fn substring(string: &str, from: Option, to: Option) -> String {...}

+end_src

If you run with ~cargo run -- --load --repl~ that will load the current bootstrapped files and then open the REPL. From there you can run ~(load "/path/to/elisp/file.el")~ to try loading a new file. Files that are not bootstrapped are not yet included in this repo, but are part of [[https://github.com/emacs-mirror/emacs][Emacs]]. Once the file is bootstrapped it can be added to the [[file:lisp/][lisp directory]].

** Blog posts