Emacs Extensions for
GE Smallworld Magik Development

Screen-casts, tutorials, and productivity tools for Magik programmers who use Emacs. From tab-mode and code folding to the Magik Debugger and object inspector — explore features built by a developer, for developers.

Learn More
HydePark Consulting Screen-casts on YouTube RSS via FeedBurner

Nine screen-casts published between November 2010 and January 2011 — covering everything from ECB mode to the Tree Item GUI control. Read the story behind the project →

Get in Touch

Building a Magik Snippet Library with Yasnippet

Magik developers at Australian utilities spend a surprising amount of their day typing the same lines of Smallworld code over and over. Whether you are maintaining a dataset for Sydney Water's wastewater network or extending a model class for an Energex field crew application, the patterns repeat: iterators over collections, predicates on RWO objects, conditional method dispatch, defensive try blocks around database calls. Each pattern is small, but multiplied across hundreds of methods, the keystrokes add up.

Yasnippet is a snippet expansion engine for Emacs that turns a short trigger word into a fully formed template the moment you press Tab. For a Magik programmer, it behaves like an extra set of fingertips, anticipating the shape of the next ten lines you would otherwise type by hand. Combined with the editor hooks already provided by magik-mode, it becomes the heart of a personal code template library that grows with your project.

This walkthrough is aimed at Smallworld developers working in Australian consultancies, in-house GIS teams at water authorities, and the wider Magik community that gathers at events such as the annual Smallworld user meeting. The article assumes basic familiarity with Emacs, but it assumes nothing about your prior experience with snippet systems. By the end, you will have a working Magik snippet library, an approach to organising it, and a way to share it with colleagues whether they sit in Brisbane, Perth, or Adelaide.

The examples are deliberately small so that the mechanics stay visible. Once the mechanics are familiar, the same approach scales to whole method bodies, file headers, and test scaffolds that match the coding standards your team has refined over years of Smallworld delivery work.

Installing Yasnippet and Wiring It into Emacs

Yasnippet ships on MELPA, which most Australian Magik developers already have configured through their magik-mode bootstrap script. Installing it is a one-line call from package-list-packages, followed by the usual M-x package-install RET yasnippet. After the package lands in your load path, you enable global expansion and add the Magik snippet directory to the variable yas-snippet-dirs.

A minimal init snippet looks like this:

