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

Taming Magik's Dynamic Typing With Company Mode Completion

Magik code lives in a world where variables take on whatever shape the surrounding logic demands. A single identifier can hold a rope, a sw:rb_tree, or a sw:coordinate one moment and a completely unrelated record the next, because the language deliberately delays type decisions until runtime. For developers working on GE Smallworld datasets inside Emacs, that flexibility is liberating on the console yet unnerving in a long source buffer, where the next keystroke could autocomplete to almost anything. Company Mode is well placed to soften the surprise, but only if the backend feeding it speaks Magik's dialect of dynamic typing rather than guessing from textual context alone.

The Smallworld community in Australia is unusually concentrated. Sydney and Melbourne host engineering teams behind several gas, water, and electricity distributors that rely on Smallworld for network modelling, while consultancies in Brisbane and Perth support field crews across regional Queensland and Western Australia. Many of those engineers keep an Emacs session open all day alongside their Smallworld session, switching between Magik REPL, source files, and a chat client such as the one used by HydePark Consulting. Reliable completion into that workflow is more than cosmetic; it changes how confidently a developer navigates a thousand-line method without stepping away to dig through class hierarchies.

Because Magik is prototype-based and reflects almost everything about itself, candidates can be assembled from real runtime data rather than from a static parser's guesswork. The challenge is wiring Company Mode to the introspection primitives shipped with Smallworld's Magik image, then trimming the noise so the popup shows the three or four identifiers a developer wants at that moment.

A reliable completion backend for Magik will not look like one built for Java or Python. The receiver of a message is rarely declared in the visible source, and Smallworld's domain classes come and go as image patches roll out across an organisation. That volatility is exactly what makes a Magik-aware backend worth the effort: suggestions grounded in the live image keep up with the stack automatically.

Why Static Backends Fall Short in Magik

Magik's grammar does not advertise a variable's type, and there is no header file to inspect when a developer types my_dataset.. Built-in Company backends such as company-dabbrev and company-etags rely on lexical neighbours or symbol tables, and they happily suggest any identifier that has appeared anywhere in the buffer. For a strongly typed language that is usually harmless; for Magik it floods the menu with irrelevant names. company-semantic does not attempt Magik files without an external grammar, and where it does, it produces candidates that ignore the receiver object entirely.

Engineers maintaining Smallworld databases for utilities around Sydney Harbour or the Mornington Peninsula often inherit modules written by people who have long since moved on. Those modules mix Magik conventions from different decades: pragmas borrowed from Smalltalk, ALPHA-era variable naming, and modern keyword arguments. A completion menu that does not respect the receiver's actual class cannot tell whether sw_dataset!.| should resolve to a geometry method or a property accessor, and it cannot filter out inherited mixins that the current image no longer understands.

Backend Magik Awareness Speed Requires External Tool Quality of Candidates
company-dabbrev None Very fast No Noisy, buffer-local only
company-etags Limited Fast etags pass Token based, no dispatch
company-semantic None for Magik Medium Semantic grammar Generic, ignores receiver
Custom Magik backend Full runtime Medium to fast Magik REPL/image Receiver-aware, filtered

The custom row at the bottom is the path the rest of this piece explores: a backend that asks the Magik image what an expression evaluates to, then asks the same image what messages that value responds to.

Building the Bridge From Emacs to the Magik Image

A practical completion backend for Magik leans on a long-running inferior process. Most developers keep a Magik prompt open through magik-session or a custom comint buffer; that buffer becomes the oracle for completion queries. Company Mode's company-backend machinery accepts any function that returns candidates given a prefix and a callback, so the wrapper only needs to serialise the request, push it into the inferior process, and parse the response back into Emacs structures.

The trick is choosing a serialisation that survives round-trips across namespaces. Magik methods routinely contain square brackets, exclamation marks, and question marks, none of which survive naive shell quoting. Wrapping each query in a heredoc, or sending commands through process-send-string with explicit length framing, prevents truncation when a developer in an Adelaide-based water utility's office queries a method whose name includes a full Unicode degree symbol.

Once the round-trip works, the backend translates Magik's >> and << stream operators into something Emacs can pattern-match on. A lightweight protocol such as __COMPANY_BEGIN__ ... __COMPANY_END__ keeps the candidate stream isolated from incidental REPL output, such as a print statement from another thread.

Reading the Receiver With Magik's Own Introspection

Magik offers a generous introspection surface that most developers only meet halfway. .methods() returns a sorted list of messages an object responds to, .class reports the dynamic class, and .superclass walks the prototype chain. Combined with the sw_property metadata exposed by Smallworld records, these primitives let a backend reconstruct an accurate picture of what lives on the other side of a dot.

