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

Writing your first Magik extension in Emacs

A small Emacs extension can remove repetitive work from a Magik development day. Instead of repeatedly typing method scaffolding, searching for related definitions, or running the same inspection command, you can add a focused command that fits the way your team works. The most useful first extension is usually modest: one command, one key binding, and a clear improvement to an existing workflow.

This guide builds an Emacs Lisp minor mode for Magik programmers. It inserts a correctly shaped Magik method, detects the current method name, and provides a foundation for later features such as method navigation, object inspection, code folding, or database analysis. The examples suit developers working with GE Smallworld environments in Australian utilities, councils, transport organisations, and specialist consulting firms.

Choose a small workflow to improve

Before writing code, choose a task that happens often and has a predictable result. Creating a method is a good starting point because Magik methods have a recognisable structure and developers frequently need an empty definition while exploring an object or implementing a change.

An extension should solve a real inconvenience rather than demonstrate every Emacs API at once. A Sydney or Melbourne development team maintaining a large Smallworld application may have hundreds of methods spread across product and custom code. A command that inserts a consistent method template can reduce typing errors and encourage a shared style across the codebase.

The extension will provide a minor mode called magik-extension-mode. Its first command, magik-extension-insert-method, asks for a method name and inserts this structure at the cursor:

_method _self.calculate_length()
  
_endmethod

Magik uses _method and _endmethod to delimit a method definition. The receiver can vary according to the codebase, so _self is a sensible default for a first tool. You can later add prompts for a class, exemplar, parameters, or documentation comments.

Prepare Emacs and the Magik buffer

Create a file named magik-extension.el somewhere in your Emacs load path. If you keep configuration in ~/.emacs.d/lisp, add that directory to the load path, or use an absolute path while experimenting. The extension is ordinary Emacs Lisp, so it can be loaded without compiling a package or changing your Smallworld installation.

The code below defines a sparse keymap, a command, and a minor mode. The interactive declaration makes the function callable through M-x, while the "sMethod name: " argument displays a minibuffer prompt. string-trim removes accidental spaces before the name is inserted.

;;; magik-extension.el --- Small Magik editing helpers

(defvar magik-extension-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-c m m")
      #'magik-extension-insert-method)
    map)
  "Key bindings for `magik-extension-mode`.")

(defun magik-extension-insert-method (name)
  "Insert a Magik method called NAME at point."
  (interactive "sMethod name: ")
  (let ((method-name (string-trim name)))
    (unless (string-empty-p method-name)
      (insert (format "_method _self.%s()\n  \n_endmethod\n"
                      method-name))
      (forward-line -2)
      (indent-according-to-mode))))

(define-minor-mode magik-extension-mode
  "Provide small editing helpers for Magik source files."
  :lighter " Magik+"
  :keymap magik-extension-mode-map)

