GNU Emacs major modes for Racket: Edit and REPL.
Emacs Lisp Racket Makefile
Clone or download
Permalink
Failed to load latest commit information.
example Improve font-lock regexps for define; fixes #276 Sep 7, 2017
test Formatting Jun 16, 2017
.dir-locals.el Add .dir-locals Jun 2, 2017
.gitignore Fix .gitignore of .elc files Jul 20, 2014
.travis.yml Update .travis.yml through Emacs 26.1 and Racket 6.12 May 28, 2018
CONTRIBUTING.md Various updates to CONTRIBUTING.md Nov 8, 2015
README.md racket-program; closes #263 Jun 3, 2017
Reference.md Fix racket-here-string doc str; closes #295 Mar 13, 2018
THANKS.md Link to contributors Sep 13, 2017
channel.rkt Command I/O via sockets Oct 23, 2016
cmds.rkt Add racket-logger-mode; closes #109 Jun 13, 2017
defn.rkt Treat #%runtime as #%kernel; fixes #303 May 28, 2018
error.rkt Explain how to set db pkg catalogs; fixes #306 Jun 20, 2018
find-module-path-completions.rkt Use .dir-locals.el instead of file variables Jul 15, 2015
fresh-line.rkt Avoid flush-output on closed port. Apr 14, 2015
gui.rkt Use .dir-locals.el instead of file variables Jul 15, 2015
help.rkt racket-doc: Use net/url to encode url in find-help/mac (#268) Jun 7, 2017
image.rkt Use .dir-locals.el instead of file variables Jul 15, 2015
instrument.rkt Require Racket 6.0+ Oct 23, 2016
keywords.rkt Refresh types/builtins/keywords thru Racket 6.10 Sep 13, 2017
logger.rkt Fix stupid duplication in previous commit Aug 18, 2017
makefile Simplify indent Jun 2, 2017
mod.rkt Fix problems with module->namespace warning Sep 24, 2015
namespace.rkt Try to eval "skeleton" of file with error Sep 1, 2017
racket-bug-report.el racket-program; closes #263 Jun 3, 2017
racket-collection.el Various spring-cleaning Jun 16, 2017
racket-common.el Advise lisp-indent-mode and indent-sexp for paredit Sep 1, 2017
racket-complete.el OS-independent path compare; fixes #256 Apr 24, 2017
racket-custom.el Fix racket-here-string doc str; closes #295 Mar 13, 2018
racket-edit.el Only remove overlays created by racket-mode Apr 2, 2018
racket-font-lock.el Fix undesired font-lock of lambda; fixes #304 Jun 9, 2018
racket-imenu.el Update copyright through 2016 Aug 4, 2016
racket-indent.el Advise lisp-indent-mode and indent-sexp for paredit Sep 1, 2017
racket-keywords-and-builtins.el Refresh types/builtins/keywords thru Racket 6.10 Sep 13, 2017
racket-logger.el Fix racket-logger--item-rx Aug 18, 2017
racket-make-doc.el Deprecate racket-paren-face; closes #269 Jun 13, 2017
racket-mode.el Call syntax-propertize before hook; fixes #222 Jun 14, 2017
racket-ppss.el Simplify indent Jun 2, 2017
racket-profile.el Command I/O via sockets Oct 23, 2016
racket-repl.el Call syntax-propertize before hook; fixes #222 Jun 14, 2017
racket-tests.el Command I/O via sockets Oct 23, 2016
racket-unicode-input-method.el Add unicode for Union and Intersection. (#250) Jan 29, 2017
racket-util.el Ignore quoted module forms; fixes #275 Sep 2, 2017
run.rkt Don't use #lang at-exp; fixes #290 Nov 16, 2017
scribble.rkt Use test-case intead of comments Jun 16, 2017
try-catch.rkt Use .dir-locals.el instead of file variables Jul 15, 2015
util.rkt Command I/O via sockets Oct 23, 2016

README.md

Racket mode for GNU Emacs

Build Status MELPA

This provides a major mode to edit Racket source files, as well as a major mode for a Racket REPL. The edit/run experience is similar to DrRacket.

  • Focus on Racket.

    • Mode line and menu say Racket.
    • Omit stuff for various current and historical Schemes that's not applicable to Racket.
  • Use DrRacket concepts where applicable.

    • A simple and obvious way to "run" a file.
    • Allow interaction in the REPL, but the effect is wiped on the next run.
    • A simple way to run unit tests (to run the test submodule).
  • More thorough syntax highlighting ("font-lock"):

    • All Racket keywords, built-ins, self-evals, and so on.
    • All variations of define for functions and variables.
  • Correct indentation of Racket forms, including for/fold and for*/fold.

  • Compatible with Emacs 24.3+ and Racket 6.0+.

  • More.

Caveats

  • If you've used other Lisps and Schemes before, you might prefer Geiser, which is very sophisticated.

  • Although I dogfood this -- use it constantly to code Racket -- it is beta quality. My total experience writing Emacs modes consists of writing this mode.

  • Pull requests from smarter/wiser people are welcome.

  • Please report issues here, including the output from M-x racket-bug-report.

Install

The recommended way to use racket-mode is to install the package from MELPA. M-x package-install, racket-mode.

TIP: To use MELPA add the following to your ~/.emacs or ~/.emacs.d/init.el:

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/")
             t)

Minimal Racket

If you have installed the minimal Racket distribution (for example by using the homebrew recipe): racket-mode needs some additional packages (like errortrace and macro-debugger). A simple way to get all these packages is to install the drracket package:

$ raco pkg install drracket

Update

Be aware that Emacs package updates don't necessarily fully update Emacs' state. An example symptom is an "invalid function" error message. You might need to restart Emacs. In some cases, you might even need to:

  1. Uninstall racket-mode
  2. Exit and restart Emacs
  3. Install racket-mode

If you still experience a problem, please M-x racket-bug-report and submit an issue.

Configure

To start, there is only one variable you might need to set:

  • racket-program is the name or pathname of the Racket executable. It defaults to Racket.exe on Windows else racket.

On Windows or Linux, this default will probably work for you.

On macOS, downloading Racket doesn't add its bin directory to your PATH. Even after you add it, GUI Emacs doesn't automatically use your path (unless you use the handy exec-path-from-shell package). Therefore you may want to set racket-program to a full pathame like /usr/racket/bin/racket.

You can setq this directly in your Emacs init file (~/.emacs or ~/.emacs.d/init.el), or, use M-x Customize, as you prefer.

Key bindings

To customize things like key bindings, you can use racket-mode-hook in your Emacs init file. For example, although F5 and C-c C-k are bound to the racket-run command, let's say you wanted C-c r to be an additional binding:

(add-hook 'racket-mode-hook
          (lambda ()
            (define-key racket-mode-map (kbd "C-c r") 'racket-run)))

Unicode input method

An optional Emacs input method, racket-unicode, lets you easily type various Unicode symbols that might be useful when writing Racket code.

To automatically enable the racket-unicode input method in racket-mode and racket-repl-mode buffers, put the following code in your Emacs init file:

(add-hook 'racket-mode-hook      #'racket-unicode-input-method-enable)
(add-hook 'racket-repl-mode-hook #'racket-unicode-input-method-enable)

For more information, see the documentation: C-h f racket-unicode-input-method-enable.

Completion

The usual M-x complete-symbol -- bound by default to C-M-i -- works, drawing on all symbols in the current Racket namespace.

Tip: When you first visit a .rkt file, or edit it to change its requires, you may need to racket-run it to make the symbols available. Otherwise, you may get "stale" symbols, or just those from racket/base.

To have TAB do completion as well as indent, add the following to your Emacs init file:

(setq tab-always-indent 'complete)

This changes the behavior of Emacs' standard indent-for-tab-command, to which TAB is bound by default in the racket-mode edit and REPL modes.

Font-lock (syntax highlighting)

Font-lock (as Emacs calls syntax highlighting) can be controlled using font-lock-maximum-decoration, which defaults to t (maximum). You can set it to a number, where 0 is the lowest level. You can even supply an association list to specify different values for different major modes.

Historically you might choose a lower level for speed. These days you might do so because you prefer a simpler appearance.

Racket-mode supports four, increasing levels of font-lock:

0: Just strings, comments, and #lang.

1: #:keywords and self-evaluating literals like numbers, 'symbols, '|symbols with spaces|, regular expressions.

2: Identifiers in define-like and let-like forms.

3: Identifiers provided by racket, typed/racket, racket/syntax, and syntax/parse. (This level effectively treats Racket as a language, instead of a language for making languages.)

paredit

You may want to add keybindings to paredit-mode-map:

  • Bind { and } to paredit-open-curly and paredit-close-curly, respectively.

  • Bind whatever keys you prefer for paredit-wrap-square and paredit-wrap-curly.

smartparens

To use the default configuration that smartparens provides for Lisp modes generally and for racket-mode specifically, add to your Emacs init file:

(require 'smartparens-config)

eldoc

By default racket-mode sets eldoc-documentation-function to nil -- no eldoc-mode support. You may set it to racket-eldoc-function in a racket-mode-hook if you really want to use eldoc-mode with Racket. But it is not a very satisfying experience because Racket is not a very "eldoc-friendly" language. Although racket-mode attempts to discover argument lists, contracts, or types this doesn't work in many common cases:

  • Many Racket functions are defined in #%kernel. There's no easy way to determine their argument lists. Most are not provided with a contract.

  • Many of the interesting Racket forms are syntax (macros) not functions. There's no easy way to determine their "argument lists".

A more satisfying experience is to use racket-describe or racket-doc.

Documentation

Within Emacs, use the usual help functions.

  • Type C-h m to get help about the modes in effect for the current buffer, including a list of key bindings and commands.

  • To see help about a specific command, for example racket-run, type C-h f and then racket-run.

Here on GitHub you can browse the Reference.

Contributing

Pull requests are welcome! See CONTRIBUTING.md.

Background/Motivation

I started this project accidentally, while trying to figure out a font-lock issue with Quack under Emacs 24.2.

Knowing nothing about how to make a mode in Emacs, I tried to isolate the problem by making a simple major mode, then adding things until it broke. It didn't break and I ended up with this.

I took various .emacs.d hacks that I'd previously made to use with Quack, and rolled them into this mode.

Also, I'd recently spent time adding Racket fontification to the Pygments project, and wanted richer font-lock.

Also, I had experienced issues with enter! not always reloading modules in recent versions of Racket, and came up with a DrRacket-like alternative, run!.

Finally, I remembered that when I was new to Racket and Emacs, I got confused by the Scheme menu. It has options that work with various Schemes over the years, but which are N/A for Racket. I would stare it and wonder, "Um, how do I just 'run my program'??". I figured a fresh focus on Racket might be helpful, especially for other folks transitioning from using DrRacket.

Update, Jan 2014: After I had used this for a long time, putting up with its quirks, someone put it on MELPA. That nudged me to take another look, learn more about Elisp and Emacs modes, and improve it. Although I still feel like an amateur, it has probably improved from alpha to beta quality.

Please see the Acknowledgments.