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 MoreNine 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
Refactoring Magik Code with Emacs Query-Replace and Regex
Refactoring a mature Magik system often begins with a change that looks harmless: a renamed method, a clearer slot name, or a consistent spelling for an application concept. In a large GE Smallworld codebase, however, the same identifier may appear in method definitions, calls, comments, strings, documentation, and generated files. Emacs provides a controlled way to find those occurrences and change only the ones that belong to the refactoring.
The basic tools are query-replace and query-replace-regexp. The first handles exact text substitutions with confirmation for every match. The second adds pattern matching, grouping, word boundaries, and captured replacement text. Used with Magik-aware habits, these commands can support broad changes without turning a simple rename into a debugging exercise.
This is particularly useful for Australian Smallworld teams maintaining utilities, transport, cadastral, telecommunications, and mining systems. A development group may be split between Sydney, Melbourne, Brisbane, Perth, or regional offices, with engineers sharing repositories across different working hours. A repeatable Emacs workflow helps each developer apply the same change locally rather than relying on an informal search-and-edit process.
The safest approach treats a regular expression as a small refactoring program. First define the exact code pattern, then limit the search area, inspect matches interactively, and run Magik tests afterwards. Emacs makes each stage visible, while Magik’s dynamic object model makes semantic verification essential.
Start With A Narrow Refactoring Target
Before opening the replacement command, decide what must change and what must remain untouched. Suppose a legacy method is called asset_status, and the preferred name is asset_condition. An unrestricted replacement could alter a comment, a string displayed to users, or a similarly named method in an unrelated package. The intended target might instead be calls written as object.asset_status() within a selected directory of source buffers.
M-x query-replace is suitable when the old text is unambiguous. Enter the search text, enter the replacement, and Emacs visits each match. Press y to replace, n to skip, ! to replace all remaining matches, and q to stop. C-g cancels the command. When working in a region, activate the region before invoking the command so that the operation is restricted to the selected code.
A useful preparation step is to search first without changing anything. M-x occur can list matching lines in a separate buffer, while M-x grep or M-x project-find-regexp can show occurrences across a repository. This reconnaissance reveals whether the identifier appears in method names, calls, test fixtures, comments, or configuration files. It also prevents an engineer from editing generated output when the source definition is the real target.
Use Regex To Describe Magik Syntax
M-x query-replace-regexp, bound to C-M-% in standard Emacs, accepts an Emacs regular expression. A pattern such as:
asset_status
finds the same text wherever it occurs. To match the identifier as a complete symbol rather than as part of asset_status_old, use word or symbol boundaries where they fit the source text:
\<asset_status\>
Emacs uses \< and \> for word boundaries. \_< and \_> are symbol boundaries and can be preferable when an identifier is adjacent to punctuation. Boundary behaviour depends on the syntax table, so inspect a few matches rather than assuming that every Magik naming convention will be interpreted exactly as expected.
Regex becomes more valuable when a refactoring involves several forms. For example, calls may contain optional whitespace before parentheses:
asset_status[ \t]*(
This matches asset_status( and asset_status (. A literal period in a qualified expression must be escaped because . means “any character” in a regular expression:
\.[ \t]*asset_status\_>
Patterns should stay readable. A complicated expression that matches several unrelated constructs is difficult to review interactively. Separate replacements are usually safer than one clever expression, especially when a Magik package contains both public methods and internal helper methods with similar names.
Control Matching With Case And Scope
Emacs search commands commonly obey the value of case-fold-search. If it is non-nil, searches are case-insensitive in many buffers. Magik projects may follow a consistent naming style, but comments and imported code can contain different capitalisation. Check the actual setting before a large replacement, and use an exact case-sensitive search when the change is intended for one spelling only.
Scope is equally important. In a source buffer, mark a region with C-SPC, move to its end, and run the replacement command. For multiple files, use a project search to identify candidates, then visit and edit only the relevant files. M-x dired can also be useful for marking Magik source files before applying a controlled operation to their contents.
Do not assume that every file returned by a repository search is safe to edit. Smallworld installations often contain locally generated code, vendor packages, migration scripts, and site-specific customisations. Australian organisations may also separate development, staging, and production support repositories for audit reasons. Keep the replacement within the development checkout and review version-control status before committing.
Capture Structure For Consistent Renames
Regular expressions can capture part of a match and reuse it in the replacement. Parentheses create capture groups, and \1, \2, and similar references insert captured text in the replacement. For example, a family of method names might be normalised from a prefix such as old_:
\<old_\([a-z][a-z0-9_]*\)\>
A replacement of:
new_\1
turns old_length into new_length while retaining the variable suffix. The exact expression should reflect the project’s identifier rules; if uppercase letters or additional punctuation are valid, include them deliberately rather than broadening the match by accident.
Replacement text has its own special syntax. \& inserts the entire matched text, while \1 inserts the first captured group. A literal backslash may need escaping, and replacement strings containing backslashes or special characters deserve a test on a small buffer first. Use C-h f on query-replace-regexp to check the installed Emacs documentation when uncertain about replacement syntax.
A useful technique is to preserve context while changing one component. If a method call includes a receiver and method name, capture the receiver:
\([A-Za-z][A-Za-z0-9_]*\)\.[ \t]*asset_status\_>
and replace it with:
\1.asset_condition
This is still a textual transformation, not a Magik parser. It will not understand whether the receiver has the expected class or whether a method is supplied dynamically. Treat captures as a way to reduce typing and preserve visible structure, not as proof of semantic correctness.
Review Matches Before Accepting Them
Interactive confirmation is the main safety feature of query-replace-regexp. At each match, Emacs displays the surrounding source so you can decide whether to replace it. Use n for a false positive, y for a correct match, and ! only after the remaining matches have been inspected enough to justify a bulk change. SPC can move through matches without replacing them in many query-replace interactions, while q provides an immediate exit.
For difficult patterns, create a temporary scratch buffer containing representative Magik examples. Include method definitions, method calls, comments, string literals, qualified names, whitespace variations, and near misses. Run the expression there before touching the repository. This makes it easy to test whether \<, \_>, parentheses, character classes, and replacement groups behave as intended.
After a replacement, use M-x diff-buffer-with-file or the version-control diff to inspect every changed line. A diff often exposes an unintended edit more clearly than the original interactive prompt. Check for changes in comments, quoted user messages, test data, generated files, and documentation. If the result is wrong, undo immediately with C-x u or use version control to restore the affected files before refining the expression.
Verify Magik Behaviour After Textual Changes
A successful replacement only proves that text changed. Magik code can depend on inheritance, method lookup, mixins, dynamic variables, and runtime-created objects. Renaming a method definition without updating every invocation can produce failures only when a particular object path is exercised. Conversely, changing a common name in a comment or string may be harmless, while missing a dynamically assembled selector may be significant.
Search for both the old and new names after the edit. The old name should remain only where it is intentionally supported, documented, or handled by a compatibility layer. Review method definitions and calls together, then run the project’s normal compilation, load, and test procedures. Where available, use Magik debugging and object inspection tools to verify that the expected class responds to the renamed method.
Pay attention to database and collection code. A replacement inside a query expression, collection iterator, attribute name, or external import can alter data behaviour without producing a syntax error. Test representative records and empty collections, and review any scripts that write to persistent Smallworld databases. If logs or fixtures include customer, property, or network information, follow the organisation’s handling rules and the Australian Privacy Act 1988 before copying examples outside the approved environment.
Make Refactoring Repeatable Across Teams
A one-off interactive replacement is valuable, but a documented command sequence is easier to audit and repeat. Record the old pattern, the new text, the intended file scope, and the validation commands in the change description. Store reusable Emacs Lisp only when the operation is genuinely recurring and the pattern has clear tests. A small helper can set case-fold-search, narrow the buffer, and call query-replace-regexp, but automation should preserve a reviewable diff.
Teams working across Australian offices can benefit from agreeing on a common Emacs configuration and project search conventions. A Melbourne developer and a Perth developer should obtain comparable results from the same repository state, even when local shell tools or operating systems differ. Keep editor customisations in version control, and avoid depending on an unrecorded personal syntax-table setting.
Consider the operational context as well. Utility and telecommunications projects may fall within security obligations associated with critical infrastructure, while customer records and location data require careful access control. Do not paste production extracts into a scratch buffer that is synchronised to an unmanaged cloud service. Use synthetic examples when testing regular expressions and keep refactoring logs free of sensitive data.
| Task | Emacs command or technique | Best use | Main precaution |
|---|---|---|---|
| Exact rename | M-x query-replace |
One unambiguous identifier | Limit the region or files |
| Patterned rename | C-M-% / query-replace-regexp |
Whitespace, boundaries, and variants | Test the expression first |
| Repository discovery | M-x project-find-regexp |
Finding definitions and calls | Exclude generated or vendor files |
| Match review | M-x occur and version-control diff |
Auditing possible changes | Inspect comments and strings |
| Structural reuse | Capture groups such as \1 |
Preserving receivers or suffixes | Remember this is not a parser |
| Behavioural validation | Magik tests, loading, debugging | Confirming method dispatch and data logic | Check persistent database effects |
A dependable refactoring routine is therefore simple: search broadly, narrow the target, test the expression, replace interactively, inspect the diff, and validate Magik behaviour. Emacs supplies the precision and reversibility; the developer supplies knowledge of the object model and the application domain.
Build a small library of tested patterns for the renames your team performs regularly, and keep each one paired with an example and a rollback path. Use query-replace as a deliberate code-maintenance tool rather than a blind global edit, and make your next Magik refactoring safer, faster, and easier for the whole team to review.
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
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.
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.
Screen-cast 7: Magik Debugger
Useful tools for application developers: Object Inspector and Magik Debugger with breakpoints and slot/variable monitoring.
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.