(require 'yasnippet)
(yas-global-mode 1)
(setq yas-snippet-dirs '("~/.emacs.d/snippets/magik-mode"))
(yas-load-directory yas-snippet-dirs)

The snippet directory itself is just a folder named magik-mode that lives somewhere reachable from your home directory. When Emacs starts up, Yasnippet scans the folder, parses every .yasnippet file inside, and registers the trigger keywords. From that point, typing the trigger and pressing Tab expands the template.

If you work across multiple machines, such as a workstation in your Melbourne office and a laptop you take to a client site in Canberra, symlinking the snippet folder into your dotfiles repository keeps both environments in sync. Many local Magik consultants treat the snippet library as part of their personal dotfiles rather than the project codebase, because the templates are language-wide rather than project-specific.

Designing Triggers that Match Magik Conventions

The trigger is the short keyword you type before Tab. Picking triggers that already feel natural inside a Magik buffer means the library fades into the background rather than fighting your muscle memory. Common conventions borrowed from other Emacs modes include def for method definitions, iter for for_each loops, and pred for predicate methods that return a true_false value.

Magik itself has a small set of idioms worth mirroring. A defensive method often starts with protect and a when error block. A collection filter almost always uses _for or _over chained with suchthat. Trigger names such as protect-block, iter-over, and suchthat-filter read clearly in code review and are easy to remember during a long Friday afternoon maintenance session in Brisbane.

Keep trigger names short enough to type quickly but specific enough to avoid clashes with the words Magik already uses. _iter, _meth, and _pred are safe because the leading underscore is rarely typed at the start of a Magik identifier outside string literals. When in doubt, prefix every trigger with an underscore so they never collide with real variable names.

Avoid putting the same word in two different snippets within the same mode. Yasnippet raises a warning when it loads duplicated triggers, and a confused expansion at midnight, while you are patching a dataset before a Monday-morning cutover in Adelaide, costs far more than the minute it would take to rename one of them.

Writing the First Magik Snippet

A Yasnippet file is a plain text snippet with a header that names the trigger and a body that holds the template. The body uses ${1:placeholder} syntax for fields and $0 for the final cursor position. A simple snippet that expands a method definition skeleton looks like this:

# name : _meth
# key  : _meth
# --
_method ${1:object_name}.${2:method_name}($3)
    ## Purpose: $4
    ## Author:  ${5:$(user-full-name)}
    ## Date:    `(format-time-string "%Y-%m-%d")`
    $0
_endmethod
$0

Save the file as ~/.emacs.d/snippets/magik-mode/_meth.yasnippet, reopen a Magik buffer, type _meth, and press Tab. The method signature expands, the cursor lands on object_name, and pressing Tab again walks you through the parameter list, the purpose comment, the author field, and finally the body.

The (format-time-string "%Y-%m-%d") expression is evaluated the moment the snippet expands, so the date stamp reflects your current AEST or AEDT clock depending on daylight saving. That little detail matters when you are exporting change logs for an audit at a regulated authority, where every method needs a creation timestamp that matches the build cycle.

The $0 markers are placeholders that mark where the cursor should land after you have filled in all the numbered fields. Placing $0 both inside and outside the _endmethod line gives the cursor a sensible resting position whether you tab through to the end or escape out early with M-x yas-abort.

Adding Mirrors, Choices, and Transformations

Snippets become far more useful when fields can refer to one another. A mirror field is a placeholder that automatically fills with whatever you typed in another placeholder earlier in the template. For a Magik predicate that returns the boolean true_false, mirroring the object name into the documentation comment keeps the two in sync:

# name : _pred
# key  : _pred
# --
_method ${1:object_name}.${2:is_}_p()
    ## Returns true_false: whether ${1:object_name} $3
    _return $0
_endmethod

The ${1:object_name} reference appears twice. Typing switch in the first field fills both occurrences. Mirrors are also handy inside iterator snippets where the collection variable and the loop variable need to share a stem, such as _for a_pipe _over pipe_collection.

Choice fields turn a placeholder into a small menu of fixed values. The syntax ${1|true,false,unset|} shows a list the moment the cursor enters the field, which is perfect for status enums that recur across an asset record model. Local teams often add their own utility-specific values, such as the closed, isolated, and decommissioned states used by Victorian water authorities, by editing the choice list directly inside the snippet file.

Transformations wrap a field with an elisp expression. The earlier $(format-time-string "%Y-%m-%d") example is one transformation; another useful one inserts the current buffer name with $(buffer-name), which helps when you are writing a snippet that needs to reference the enclosing module path. Treat transformations as small, readable elisp; anything longer than two or three lines belongs in a helper function rather than the snippet body.

Organising the Library by Domain

A snippet folder quickly grows past a hundred entries if you are not careful. Splitting the directory into subfolders named after Magik domains keeps Yasnippet happy, because each subfolder becomes a dropdown group in the snippet menu bound to M-x yas-insert-snippet. Suggested groupings for an Australian Smallworld shop include methods/, loops/, ds/, swaf/, and tests/.

The ds group holds snippets that wrap dataset operations, such as ds-read, ds-write, and the read-modify-write pattern that protects against concurrent edits from field crews. The swaf group covers Smallworld Application Framework callbacks, which have very particular argument lists and are easy to mistype. The methods group collects the reusable method skeletons you have built up over years of delivery.

If you maintain multiple product branches, such as one for Sydney Water's sewer model and another for SA Water's stormwater model, you can keep separate snippet directories per branch and toggle yas-snippet-dirs from a project-local .dir-locals.el. The same Magik buffer behaves differently depending on which project you have open, and your snippet library travels with the codebase rather than living as a single global bag.

Search becomes important once the library passes a few dozen snippets. Yasnippet honours yas-choose-keys, which lets you bring up an helm or ivy completion buffer from any Magik buffer with M-x yas-insert-snippet. Typing iter in that buffer shows only the iterator snippets, which is much faster than scrolling the dropdown menu when you have a packed library.

Sharing the Library Across Teams

A snippet library is most valuable when it is shared, because every team member benefits from the patterns your senior developers have refined. Storing the directory in a Git repository alongside your dotfiles works for personal use; for a consultancy team, a separate internal repository scoped to the Magik mode keeps the history clean and lets you tag releases.

A typical setup at a mid-sized Australian Smallworld consultancy is a bare Git repo on a small server hosted in a Sydney data centre, mirrored to an Atlassian Bitbucket project for code review. Each Magik developer clones the repo into ~/.emacs.d/snippets/magik-mode, and a small bootstrap script in the team dotfiles ensures the clone is up to date every time Emacs starts. Pulling changes takes a few seconds and survives a flaky link from a regional office.

Pull requests are the right place to discuss trigger names, comment headers, and snippet placement. A change that introduces a new pattern for handling Magik dynamic method dispatch is exactly the kind of decision worth a code review thread, because the snippet will be expanded thousands of times across the life of the project. The review is also where disagreements about coding style get resolved once, for everyone, rather than every time someone starts a new method.

When a snippet graduates from personal use to team use, give it a brief header comment in the .yasnippet file explaining its intent. Future developers, including the future you who has forgotten what swaf-cb-record-change was supposed to do, will thank you for the two lines of context.

Keeping the Library Alive

A snippet library decays quickly if nobody tends it. Triggers fall out of favour, transformation expressions stop matching new Magik syntax, and choice lists drift away from the actual enum values used in production. Schedule a short quarterly review where one developer reads through the library, deletes obsolete entries, and updates timestamps or author placeholders to reflect the current team.

Pair the review with a survey of recent Magik code in the main project. Look for blocks that were typed by hand at least three times in the last sprint; each one is a candidate for a new snippet. Many Australian Smallworld teams have discovered that the act of writing the snippet is itself a useful refactoring exercise, because it forces a conversation about what the canonical version of a pattern looks like.

Finally, retire triggers that nobody uses. A snippet with a clever name that no one remembers is worse than no snippet at all, because it sits in the dropdown menu and adds noise. Move retired snippets into an archive/ folder rather than deleting them outright, in case an old project resurfaces months later.

The table below compares three common snippet libraries used by Magik developers and shows where Yasnippet fits relative to abbrev mode and the built-in magik-mode skeleton inserts.

Feature Yasnippet Emacs abbrev mode magik-mode skeletons
Multi-line templates Yes, with field navigation No, single expansion only Yes, fixed text
Mirrored fields Yes, with placeholders No No
Choice menus Yes, via `${1 a,b,c }`
Folder grouping Yes, subfolders per group No No
Per-mode trigger table Yes, one per major mode Single global table One per mode
Version-controllable Plain text files in Git Stored in your abbrev file Bundled with the mode
Learning curve Moderate Low Low

Yasnippet stands out for Magik work because the templates can hold multi-line method bodies, mirrored arguments, and embedded elisp transformations, all of which fit naturally with the way Smallworld developers structure their code. Abbrev mode remains useful for short single-line expansions, and magik-mode skeletons cover the language features that ship with the mode.

If you are ready to start building your own library, the first step is to clone a minimal snippet repository, add a single .yasnippet file, and let the rest grow from there. HydePark Consulting publishes a starter pack for Australian Smallworld teams, and the broader Magik community shares snippets through the magik-mode mailing list. Drop into the user group, share what you build, and the patterns you refine today will save your colleagues hours tomorrow.

Core Features

Tab Mode & ECB

Quick tab switching and Emacs Code Browsing mode for navigating Magik codebases efficiently.

Magik Smeller

Code analysis tool that helps identify potential issues in Magik source files.

Code Folding

Hide/Show mode for collapsing and expanding Magik code blocks to focus on what matters.

Visual Bookmarks

Quick visual bookmarks for jumping between key locations in your Smallworld session buffers.

Object Inspector

Inspect Magik objects and display them in an Emacs Deep Print buffer for detailed examination.

Magik Debugger

Set breakpoints and monitor slots and variables directly from within Emacs.

Development Tools

Direct links between Emacs and the Smallworld Development Tools application, including Click Monitor.

Screen-casts & Tutorials

Dark code editor window with syntax-highlighted Magik source code in muted blues and greys, conveying a focused development environment

Screen-cast 1: Tab Mode, ECB & More

Covers tab-mode, ECB, Magik Smeller, code folding, visual bookmarks, pragma toggling, moving code, external editor, and MS Explorer.

November 7, 2010
Split-pane Emacs interface with multiple buffers open, warm amber and navy tones against a dark background

Screen-cast 5: Object Inspection & Deep Print

Inspect a Magik object, prompt for an expression evaluated within a Smallworld session, and display results in a Deep Print buffer.

January 16, 2011
Debugging interface with breakpoint markers and variable watch panels in subdued teal and charcoal tones

Screen-cast 7: Magik Debugger

Useful tools for application developers: Object Inspector and Magik Debugger with breakpoints and slot/variable monitoring.

January 2011
Tree control GUI element with expandable branches rendered in clean greys and muted blues on a light background

Screen-cast 9: Tree Item GUI Control

Tree Item is a GUI control providing extensive facilities for displaying lists with rows, columns, trees, and in-place editing.

January 20, 2011