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

A practical Flycheck workflow for Magik compilation errors

Magik development often happens inside a running Smallworld environment rather than through a simple command-line compiler. That arrangement is powerful for inspecting objects, navigating methods, and testing changes against a live application, but it can leave Emacs without a consistent stream of diagnostics.

Flycheck provides the missing editor integration. It can run a checker whenever a Magik buffer changes, read compiler output, and place errors and warnings directly on the relevant lines. The important work is connecting Flycheck to the particular Magik runtime, launcher, and output format used by a project.

Integrating Magik compilation errors into Emacs’ Flycheck is therefore less about writing a large Emacs Lisp package and more about defining a reliable boundary between two tools. A small wrapper can start the right Smallworld environment, compile one source file, and print predictable diagnostic records.

This approach suits Australian development teams working across utilities, transport, government, mining, and location-based infrastructure projects. It also works well for distributed teams in Sydney, Melbourne, Brisbane, Perth, or Adelaide, where developers may use different local paths while sharing the same Magik source tree.

Why the compiler output needs an adapter

Flycheck expects diagnostics in a recognisable structure: a file name, a line number, optionally a column, a severity, and a message. Magik errors may instead be printed by a launcher, logged by a running session, or decorated with Smallworld-specific text. Some environments report a source location on one line and the explanation on the next.

A direct Flycheck definition can work when the compiler already emits stable records such as:

/opt/project/modules/map.magik:42:7:error: Unknown method calculate_extent

Many production installations are less uniform. A command may require environment variables, a product installation path, a workspace configuration, or a licence-aware runtime. In that situation, placing those details in an executable wrapper is easier to maintain than encoding them in every developer’s .emacs file.

The wrapper should accept the source file as an argument, invoke the project’s normal Magik compilation process, and convert each diagnostic into one line. It should preserve the original exit status where practical, but Flycheck can still display parsed errors even when the underlying command exits unsuccessfully.

Choose a stable compilation boundary

Start by identifying how a developer currently compiles a Magik file without Emacs. That might be a shell script supplied by the project, a Smallworld batch command, a launcher configured by an IDE, or an Emacs command that sends forms to a live Magik process.

A wrapper named magik-flycheck could perform tasks such as loading the project environment, selecting the correct product version, setting the working directory, and invoking the compiler. A simplified POSIX shell outline might look like this:

#!/bin/sh
set -u

source_file=$1
project_root=${MAGIK_PROJECT_ROOT:?Set MAGIK_PROJECT_ROOT}

cd "$project_root" || exit 2

# Replace this command with the project's supported compiler entry point.
smallworld-magik --compile "$source_file" 2>&1 |
  ./tools/normalise-magik-diagnostics

The actual command will vary between Smallworld installations. Avoid bypassing a site’s standard startup process merely to make Flycheck run. A utility company in Perth may have a version-managed launcher, while a consulting team in Melbourne may use a shared Linux build host. Both should call the same supported project entry point so that editor checks match the build system.

Make the wrapper executable and test it in a terminal with a deliberately broken Magik file. Confirm that it exits, does not wait for interactive input, and prints the source path and line number. If compilation requires a long-lived session, use a separate non-interactive command or a project-provided batch facility rather than trying to scrape messages from a developer’s personal REPL.

Define a predictable diagnostic format

A normalised format reduces the amount of regular-expression logic required in Emacs. One useful contract is:

path/to/file.magik:line:column:severity:message

For example:

src/roads.magik:118:12:error: Unexpected end of method
src/roads.magik:204:4:warning: Deprecated collection operation

When the Magik compiler does not provide a column, output 0 or a sensible default. The line number is essential because Flycheck uses it to create overlays and entries in the *Flycheck errors* buffer. Keep the message on one physical line, escaping or replacing embedded newlines where necessary.

A normaliser can use awk, Python, or a small Magik-side utility, depending on where the original output is easiest to parse. It should recognise common variants such as Error, ERROR, and warning, then translate them to the lower-case severity names expected by the editor. It should also retain the original compiler message rather than reducing it to a generic “compilation failed”.

Paths deserve particular attention. A Windows Smallworld installation may produce drive letters and backslashes, while a remote Linux environment may emit paths rooted inside a container or mounted workspace. Test paths containing spaces, parentheses, and non-ASCII characters. Consistent path handling matters to developers moving between a Brisbane laptop and a shared build server.

Register a checker in Emacs

Once the wrapper produces stable output, define a custom checker with flycheck-define-checker. The following example assumes the wrapper accepts one source path and emits the format described above:

