These Weeks in Remacs II


It’s been six months since the last Remacs update, and many new features have landed!

Community

We now have a Gitter chat room! Do drop by if you have any questions or wish to discuss Remacs. There’s a low traffic Remacs Subreddit too.

We’ve added @jeandudey and @birkenfeld to the GitHub collaborators, bringing us to five fine people who can approve your pull requests.

Elisp Features

We’re still tracking upstream GNU Emacs master, so new features there are landing in Remacs (1, 2).

We’ve added a lot new elisp primitive functions:

Strings: characterp, multibyte conversions (1, 2, 3), and comparisons

Vectors: type definitions, functions

Buffers: type definitions, functions

Symbols: various functions

A much requested feature, adding Rust support to find-function, has been added. This was an unusual PR as it includes some elisp changes in Remacs.

We now have documentation on our compatibility with GNU Emacs. This covers all known implementation differences, platform support differences, and describes how to detect Remacs in elisp code.

Cleanup

Platforms: We’ve dropped MS-DOS support. The Remacs build has been fixed on 32-bit Linux and 32-bit macOS.

The codebase has been split out:

  • remacs-lib (Rust equivalents of gnulib)
  • remacs-sys (type definitions of Emacs types and C functions)
  • remacs-macros (procedural macros supporting elisp primitive functions in Rust)
  • src (Rust implementation code of elisp)

Signal name mapping is pure Rust code.

We now run rustfmt on every PR.

If you fancy building Remacs without installing a dev toolchain (compilers, C libraries etc), there’s now a docker-compose.yml to make your life easy.

Macros

It wouldn’t be a proper lisp project without some macro magic.

After several PRs and discussions, Remacs now includes a procedural macro to simplify defining elisp functions in Rust.

For example, here’s vectorp:

/// Return t if OBJECT is a vector.
#[lisp_fn]
fn vectorp(object: LispObject) -> LispObject {
    LispObject::from_bool(object.is_vector())
}

Leveraging Rust

Remacs now uses Rust crates for SHA-1 and SHA-2, and for base64 encoding. We’ve even replaced some C bit-counting functions with functions from the Rust stdlib.

Rust has also enabled us to mark Emacs functions with the ! type, a neat Rust feature that marks functions as not returning.

The #[repr(transparent)] Rust RFC has been approved, so we’re looking forward to using that in Remacs. In the meantime, Remacs has a LispObject type for use in Rust, and a CLisp_Object type for FFI compatibility.

Remacs also takes advantage of the user-defined allocators RFC, which has been approved too. We’re now up-to-date with the new API.

Phew!

There’s still lots to do on Remacs: many small elisp functions to port, or larger projects to sink your teeth into. We also welcome incomplete pull requests: many of the PRs shown here have been built on top of initial implementations written by other contributors.

Join the fun at: https://github.com/Wilfred/remacs

Recent Posts

Difftastic, the Fantastic Diff

The Siren Song of Little Languages

How High Are Your Tests?

Helpful: One Year On

The Emacs Guru Guide to Key Bindings