(provide 'magik-extension)
;;; magik-extension.el ends here

Evaluate the file with M-x eval-buffer, then enable the mode using M-x magik-extension-mode. Press C-c m m, enter calculate_length, and inspect the result. If Emacs reports that string-empty-p is unknown on an old installation, add (require 'subr-x) near the top of the file.

Load the extension for Magik files

Manually enabling a minor mode is useful for testing, but a daily tool should activate automatically in the relevant buffers. Many installations use a Magik major mode supplied by an internal package or a community implementation. The exact major mode name can differ, so check the mode line or run M-x describe-mode inside a Magik buffer.

Add this configuration to your Emacs init file after placing magik-extension.el in the load path:

(add-to-list 'load-path "~/.emacs.d/lisp")
(require 'magik-extension)

(with-eval-after-load 'magik-mode
  (add-hook 'magik-mode-hook #'magik-extension-mode))

If your major mode is called smallworld-magik-mode, replace magik-mode-hook with smallworld-magik-mode-hook. If the Magik mode is loaded before your init file reaches this code, the with-eval-after-load form still protects the configuration from loading errors. Restart Emacs or evaluate each form with C-x C-e, then open a .magik file and confirm that Magik+ appears in the mode line.

Australian teams often share an Emacs configuration through Git rather than asking each developer to maintain local snippets. That approach works well for a Brisbane consultancy supporting several council GIS projects, provided site-specific paths and Smallworld installation locations remain outside the shared file. Keep the generic extension in version control and place workstation-specific settings in a local configuration file.

Add context awareness

A useful extension should understand enough of the current buffer to avoid behaving like a simple text macro. The next command finds the name of the method surrounding point. It searches backwards for _method, captures the portion after _self., and stops at the opening parenthesis. This is intentionally conservative because Magik code can use different receivers and formatting conventions.

(defun magik-extension-current-method ()
  "Return the Magik method name around point, or nil."
  (save-excursion
    (when (re-search-backward
           "^[[:space:]]*_method[[:space:]]+[^.[:space:]]+\\.\\([^ (]+\\)"
           nil t)
      (let ((candidate (match-string-no-properties 1)))
        (unless (re-search-forward "^[[:space:]]*_endmethod\\b"
                                   (line-end-position) t)
          candidate)))))

(defun magik-extension-show-method ()
  "Display the Magik method containing point."
  (interactive)
  (message "Current Magik method: %s"
           (or (magik-extension-current-method)
               "not inside a method")))

(define-key magik-extension-mode-map (kbd "C-c m ?")
  #'magik-extension-show-method)

The regular expression is a starting point, not a complete Magik parser. It will work with common definitions such as _method _self.calculate_length() and can be extended when your codebase uses different receiver syntax. Test it against methods with parameters, comments, line breaks, and nested blocks. A false result is preferable to a command that silently reports the wrong method during a production change.

This small feature already creates a path towards method navigation. The command could later call xref-find-definitions, use an index generated from Magik source, or display matching methods in another buffer. In a Perth network-utility project, that could help developers move between custom network objects and the framework methods they override without repeatedly searching several source directories.

Test and debug in a controlled buffer

Test the extension in a scratch file before using it on an important product repository. Include a few representative Magik definitions, comments, long method names, and blank lines. Confirm that the insertion command places the cursor inside the new method and that the current-method command returns the expected name.

Emacs provides useful inspection commands when a function does not behave as expected. Use M-x describe-function to inspect a command, M-x describe-variable to inspect the keymap, and M-x toggle-debug-on-error before reproducing an error. M-x emacs-version can reveal whether an older corporate workstation is missing a library function available in newer Emacs releases.

Indentation deserves particular attention. The example calls indent-according-to-mode, which delegates formatting to the installed Magik major mode. If the mode does not indent the inserted body correctly, the problem may be in the major mode rather than your extension. Avoid embedding a large formatting system in the first version; keeping formatting delegated makes the helper easier to maintain across different Smallworld environments.

You can add a basic automated test without opening a graphical Emacs session:

(require 'ert)

(ert-deftest magik-extension-inserts-method ()
  (with-temp-buffer
    (magik-extension-insert-method "inspect_network")
    (should (equal (buffer-string)
                   "_method _self.inspect_network()\n  \n_endmethod\n"))))

Run the test with M-x ert and choose magik-extension-inserts-method. Tests become valuable when the extension gains commands for folding, debugging, or object inspection, because a change to one helper can otherwise affect several workflows.

Turn the helper into a team tool

Once the command works, improve the interface before adding many features. A prefix argument could ask for a receiver or insert a different template. A custom variable could control indentation, documentation comments, or whether the cursor lands on the first body line. Emacs users expect customisation through defcustom, so avoid scattering fixed paths and organisation-specific names through the code.

For example, a template variable keeps local conventions separate from command logic:

(defcustom magik-extension-method-template
  "_method _self.%s()\n  \n_endmethod\n"
  "Template used when inserting a Magik method."
  :type 'string
  :group 'magik-extension)

;; In the command, replace the format string with:
(insert (format magik-extension-method-template method-name))

Package the file with a descriptive header, document each interactive command, and keep the provide form at the end. If the extension grows beyond a few commands, split features into files such as magik-extension-navigation.el and magik-extension-inspection.el. A simple Git repository with a README, installation instructions, and a short changelog is enough for an internal package.

This is especially practical for Australian organisations where development teams may be distributed between Sydney, Adelaide, Melbourne, and remote project sites. A shared extension reduces variation between laptops and makes onboarding easier for consultants moving between clients. Keep the package independent from confidential schemas, customer data, and hard-coded paths so it can support several Smallworld installations safely.

Extend the workflow beyond insertion

The method generator is a foundation rather than the final destination. The same minor mode can expose commands for jumping to _endmethod, folding the current definition, opening a related class, or sending a selected expression to a Magik development session. Each command should have one clear responsibility and a predictable key binding.

A practical next feature is a command that narrows the current buffer to method definitions or builds an index of method names. Another is an object-inspection helper that sends a selected variable to the appropriate Magik console. These features need knowledge of the local runtime and connection process, so implement them only after documenting how your team starts, debugs, and authenticates its Smallworld environment.

Keep Emacs Lisp and Magik responsibilities distinct. Emacs Lisp manages buffers, keymaps, navigation, and process interaction; Magik remains the language used for application behaviour and domain logic. That separation makes the extension easier to test and reduces the risk of coupling an editor convenience to one customer’s data model.

Save magik-extension.el, load it in a test buffer, and commit the working version to your team’s configuration repository. Then use the same foundation to add the Magik navigation, inspection, folding, and debugging features that provide the greatest benefit in your Smallworld projects.

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