2
1
Fork
You've already forked schemacs
0
A clone of Emacs and Emacs Lisp written in Scheme
  • Scheme 55.5%
  • Emacs Lisp 43.7%
  • HTML 0.5%
  • Makefile 0.2%
2025年12月20日 14:35:43 +02:00
.wiki @31c254d02d add Code of Conduct (Contributor Covenant 3.0) 2025年12月07日 23:39:08 +09:00
chibi HUGE COSMETIC CHANGE: rid all library defs of "include" statements 2025年11月12日 17:31:15 +09:00
elisp pull 3 more GNU Emacs source files into this tree 2025年02月27日 15:04:41 +09:00
rapid HUGE COSMETIC CHANGE: rid all library defs of "include" statements 2025年11月12日 17:31:15 +09:00
schemacs Fix typo. 2025年12月20日 14:35:43 +02:00
slib improve Makefile for Chicken, install '(chibi match)' via Akku 2025年11月13日 00:53:30 +09:00
.dir-locals.el include Emacs .dir-locals.el 2024年11月14日 02:02:44 +09:00
.gitignore modify build scripts to support Chez Scheme via Akku-R7RS 2025年05月22日 12:46:37 +09:00
.gitmodules make the wiki a submodule of the main repo 2024年11月14日 00:01:04 +09:00
Akku.manifest improve Makefile for Chicken, install '(chibi match)' via Akku 2025年11月13日 00:53:30 +09:00
build.scm move cond-expand logic that selects matcher into (schemaces match) 2025年05月22日 12:46:37 +09:00
CONTRIBUTING.md add Code of Conduct (Contributor Covenant 3.0) 2025年12月07日 23:39:08 +09:00
elisp-tests.scm implement fold algorithm over syntax tree 2025年12月11日 01:20:50 +09:00
guile.sh squash all commits and make this repo public 2024年11月13日 23:06:24 +09:00
LICENSE squash all commits and make this repo public 2024年11月13日 23:06:24 +09:00
main-guile.scm rename "gypsum" to "schemacs" in all source files and documentation 2025年05月13日 02:54:54 +09:00
main.scm fix bugs in various library decalarations 2025年05月18日 02:36:36 +09:00
Makefile improve Makefile for Chicken, install '(chibi match)' via Akku 2025年11月13日 00:53:30 +09:00
manifest_guile-gi.scm include "guile-readline" into the Guix manifest. 2025年12月08日 08:42:53 +09:00
README.md corrected minor typeos in README 2025年12月08日 08:56:44 +09:00
run-tests.scm rename "gypsum" to "schemacs" in all source files and documentation 2025年05月13日 02:54:54 +09:00

Project Schemacs

A clone of Emacs and Emacs Lisp written in R7RS Scheme

Project Goals

Although this project is still incomplete and experimental, the goals of this project are to construct a Scheme app platform similar to Emacs, not just in the UI/UX, but also to be backward compatible (to the greatest degree possible) with GNU Emacs by implementing an Emacs Lisp interpreter as well.

  • written in portable R7RS Scheme, should run on any compliant Scheme implementation.
  • able to run your init.el, run Emacs software pulled from ELPA.
  • use Emacs Regression Tests (ERT) from GNU Emacs to ensure compatibility.
  • encourage the use of the Scheme programming language to develop apps and text editing workflows.

Sub-goals

  • contribute patches upstream to the Guile Scheme Emacs Lisp compiler
  • provide a cross-platform GUI library like Racket/GUI or McCLIM
  • be able to develop Schemacs from within it's own editor, create pull requests in Git.

The Wiki

The wiki documents several of the important libraries in this source code.

How to help contribute code

Code of Conduct

We respectfully ask all contributors to this project adhere to the principles stated in the Code of Conduct (CoC), so please be sure you read and understand this agreement before asking to contribute. The CoC is currently based on the Contributor Covenant 3.0 Code of Conduct.

First steps toward contributing to Schemacs

There are many tasks to complete, many of which are fairly simple to do even for people with not a lot of experience using the Scheme programming language, as long as you can get the code in this project to run on your Scheme implementation. See the "How to build", "How to run", and "How to hack" sections below.