A useful query asks the image to evaluate the expression up to the caret, then return the class of the result. Because Magik evaluates eagerly, the backend has to be defensive: arbitrary user code may have side effects, open database cursors, or trigger remote procedure calls. Wrapping the probe in protect with a small timeout avoids wedging the completion popup when a developer is connected to a slow field-office server outside Hobart.

Once the class is known, the backend merges three sources: directly defined methods, prototype chain methods, and sw_property slots. Candidates are tagged internally with their origin so that the popup sorts them — own methods first, inherited second, properties third — and so buffer-local Company Mode settings can hide inherited entries entirely for users who prefer a terse menu.

Filtering, Sorting, and Grouping the Candidate List

Raw introspection produces dozens of candidates, and Company Mode displays at most a screenful before scrolling. Filtering happens in two stages. The first stage drops anything that does not match the prefix the developer has typed; the second stage applies a fuzzy match tuned for Magik's naming style, where underscores separate words and trailing punctuation carries meaning. A simple match-score that rewards exact prefixes and penalises identifiers with mismatched case keeps the top of the menu aligned with developer intent.

Grouping matters too. Methods that mutate state end with !, predicates with ?, and Smallworld collection iterators carry a >> motif. The backend tags each candidate with one of those categories and lets the popup display them with a subtle annotation in the margin, enough for a developer between sips of a flat white at a Melbourne CBD desk to recognise which candidate is destructive.

Sorting blends the match score with usage hints gathered from the current buffer. A small buffer-local hash records how often each candidate was accepted during the session, and that count nudges familiar names upward. The result feels responsive without becoming idiosyncratic: a developer working on a regional electricity distributor's switchgear records sees their habitual methods rise, while one-off names sink into the lower half of the popup.

Documentation, Method Signatures, and Tooltips

Completion is only half the comfort. Company Mode's documentation popup can show a short blurb next to the highlighted candidate, drawn either from inline comments or from a separate docstring table. Magik supports both styles, and the backend detects which is in play by scanning the slot's source location. When the signature includes optional or keyword arguments, the tooltip renders them in the order Magik expects, including the +optional+ and +gather+ markers that the language uses to declare variadic behaviour.

A small magik-company-doc function reads the relevant section of the source file through imenu, extracts the docstring, and hands it back to Company Mode's company-doc-buffer. Engineers reviewing code in commit hunks during a Sydney-to-Perth video call appreciate seeing the signature without breaking focus, especially when the candidate is a generic collection method whose behaviour differs between Smallworld versions.

For Smallworld-specific classes such as sw_dataset! or sw_corridor!, the backend can also surface the persistent class name and the underlying database table. That extra context saves a developer working on a multi-tenant hosted instance from opening a separate Smallworld session to confirm which schema a candidate targets, a small productivity win during a long debugging session.

Performance, Caching, and Working With Large Images

Introspection queries are not free. On a full Smallworld production image they can take several hundred milliseconds, longer than the threshold at which Company Mode starts to feel sluggish. The backend caches results keyed by (expression-text, image-checksum), invalidating whenever the inferior Magik process announces a recompile or fresh image load. Buffer-local expiry after a configurable number of seconds protects against stale results when a developer has been editing method bodies without saving.

For very large modules, the backend pre-warms the cache by asking the image for the full method table of frequently used classes such as sw_dataset!, rope, and simple_vector. Pre-warming happens asynchronously through Emacs's built-in timer machinery so it never blocks the editor. A developer in a Brisbane consultancy hot-desking on a winter morning sees the menu respond instantly once warm-up finishes, even on a project that touches dozens of Smallworld databases across multiple state-based clients.

Cache hygiene matters under Australian privacy obligations. The Magik buffers a developer edits may contain asset identifiers covered by the Privacy Act 1988 and the Notifiable Data Breaches scheme, particularly when working with water utilities in New South Wales. The backend never writes candidate text to disk, never logs queries, and clears its caches when the inferior process dies. Local configuration keeps the cache directory inside the developer's home folder, away from shared network drives that auditing teams elsewhere can reach.

A final tweak is tying the backend's enablement to file-local variables. A Local Variables: block at the bottom of a Magik source file can request completion only when the file is part of a registered Smallworld project, sparing developers from triggering Magik queries inside scratch buffers or Emacs configuration files. With that guardrail, Company Mode becomes a calm companion, and the dynamic nature of Magik stops feeling like a liability each time the caret lands after a dot.

Subscribers to the Magik Emacs newsletter receive early access to the backend's release notes, including a checklist for configuring it against Smallworld 5.x and the upcoming 6.0 image used by several New South Wales utilities. Drop into the HydePark Consulting office hours in Melbourne or Sydney, or join the open channel on the portal, to share what works in your environment and pick up the latest patches as the Smallworld ecosystem keeps evolving.

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