(require 'flycheck)

(flycheck-define-checker magik-compiler
  "Check Magik source with the project compiler."
  :command ("magik-flycheck" source-original)
  :error-patterns
  ((error
    line-start
    (file-name) ":" line ":" column ":error:" (message)
    line-end)
   (warning
    line-start
    (file-name) ":" line ":" column ":warning:" (message)
    line-end))
  :modes magik-mode)

(add-to-list 'flycheck-checkers 'magik-compiler)

The source-original argument gives the command the file name associated with the current buffer. This is generally preferable to passing a temporary copy when the compiler needs to resolve relative imports, modules, or project resources. If the wrapper specifically requires a temporary file, use source instead and confirm that diagnostics still map back to the buffer.

Load this definition after Flycheck and after the Magik major mode has been installed. In a normal Emacs configuration, it can live in an accompanying Lisp file loaded from init.el. Run M-x flycheck-verify-setup in a Magik buffer to confirm that the checker is registered and that the expected major mode is active.

If the mode uses a different symbol, adjust :modes accordingly. The name shown by M-x describe-mode is the reliable source, especially when a local Magik mode has been customised by a project.

Map paths back to the current buffer

A checker may successfully report errors while still failing to underline them if the compiler prints a path that Flycheck cannot match. Typical mismatches include relative paths versus absolute paths, Windows separators versus Unix separators, and a remote workspace path versus a local TRAMP path.

First, make the wrapper run from the project root and ask the compiler to print paths relative to that root if supported. Otherwise, convert paths in the normaliser. On Unix-like systems, realpath can help, but do not assume it is available on every developer machine. A Python normaliser is often a better cross-platform choice for teams supporting both macOS and Windows.

Remote editing requires an additional decision. If Emacs is connected through TRAMP to a host where Magik runs, the checker should run remotely and return remote file names. If compilation happens locally while the source is mounted elsewhere, paths need translating before Flycheck receives them. Mixing these models can produce errors in the right file name but the wrong buffer.

Use M-x flycheck-list-errors to inspect the parsed file and location. This is more informative than looking only at the red or yellow fringe marker. It shows whether the problem is the compiler, the normaliser, the path mapping, or the regular expression.

Handle interactive Smallworld sessions

Some Magik workflows depend on an already-running Smallworld session. Developers may load modules, inspect objects, or compile methods interactively, and a batch checker may not have access to the same database connection or application state. In that case, Flycheck should be treated as a fast syntax and static compilation check, not as a replacement for every interactive test.

One option is to expose a dedicated compile command in the running session. The Emacs checker can send the current file or method to that process, capture a marked section of output, and parse only diagnostics between start and end tokens. This requires more Elisp than a shell wrapper, but it preserves the project’s established runtime assumptions.

Another option is to keep Flycheck focused on checks that are safe without a live database. Compilation errors, malformed syntax, missing method declarations, and obvious type or name problems are useful in every environment. Database-dependent validation can remain attached to a separate command, such as a project test runner or a Magik-specific inspection tool.

Set a sensible flycheck-idle-change-delay so that saving or pausing does not trigger expensive application startup repeatedly. Developers on a slow VPN connection from regional New South Wales should not have every keystroke launch a remote Smallworld process. A delay of one or two seconds, combined with checking on save, is often a practical compromise.

Make failures visible and actionable

Flycheck supports more than inline overlays. Its error list can be navigated with flycheck-next-error and flycheck-previous-error, while flycheck-explain-error-at-point can show the full diagnostic message. These commands are especially helpful when Magik output includes a long method name, package path, or compiler suggestion.

Add a small keymap or use the standard Flycheck bindings so that moving between compiler errors is quick. Keep the original diagnostic text intact, including any error code emitted by the project. Teams can then search for recurring failures in logs and documentation instead of seeing a shortened editor-only message.

Warnings should be classified deliberately. A deprecation warning may be useful during development but should not block a buffer from being considered clean. Conversely, a project-specific warning about an unsafe database operation may deserve the error severity for local purposes. The wrapper or normaliser is the right place to apply that policy, where it can be version-controlled with the project.

For Australian organisations with formal release processes, consistent severity handling also helps bridge local development and controlled deployment. A team maintaining council assets in Adelaide or network infrastructure in Sydney can use the same diagnostic vocabulary in Emacs, automated builds, and review documentation.

Share the setup across the team

Put the wrapper, normaliser, and checker definition in the project repository when licensing and security policies allow it. Keep machine-specific values outside the shared files, using environment variables such as MAGIK_PROJECT_ROOT, SMALLWORLD_HOME, or a site-specific launcher path. This allows the same configuration to work across Linux workstations, Windows installations, and remote build hosts.

Document the expected compiler version and the command used by the wrapper. A Flycheck integration that silently selects the wrong Smallworld release can produce confusing method or module errors. Version checks in the wrapper are worthwhile when a project supports multiple product generations.

Add a small fixture set containing valid source, a syntax error, an unknown method, a warning, and a path with spaces. Run the wrapper against these files whenever the compiler or project launcher changes. A few fixtures protect the regular expressions from accidental breakage and make onboarding easier for new developers joining a consultancy or an internal GIS team.

Finally, keep a manual fallback. M-x flycheck-mode can be disabled for a buffer, and the normal project compilation command should remain available. The editor checker is a productivity layer: it should make Magik feedback faster without becoming the only way to diagnose a failed build.

Add the wrapper and checker definition to a small project-level Emacs package, test them against real Magik diagnostics, and commit the normalised output contract alongside the source. With that boundary in place, Flycheck can turn compiler messages into immediate, navigable feedback while the established Smallworld workflow continues to handle interactive and environment-dependent work.

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