As of right now, the most important long-term issue to work on is #30 "Get Emacs Regression Tests (ERT) to evaluate on the cl-lib.el". Please refer to that issue for details, but briefly here is what must be done: first try running the elisp-tests.scm test program in your Scheme REPL...

(load "./elisp-tests.scm")

...if an error occurs, it will print the Emacs Lisp form that caused the error. Since the test programs run by elisp-tests.scm all work perfectly well in GNU Emacs Lisp, any error in Schemacs while evaluating these tests is an implementation bug that must be corrected.

If you find a bug, check if has already been recorded in the list of open issues, and if anyone is already assigned to working on it. If it is unassigned, please comment on the issue that you would like to begin working on a patch! You may also open a new issue if the bug seems not to have been recorded yet, but please wait until you receive a reply from the maintainers on your issue before starting work on a patch to make sure you don't end up duplicating the work of others.

If you want to contribute, but are not interested in working on the Emacs Lisp interpreter part of the Schemacs project, please feel free to contact the author (contact details on Codeberg.org) after reading through the list of open issues, or reading over the feature wish list document.

How to build

As of right now, this project only runs on Guile Scheme, although certain libraries (lens.sld, pretty.sld, keymap.sld) can build and run on other Schemes. The only GUI available right now is for Guile-GI, but the Editor is designed specifically to be able to run on other Scheme platforms with other GUI toolkits. All platform specific calls are parameterized.

Scheme Requirements

  • Guile 3

  • Guile-GI must be built and installed in a directory path that is listed in the %load-path.

C Requirements for Guile-GI

  • libglib
  • libgio
  • libgdk
  • libgtk3

Guile 3 usually installs from source using autotools on any Linux or BSD operating system provided the above developer dependency packages are installed. Installing with autotools installs all Guile modules in the site-local package directory. If you install it this way, the modules are always available to your Guile runtime without needing to set the Guile %load-path.

(Optional) use Guix

The manifest_guile-gi.scm file is provided to install development dependencies into your local Guix installation. Use it in one of two ways.

  1. The first way is to use the guix shell command, which keeps package dependencies locally and temporarily (until you run the Guix garbage collector). The full command is this:

     guix shell -m ./manifest_guile-gi.scm -- guile --r7rs ;
    
  2. The second way is to installing packages in a local profile directory. Python programmers may find this workflow more familiar, as it is similar to using a Python venv or "virtual environment", except the package directory is ./.guix-profile rather than .venv.

     guix package -p ./.guix-profile -m ./manifest_guile-gi.scm -i ;
     guix shell -p ./.guix-profile -- guile --r7rs -L "${PWD}" ;
    

    And then, when you see the Guile REPL prompt scheme@(guile-user)> you can run the Scheme programs.

    Furthermore, the guix shell command can use the profile directory, and the package dependencies installed into the profile directory will survive Guix garbage collections.

Launch the Guile REPL using ./guile.sh

The guile.sh script sets environment variables and command line parameters for the Guile runtime, it is usually easier to simply execute this script to start the REPL.

Emacs users can set the directory-local variable geiser-guile-binary to "./guile.sh". The .dir-locals.el file in this repository does this for you if you choose to use it.

(optional) Launch guile.sh in a Guix Shell

If you are using Guix Shell according to the steps in the section "(Optional) Use Guix", you can run the guile.sh script like so:

guix shell -p ./.guix-profile -- sh ./guile.sh

How to run

Once you have a Guile Scheme REPL running and you can see the scheme@(guile-user)> prompt, and you are sure the Guile-GI dependencies available in the %load-path, simply load the main program into the REPL:

(load "./main-guile.scm")

This will rebuild and launch the executable. If you are using the ./guile.sh script to start the REPL, note that the --fresh-auto-compile flag is set, and so recompilation will occur every time main-guile.scm is loaded. If you are not hacking the Schemacs source code, feel free to delete this flag from the guile.sh script file so that load only builds the application once, and launches the application more quickly.

Double-check the Guile %load-path

