Emacs Integration
To improve the development experience, it is useful to integrate Storm and Mymake into your editor or IDE. Currently, the Storm repository only contains pre-made solutions for integrating Storm with Emacs. This is, of course, possible to do with other editors as well based on the information available on this side, but no pre-made solutions exist yet. Please contact me if you have developed integrations with other editors, or are interested in doing so.
The Emacs integration is able to provide the following functionality:
- Jumping to the location associated with error messages.
- Accessing the built-in documentation in Storm.
- Providing syntax highlighting for all languages in Storm.
- Easy compilation with Mymake.
Each of these are explained in more detail in separate sections below the description of how the plugin is installed.
Installing the Plugin
To use the functionality mentioned above, you need to load the Storm plugin into Emacs. The plugin
is distributed in the binary releases of Storm provided on the webpage as storm-mode.el
, or in the
source repository as Plugin/emacs.el
.
Loading the Plugin
To use the Emacs integration for anything, you must first load the plugin. To do this, open the file
~/.emacs
and add the following to the end of it (replace the path with the actual path to the
storm-mode.el
file):
(load "~/storm/storm-mode.el")
To apply the changes, either place the cursor at the end of the line and press C-M-u
, or restart
Emacs. If you only wish to jump to errors (step 1 above), this is all the setup of the plugin you
need. You might, however, wish to look at the section on syntax highlighting below to make it more
convenient to edit Basic Storm code.
Configuring the Plugin
If you wish to access the built-in documentation in Storm, or wish to use the language server, you
must also tell the plugin where Storm is located, and where the root of the name tree is located.
This is done by setting the variables storm-mode-compiler
and storm-mode-root
. To do this, add
the following to the end of the ~/.emacs
file:
(setq storm-mode-compiler "~/storm/storm") (setq storm-mode-root "~/storm/root")
The paths in the lines above need to be modified to match where Storm is located on your system. The
path in storm-mode-compiler
is expected to refer to the Storm binary you downloaded or compiled.
If you installed Storm through the system's package manager, you can use which storm
to find its
location on your system. If you compile Storm using Mymake, Storm will be located in debug/Storm
relative to the root of the Storm repository.
As above, you need to apply the changes by either pressing C-M-u
after each line, or by restarting
Emacs.
The path in storm-mode-root
is expected to refer to the root
directory that you wish to use. The
one used by Storm can be found by simply starting Storm in the top-loop. Storm prints the path of
the root directory as a part of its greeting message.
Integrating Mymake
Finally, if you wish to compile Storm from source, and to use Mymake to build and run Storm, you also need to install the Mymake plugin from the Mymake repository. This file is not distributed with the binary packages in Debian, so you need to download the file separately regardless.
If you have built Mymake from source, you can load the file mm-compile.el
from the repository you
have already cloned. If you installed Mymake from the system's package manager, you need to download
the file from the Mymake
repository and place it somewhere
in your file system.
To load the Mymake plugin, add the following to your ~/.emacs
file, right before the line that
loads storm-mode.el
. Note that the Mymake plugin will add a few global keybindings by default.
(load "~/mymake/mm-compile.el") (setq mymake-command "mm")
The path in the first line needs to be modified to reflect the location of the file mm-compile.el
on your system. The second line specifies the name of the Mymake binary on your system. If you added
Mymake to your system's Path (so that you can run it by typing mm
anywhere), then "mm" as
specified above is enough. If this is not the case, you can specify the full path to Mymake here.
Note: on Debian, the Mymake command is named mymake
rather than mm
.
As above, you need to apply the changes by either pressing C-M-u
after each line, or by restarting
Emacs.
Jumping to Errors
When the plugin is loaded, it adds a few patterns to compilation-mode
to recognize error messages
in Storm, and allows jumping to them easily. To use this functionality, you need to use the command
compile
in Emacs to run Storm. This can be done by pressing M-p
, typing compile
and then
pressing Enter. This makes Emacs ask you which command to use for compiling. Remove the default
(often "make -k"), and instead type storm <file>
, or whichever command you wish to run and press
Enter again. This causes Emacs to display a buffer named *compilation*
that displays the output of
Storm.
If Storm prints an error message, the source reference in the error message will be underlined and
highlighted in a different color than the rest of the text. This means that it is possible to jump
to the error by pressing M-x
, typing next-error
and then pressing Enter. This causes Emacs to
open the file that contains the error, and to jump to the correct position in the file. Emacs also
highlights the problematic piece of text for a short while.
Of course, it is inconvenient to use the full commands each time. For this reason, it is convenient
to bind them to keys. For example, to bind next-error
to the key M-n
, the following can be added
to the end of ~/.emacs
(press C-M-u
after the line to apply it immediately, or restart Emacs):
(global-set-key (kbd "M-n") 'next-error)
If you do not plan on using Mymake to compile Storm, it might also be worth binding compile
to a
key, for example M-p
(press C-M-u
after the line to apply it immediately, or restart Emacs):
(global-set-key (kbd "M-p") 'compile)
Note that you only need to enter the command the first time you use the compile
command. Emacs
remembers the command you entered, so the next time you can immediately press Enter when Emacs asks
for the command line.
If you loaded mm-compile.el
, then the Mymake plugin provides an alternative to the compile
command that is already bound to M-p
. So you do not need to bind it yourself.
Accessing the Built-In Documentation
If you set the variables storm-mode-compiler
and storm-mode-root
, the Storm plugin also allows
browsing the built-in documentation directly in Emacs. To access the documentation, type M-x
storm-doc
and press Enter. Emacs will then ask you for a name to display documentation about. Note
that this name should be written using the generic Storm syntax (i.e. using .
and not :
). Tab
can be used for auto completion as usual.
For example, to read documentation about the string class, type M-x storm-doc
and press Enter. In
the new prompt, type core.Str
and press Enter again. This will open up a new buffer that contains
the documentation. In contrast to the textual documentation in the top-loop, the page in Emacs
contains clickable hyperlinks in many places. This makes it convenient to read the documentation
about the members in the class, for example.
Note that the Storm process started by Emacs does not currently reload code automatically. This
means that documentation for code you are currently writing may not be available. This can be
resolved by restarting the Storm process, which is done by typing M-x storm-restart
and pressing
Enter.
Both of these commands can of course be bound to keys similarly to above if desired.
Syntax Highlighting
If you do not wish to use the language server for syntax highlighting, it is a good idea to at least
tell Emacs to use java-mode
for Basic Storm source code. This allows Emacs to provide some level
of syntax highlighting and indentation, since Basic Storm is syntactically similar to Java. This can
be done by adding the following to the end of the file ~/.emacs
. This does not conflict with the
use of the language server, so it can act as a good fallback regardless.
(add-to-list 'auto-mode-alist '("\\.bs$" . java-mode))
As above, press C-M-u
after the line or restart Emacs to apply the changes.
To use the language server to perform syntax highlighting in a buffer, go to the buffer and press
M-x
, then type storm-mode
, and finally press Enter. This makes the buffer use the language
server for syntax highlighting.
If you wish to automatically use the language server for all supported file types, you can press
M-x
, type global-storm-mode
, and press Enter. This makes Storm mode the default for the current
session. If you wish to make it permanent, you can add the following to the end of your ~/.emacs
file:
(global-storm-mode t)
Troubleshooting
In some cases, the syntax highlighting will not work properly. Any error messages are outputted to
the *compilation*
buffer, which may help to narrow the problem down. Two common issues are:
-
Syntax highlighting in a file fails to work at all
In order to support syntax extensions in the same directory as the current file, the language server will attempt to load all files in the same directory as the file before attempting to perform syntax highlighting. If this fails due to a syntax error in one of the files, syntax highlighting will fail, and an error message is printed to the
*compilation*
buffer. You can typically jump to the error by usingnext-error
(bound toM-p
above). After fixing the error, you currently need to restart the Storm process by pressingM-x
, typingstorm-restart
, and then pressing Enter. Note that this only happens the first time a file in a directory is highlighted. As such, as long as you ensure that files parse properly when you close Emacs, this is typically not a problem. -
Syntax highlighting is offset by a few characters
This happens at times when the language server lags behind the typing of the user. The protocol aims to compensate for this type of lag, but there is apparently some bugs remaining.
If this happens, you can simply press
C-c r
to re-open the file and re-do syntax highlighting.
Compiling with Mymake
If you loaded the mm-compile.el
plugin, you can also compile Storm with Mymake. This is convenient
when developing code in C++ alongside code in Storm. It is also convenient for pure Storm
development, since the Mymake plugin provides a mechanism to store the compilation command in a
file. Using Mymake does, however, require that you are willing to compile Storm from source, as
there is no easy way to instruct Mymake to just run Storm without the C++ source code available.
By loading the mm-compile.el
file, the following keybindings are added globally:
-
M-p
- compile the code in the current buffer. See below how this is done. -
C-c q
- compile the code in the current buffer, specify a command manually. -
C-c C-k
- kill the current compilation process.
When you ask the Mymake plugin to compile code, it will search the directory of the current buffer
and upwards for a file named buildconfig
. If such a file is found, it uses the directory that
contains the file as the current working directory and examines the contents of the file. Any lines
that start with #
are considered to be comments. Any remaining text are interpreted as command
line parameters to Mymake.
If a file named buildconfig
was found, then the plugin executes Mymake in that directory with the
parameters specified in the file. This means that it is possible to store the parameters to run the
code you are currently developing in the buildconfig
-file in the root of the Storm project. Doing
so allows you to compile the code by pressing M-p
anywhere in the Storm repository to compile and
run your code. Since the compilation is run inside Emacs, you can also jump to any compilation
errors that appear in the compilation by pressing M-n
(based on your setup above).
The Storm repository contains a buildconfig
file at the root that contains a number of commands
for launching various things. Most of them are commented out, but they act as a reference for how
commands can be formatted. The buildconfig
file in the Storm repository also contains some options
for automatically generating a skeleton in newly created C++ files. Refer to the documentation in
the mm-compile.el
file for more details on this.
If no buildconfig
-file is found, the Mymake plugin simply executes Mymake in the current
directory, but with the flag --default-input <filename>
. This causes Mymake to look for a suitable
.mymake
- or .myproject
file in the current or parent directories, and compile the code based on
the information there. If no such file is found, or if the file does not specify an input file, the
file provided after --default-input
is used. The Mymake plugin supplies the name of the currently
open file here, which makes it possible to use M-p
to compile everything from standalone files, to
large projects like Storm conveniently.