------------------------

Harvey Mudd College
Computer Science 131
Programming Languages
Spring Semester 1998

Emacs Mode for SML-NJ

------------------------

This document describes the use of sml-mode to support SML programming, specifically on the host turing.cs.hmc.edu.

------------------------

Index

------------------------

Overview

If you program in SML, you may wish to know about a package for Emacs that provides some additional functionality for SML programmers. The package is called sml-mode and it provides the following features:

------------------------

SML-mode setup

To set-up sml-mode on Turing, you should just add this single line to your .emacs file:

(load "/usr/local/sml/sml-mode/sml-mode-setup")

Your .emacs file should reside in your home directory. If you already have a .emacs, just add the above line to the end of that file. If you don't have a .emacs, simply create it, making the above line the sole contents.

Note: CS-131 users should use: (load "/cs/cs131/sml-mode/sml-mode-setup-cs131") instead.

------------------------

Sending code to SML

Emacs has the ability to communicate with other programs, displaying the results in a standard buffer. SML-mode uses this capability to communicate with a SML process so that you can send sections of code to the SML process. The SML process will compile the code, just as it normally would, and display the output.

Entire buffer

To send the entire buffer to SML, you can use the (sml-save-buffer-use-file) command, bound to "C-c C-u" by default. As the function name implies, this will save your buffer and then use the SML "use" command to read in the file.

Single function

If you are working on a particular function, you can have SML compile that function by using the (sml-send-function) command, bound to "C-c C-c" by default. Note that this command requires the function be terminated by a trailing semicolon; otherwise, you will have to change to the SML inferior process and enter a semicolon manually.

Arbitrary region

You can also define arbitrary regions of code to send to SML, using (sml-send-region), on "C-c C-r". Note that (sml-save-buffer-use-file) and (sml-send-function) are logically just special cases of (sml-send-region). You should be aware that they are implemented slightly differently, though.

To define a region in Emacs, first move the cursor (also called the point) to the beginning (or the end) of the region, and execute the function (set-mark-command), bound to "M-SPC" or "C-x SPC". (The "M-" means "meta"; if you don't have a meta key on your keyboard, you can use the escape key instead.) This operation is called "setting the mark". It fixes one end of the region, so that the region is now defined as all the text between the "mark" and the "point". So, move the point to the other end of the region and execute (sml-send-region), and all the text between the point and the mark will be sent to the SML process.

------------------------

Finding errors

You may have noticed that it is often the case that you will get an error when you compile some code in SML. SML-mode makes your life easier by allowing you to jump straight to where the error(s) occured. The function is called (sml-next-error) and it is bound to "C-c '" (that's a single quote) by default.

So, to use this feature, send some code to the inferior SML process, using any of the functions described above. When a compile error occurs, simply execute (sml-next-error) and Emacs will parse the SML compiler output and move your cursor directly to the location of the compile error. When you are done, execute (sml-next-error) again, and sml-mode will jump to the next error.

Note: This feature doesn't appear to work with (sml-send-function); I'd recommend using (sml-send-region) instead.

------------------------

Interacting with the SML process

If you would like to interact directly with the SML process, instead of just sending code to it, use (sml-pop-to-shell), bound to "C-c C-s" by default. Executing this command will place you in an Emacs buffer which is connected directly to the SML process. You can move around the buffer as you would any Emacs buffer, but if you press return, the text you have typed will be sent to the SML process.

In addition, all the normal Emacs shell commands are available. If you don't know what those are, this is not the place to describe them all, but you should at least know about (comint-previous-prompt), bound to "M-p". This will revisit the last thing you entered, allowing you to edit it if you'd like, and enter return to send it to SML again.

If you do all your interaction with SML within this inferior shell, it will be trivial for you to obtain copies of sessions; simply cut and paste from this buffer.

If you are not already an Emacs guru, you may not be familiar with working with multiple windows within Emacs. To switch between windows, use (other-window), bound to "C-x o". To remove the current window from the display (thereby reducing the number of windows displayed by one), use (delete-window), bound to "C-x 0" (that's a zero).

------------------------

Automatic indentation

Since sml-mode knows the standard SML coding style, it should automatically take care of indentation for you, as long as you're even vaguely following the standard style. There are also two commands to recalculate indentation. The first operates only on the current line: (sml-indent-line) bound to TAB by default. The second operates on a region: (sml-indent-region), bound to "C-c TAB" by default. For a discussion of defining a region, see the section on sending arbitrary regions of text to SML.

------------------------

Typing shortcuts

To make the programmer's life easier, sml-mode provides some shortcuts for commonly used constructs.

Special constructs

A variety of special constructs are available via the command (sml-region), bound to "C-c RET". The constructs available include:

To use this feature, run the (sml-region) command. Emacs will ask you (in the minibuffer), for the "region to insert". For a complete list of possibilities, hit TAB at this point. Enter enough characters to uniquely identify the construct and press return.

Pipes and cases

In situations where a pipe character is appropriate (either in function definitions or cases, sml-mode can automatically insert it for you. For instance, say you were writing a function and had gotten as far as:

fun length nil count = count

Now, if on a line after this, you were to execute (sml-electric-pipe), your code would now look like:

fun length nil count = count
| length

freeing you from typing the "| function_name" every time.

Similarly, if you are coding a case statement, (sml-electric-pipe) will insert both the pipe character and the "=>" construct for you.

(sml-electric-pipe) is bound to "M-|" by default.

------------------------

Getting help

As with all Emacs modes, sml-mode provides some limited on-line documentation. If you forget what commands or available or the keys they are bound to by default, type "M-h m" (remember that this is equivalent to "ESC h m").

There is no further documentation available besides this document and the source code to sml-mode.

------------------------

Customization

Since sml-mode is written in Emacs-Lisp, it is rather customizable. There are also a number of features I haven't mentioned. The full source is also available, so you can hack on it to your heart's content. However, I'm not going to engage in a full discussion of elisp programming here. My advice would be to read the source code ("sml-mode.el") for more details. The various variables that you can change are documented there.

------------------------

This page was last updated by hodas@cs.hmc.edu on Sun, Feb 22, 1998 at 2:11:57 PM. © copyright 1996 Joshua S. Hodas. All rights reserved.