If you evaluate ,pp %load-path in the scheme@(guile-user)> REPL, the load path should look something like this:

scheme@(guile-user)> ,pp %load-path
1ドル = ("/home/user/work-src/schemacs"
 "/usr/share/guile/3.0"
 "/usr/share/guile/site/3.0"
 "/usr/share/guile/site"
 "/usr/share/guile")

Double-check the Guile %load-path in a Guix Shell

If you evaluate ,pp %load-path in the scheme@(guile-user)> REPL that was launched within a Guix Shell, the load path should look similar to this, although likely with different hash codes in the /gnu/store:

scheme@(guile-user)> ,pp %load-path
1ドル = ("/home/user/work-src/schemacs"
 "/gnu/store/ylbycmajc0sf1pndfnsfql76cr1097iq-profile/share/guile/site/3.0"
 "/gnu/store/jqrkacxgsaf7b19xqzc2x4d77v27dbc6-guile-3.0.8/share/guile/3.0"
 "/gnu/store/jqrkacxgsaf7b19xqzc2x4d77v27dbc6-guile-3.0.8/share/guile/site/3.0"
 "/gnu/store/jqrkacxgsaf7b19xqzc2x4d77v27dbc6-guile-3.0.8/share/guile/site"
 "/gnu/store/jqrkacxgsaf7b19xqzc2x4d77v27dbc6-guile-3.0.8/share/guile")

How to hack

Start a Scheme REPL as described above, but instead of running the main program or the ./elisp-tests.scm program, instead run the test suite:

(load "./run-tests.scm")

Unlike the ./elisp-tests.scm program, the ./run-tests.scm ensures the exported symbols in each library all behave as expected. Before you change anything, make sure you keep a log of which tests have passed and which have failed, if any.

Whenever you make a change to the source code of a Scheme library, be sure to run the tests for that library. The tests in ./run-tests.scm require your Scheme implementation to provide SRFI-64, without this language extension (sorry, MIT Scheme users) you will have to run each test case by hand by copy-pasting each test form into your REPL.

Keep in mind that this project is still experimental, it is possible some of the tests may not pass. As long as you create a pull request with equal or fewer passing tests, your request is more likely to be pulled into the main branch.

That said, ./schemacs/lens.scm and ./schemacs/keymap.scm should always pass all tests, as these libraries are most essential to the rest of the application.

Lenses

R7RS Scheme does not standardize any Meta-Object Protocol (MOP) implementation, not even in the R7RS "Large" standard.

Schemacs has been written such that there no need for any MOP implementation. Rather, a "function lenses" implementation written in pure R7RS-Small compliant code is provided as a library. Functional lenses are inspired by Haskell, and are a way of defining getter and setter functions that can be composed together.

Conventionally, lens definitions are prefixed with the => symbol. They may also be suffixed with *! or ! whether a lens is canonical and/or whether a lens mutates the data structure when updating it. For example, the (schemacs editor) library exports symbols such as =>editor-buffer-table*! or =>buffer-local-keymap*!.

Since it is usually much easier to use lenses rather than getters and setters, many Schemacs libraries export their own lenses for working with the record types provided within.

Lenses are useful enough to be separated into it's own separate source code package. See the documentation for Functional Lenses in its own source code repository.

Platform-independent record types

Record types that contain platform specific information are usually exported as lenses, and are usually named =>*-view, for example =>buffer-view and =>window-view. These are fields that contain references to platform-specific data needed by the platform in order to render the view of a "buffer" or "window."

Other resources

Contributors welcome!

This is a large and ambitious project, but there seems to be a lot of interest in both the Emacs and Scheme communities for an Emacs clone written in Scheme. Our job is to coordinate everyone's efforts, and to make it as easy as possible for anyone to contribute. Please feel free to get in touch with us, we want to help you contribute code.

If you would like some ideas on how to contribute, a good place to start is to read our feature wish list document.

Also check out issue #30 "Get Emacs Regression Tests (ERT) to evaluate on the cl-lib.el" if you would like to try contributing to the Emacs Lisp interpreter part of this project.