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
Renaming Magik Variables Across a File With Emacs' Iedit Mode
A method in a Magik session at a Sydney utilities provider can easily stretch to forty or fifty lines, with parameters passed into deeply nested _if statements and reused across half a dozen collection iterations. Renaming one of those parameters, say _counter to _record_count, by hand is the sort of job that quietly eats an arvo. Each occurrence has to be tracked, the case in the slot accessor has to match, and the comment block at the top of the method almost always has to be updated too. A naive search-and-replace will catch string literals, gobble up send() calls, and leave you with code that no longer compiles.
Iedit is a small Emacs minor mode that turns this chore into a single keystroke. You point the cursor at a symbol, press a key, and every occurrence in the buffer is highlighted with a coloured overlay. Whatever you type replaces them all at once, and the cursor moves in lockstep. It is not flashy, and it is certainly not new, but for Magik programmers who already live inside Emacs it is the fastest way to rename a variable without breaking the surrounding code.
This article walks through the practical side of using Iedit inside a Magik buffer, from the first install line in your init file to advanced tricks for narrowing the scope of a rename. Along the way there is a comparison table weighing Iedit against query-replace, multiple-cursors and plain manual editing, plus a few notes on pitfalls specific to Magik syntax.
Why variable renaming in Magik deserves a dedicated workflow
Magik has conventions that make renaming more than a cosmetic exercise. The leading underscore on _self, _super, _private, _local and _optional is not just stylistic; the Magik compiler reads _self as the current method receiver and _super as the inherited chain. Misspelling one of those in a large refactor can change program behaviour in ways that a syntax checker will not catch for hours. Parameters reused inside a for loop or a deeply nested if statement are also common, which means a single identifier can appear fifteen or twenty times in a hundred-line method.
The risk goes beyond identifiers. A method body often contains string literals that use the same English words you might be renaming. A variable called name will collide with the literal 'unknown name' inside an error message, and a comment line beginning with # count the items will be caught by a blind replace. Australian Magik teams working on network data models for companies such as Jemena, SA Power Networks or APA Group regularly refactor shared modules, and the cost of a missed string or a corrupted slot accessor is felt at 02:00 AEST the next morning when a nightly job fails.
A dedicated workflow, then, is not about typing speed. It is about being able to see every occurrence in front of you, exclude the false matches, and commit the change as a single, reviewable unit. Iedit is built for exactly that.
Getting Iedit ready inside your Magik Emacs configuration
Modern Emacs distributions ship Iedit as a built-in library under the name iedit.el, so a fresh install on a developer laptop in Brisbane or Perth is usually a one-line change in your init file. If you are on a stripped-down build, the package is also available from MELPA under the name iedit. Adding (require 'iedit) to your Magik configuration is enough to make M-x iedit-mode available in any buffer, including magik-mode buffers.
The standard advice for Magik developers is to bind the toggle to something you can hit without leaving the home row. Many teams settle on C-; because it sits next to the C-x and C-c prefixes but is rarely used by other modes. A small hook in magik-mode-hook will wire the binding in automatically for every Magik buffer you open:
(add-hook 'magik-mode-hook
(lambda ()
(local-set-key (kbd "C-;") 'iedit-mode)))
A few more lines in the same hook can tighten the defaults. Setting iedit-toggle-key-default to (kbd "C-;") and turning on iedit-auto-narrow-to-defun means the mode will, by default, only highlight occurrences inside the current defun boundary when the symbol under the cursor is a known local. For a deeper tour of the configuration options that pair well with Magik, the core features archive on the Magik Emacs site collects the most useful recipes in one place.
A practical walkthrough of renaming a variable with Iedit
Open a Magik file and place the cursor on the variable you want to rename. Press the key you bound, in this case C-;. Every occurrence of the symbol in the visible buffer is immediately outlined with a coloured overlay, including occurrences inside the same defun and, unless you narrow, any matches in other methods below. The minibuffer shows the number of occurrences matched, which is a quick sanity check before you start typing.
Now type the new name. The overlay updates with each keystroke, and every highlighted site changes at once. There is no need to move the cursor; the next character goes wherever the next match was. If the new name turns out to be longer or shorter than the old one, Iedit pads or trims the surrounding whitespace so the column count stays roughly sensible, though you will still want to do a visual pass afterwards to clean up alignment.
Consider a concrete example. A method iterates over a smallworld collection, building a hash of record counts. The current parameter is _counter, used in a loop, a slot assignment and a print statement at the bottom. Hitting C-; while the cursor is on the first _counter highlights seven sites across four dozen lines of code. Typing _record_count in one pass renames all of them. A second C-; exits Iedit and returns to normal editing. From there, you can run magik-compile-buffer and, if you are working on a remote session over a slow link, save the file and let the Magik image reload the changes.
A couple of keystrokes are worth memorising for the times when the default scope is too wide. Pressing 0 while Iedit is active restricts the matches to the current defun only, which is the right answer for almost every rename in a Magik buffer. Pressing C-h opens the Iedit help, and pressing TAB cycles the overlay between all occurrences in the buffer, the current defun and a single line.
Comparing Iedit with other approaches
Before settling on Iedit, it is worth seeing how it stacks up against the alternatives a Magik developer is likely to try first. The table below summarises the trade-offs for a typical rename of a parameter used in a single method.
| Approach | Speed for one symbol | Safety with Magik syntax | Narrowing to current defun | Setup needed |
|---|---|---|---|---|
| Iedit | Very fast | High, symbol-aware and skips strings | Yes, with the 0 key |
One line in init |
query-replace-regexp |
Medium | Medium, depends on the regex | No, whole buffer | None |
multiple-cursors |
Medium | High, visual confirmation | Yes, by region | MELPA package |
| Manual edits | Slow | High, but error-prone | n/a | None |
Iedit wins on the combination that matters most for Magik work: it understands symbol boundaries, so 'count' inside a string is not touched, and it can be narrowed to a single method with a single keystroke. Query-replace-regexp is more flexible when the pattern is not a clean symbol, such as a Magik slot path of the form @a@b.c, but for ordinary variable renames it is more keystrokes and more chance of error. Multiple-cursors gives a similar visual experience and is a reasonable fallback for developers who already have it installed, though its narrowing model is region-based rather than syntactic.
The single biggest advantage of Iedit, though, is what happens after the rename. Because the buffer is updated in one pass, the diff you see in magit is a clean, atomic edit on a known symbol. A reviewer can read the change as a single refactor step, which is much easier to approve than the scattered hunks a blind query-replace tends to produce.
Try Iedit on your next Magik refactor
The first thing to watch for is shadowing. Magik allows a method parameter to share its name with a slot on _self, and a local declared with _local can shadow an outer-scope variable. Iedit does not parse scope, so if you point it at a symbol that is reused at a different lexical level it will happily rename both. The fix is the 0 key to restrict the match to the current defun, or a quick read of the highlight to confirm the colour is on the sites you actually want. A second pitfall involves method calls: Magik's message-passing syntax, object.method(arg), is a single token to Iedit, so renaming a variable called method will not touch the dot syntax, but renaming a method name itself will rename every call site in the buffer.
Refactoring and debugging do not mix well, either. If you have a magik-debugger session open with breakpoints set on the method you are about to change, exit the session first, run the rename, recompile the buffer, and only then re-enter the debugger. The same care you take when you transfer app data to a new device, checking twice before confirming, applies to refactoring a method that is currently being stepped through.
When the rename is done, the buffer saved and the Magik image recompiled, the rest of the workflow is no different from any other Magik edit. Stage the file in magit, write a commit message that names the method and the new identifier, and push to the shared branch. If your team is co-located, that is often the moment for a quick brekkie meeting to walk through the change; if you are working remotely from Adelaide or Hobart, drop a note in the team channel with the diff attached.
The Magik Emacs extensions, including the Iedit integration described here, are available for download from the project site, along with a growing library of screen-casts and tutorials for Magik developers working in the Australian utilities, mining and telecommunications sectors. Subscribe to the newsletter for new release notes, or get in touch with HydePark Consulting about tailored support for your team.
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.