2
1
Fork
You've already forked ma
1
A minimalistic clone of the "acme" editor
  • Tcl 95%
  • C 4.3%
  • Shell 0.7%
Find a file
2026年07月09日 12:07:07 +02:00
awd initial import 2026年04月01日 23:59:48 +02:00
B typo fix 2026年07月09日 12:06:30 +02:00
build initial import 2026年04月01日 23:59:48 +02:00
h initial import 2026年04月01日 23:59:48 +02:00
ma Windows-keys "leap" back and forth 2026年07月09日 12:07:07 +02:00
pty.c initial import 2026年04月01日 23:59:48 +02:00
README update doc 2026年07月05日 23:23:37 +02:00
win initial import 2026年04月01日 23:59:48 +02:00

88,dPYba,,adPYba, ,adPPYYba,
88P' "88" "8a "" `Y8
88 88 88 ,adPPPPP88
88 88 88 88, ,88
88 88 88 `"8bbdP"Y8
"ma" is a minimalistic clone of the acme[1] editor used in Plan 9,
and is written in Tcl/Tk. It has been tested with Tcl/Tk 8.5, mostly
under Linux and OpenBSD. "ma" has successfully been run on Mac OS
X with XQuartz, but needs a tiling window manager to be used in a
satisfactory way.
Note that this editor is single-window based - it doesn't provide
multiple windows, nor does it manage them in any way (this is
delegated to the window manager.)
Installation:
Invoke
 ./build
and put the files "ma", "awd", "win", "pty" and "B" in your
PATH.
Usage:
"ma" attempts to work as much as possible like acme, but does no
own window-management. Configuration is done in the file "~/.ma",
holding Tcl code to modify fonts, colors, etc. A number of
command-line options can be provided to set various of these options
and to run "ma" in special modes.
Inter-window communication is implemented using the Tk "send"
command, so X-forwarding must be disabled (enter "xhost" to see
wether this is the case). "ma" should still run, but features related
to the registry will not be available in this case (locating already
open windows, and "Putall".)
The "B" shell script takes one ore more filenames (optionally followed
by an address) and opens the given files or activates already open
windows holding these files.
"pty" is a generic program running a subprocess in a pseudo terminal
and is used by "win" to have interactive windows inside a "ma"
instance. Note that this is currently very crude and does not support
escape codes of any kind.
"awd" sets the label of the window in which the command is executed.
You can create an alias for "cd" to set the label automatically
when used inside an interactive shell window:
alias cd="_cd"
function _cd () {
 \cd "$@"
 if test -n "$MA"; then
 awd bash
 fi
}
"h" searches the command history for a matching line and prints out
matching lines. If no arguments are given, the last 20 entries are
shown. For this the "history_file" variable must be set in your
configuration file, or the MA_HISTORY environment variable must be
set.
When you create a new, unnamed window and want to save it, then
just edit the filename in the tag (initially "UNNAMED"). Also saving
the file under a different name can be done the same way.
Environment variables:
MA_HISTORY
 If set, all code that is executed in "win" mode or via B2 is logged in
 the file given in this variable (this includes all input, including
 passwords!)
C_INCLUDE_PATH
 Lists additional include-directories, separated by ":" (default:
 "/usr/include")
SHELL
 Shell to use for executing commands (default: "bash")
MA
 Set to the name of the wish(1) instance when executing external
 programs.
Customization:
At the start of the "ma" script, you will find a number of global
variables that hold default values for fonts, colors and other
settings that are used throughtout the editor. Modify these at
your convenience. Alternatively, set variables and define functions
in the Tcl file "$HOME/.ma", which is loaded when ma start up
Extending:
The easiest way to add commands is simply to put scripts or programs
in your PATH. If you want more thorough integration, you can also
define commands at the Tcl level, by using "DefineCommand REGEX
EXPR" to define Tcl code to be executed when the command given in
REGEX is executed, i.e.
 DefineCommand {^MyCommand\s+(.+)$} { ... }
Arguments (subpatterns in the regex) can be extracted with "GetArg".
"ma" is not finished, and probably never will. For more information,
consult the source code or contact me[3].
Shortcomings:
- the "Kill" command (Del key) is not very reliable with respect to
 what processes are killed (should probably use a process group)
- autosnarf when selecting: no idea how to do this, keeping current
 selection and copying when selection gets empty doesn't work,
 since selection by mouse apparently clears it in between
 movements; perhaps detect when selection changes from non-empty
 to empty
- "Zerox" is implemented but quite limited: saving a zeroxed window
 will update the original "ma" instance (and other zeroxed copies),
 but only when they have not been modified since they were create.
- works very bad on Mac/Aqua and Windows:
 - Mac: default Tcl/Tk crashes, freshly installed (Aqua) aborts
 unexpectedly, B2/B3 are swapped, slow startup (note that
 Tcl/Tk for XQuartz works surprisingly well, though)
 - Windows: cursor in text widget barely visible (black, even on
 dark background), startup very slow, binding Ctrl-keys doesn't
 seem to work, UpdateTag doesn't seem to treat filename as valid
 and inserts Win-style path before it (this is with Active
 State Tcl/Tk, 8.6.4)
- there is no backup-file
- Address syntax only supports a subset of acme/sam and is rather
 crude (see also comment in ParseAddr), "/.../"/"?...?" addresses
 only select a position, not ranges
- In "win" mode, "ma" tries to ignore the prompt from input lines,
 but moving the insertion point may confuse this, if possible use
 a prompt for interactively used programs that will be ignored
 by the client program (e.g. ":;" for sh(1) or ";" for rc(1))
- Password-entry in "win" mode works only when the insertion cursor
 is not moved by mouse or cursor-movement keys
- "Putall" is implemented, but will save all files in all open
 windows, even on virtual screens not currently visible
- there is no "Edit" command
- necessary access to state of undo-stack is only available in
 Tcl/Tk 8.6, so "Undo"/"Redo" is not added to tag on demand.
Differences to the Plan 9 acme:
- Tab does not insert "\t" but whitespace.
- (obviously) single-window mode.
- no dynamic update of undo/redo commands tag.
- automatically does chmod a+x when saving file beginning with "#!/".
- missing commands: "Zerox", "Edit", "Incl".
- supports Key-Up/Down movement by line.
- inserting with active selection doesn't snarf.
- executing with redirection ("|...", ">...", "<...") in "win"
 mode invokes shell, and does not send the command to the process
 running in the window.
- executing in tag or body always has current window as context.
- double-clicking opening bracket selects forward, but quote-
 scanning works backwards (in acme both bracket and quotes only
 select backwards).
- indent-mode works differently.
- word under cursor is defined as ws-delimited (excluding
 parentheses).
- win-mode: pressing RETURN before current insert point sends the
 whole line.
- "noscroll" mode is much weaker (does not block running process).
- basic keyboard commands for mouse-less operation:
 C-1 (toggle focus), C-2 (execute selection), C-3 (acquire
 selection).
- "//.../" address means search for plain string, not regex.
- Supports various emacsish keyboard sequences, as provided by the
 Tk text widget.
- C-t transposes characters, C-q terminates (like "Del"), C-k deletes 
 from dot to end of line, C-p selects the paragraph.
- In "win" mode, C-r shows the last command entered. In
 normal editing mod C-r repeats the previous line.
- Additional commands:
 Anchor: add address of insertion point into tag
 Withdraw: hide window
 Tcl CODE: execute Tcl code
 Crnl: toggle between UNIX/DOS line-terminator encoding
 Interrupt: send ^C to interactive subprocess (win mode)
- MA highlights matching parens/brackets/braces.
- Shift-B3 is equivalent to B2.
- C-B3 searches backwards.
- Acquiring (B3) an existing window doesn't warp mouse to current
 selection.
- "Look" without a selection searches the last string any
 running instance (including the current one) was searching for.
- The "Local" command toggles a state whether directories are
 opened in the current window or in a new one
- "Abort" terminates, like "Del", but with an exit status of 1
- "Wrap" toggles between word-wrapping and char-wrapping.
- Closing a window does not warp mouse pointer to "Del" of next 
 active window.
- The Windows keys (Super_L and Super_R) search backwards and 
 forwards, respectively, equivalent to pressing B3 (Super_R)
 and Control-B3 (Super_L).
Idioms:
* Remember that you have filename completion (^F) everywhere
* Select command in tag and B2 to use it like a custom button, this
 is especially useful in win-mode, by adding often repeated
 commands in the tag
* In interactive programs running in a "win" window, any command or
 line of commands can be B2-clicked to insert it when input is
 requested, this also works for B2B1 chords.
* Avoid the console, a temporary guide file with commands reduces
 typing
* use "|sed s/.../g" to perform replacements in selection
* Select and B2 "<cat FILENAME" to insert into current position
* use "env ... COMMAND" to override env-vars when using B3
* Double-click words to quickly select them and avoid sweeping
* Double-click start or end of line to select whole line
* Quote or parenthesize commands that contain whitespace to
 quickly select them
* Addresses like "FILENAME:/.../" or "FILENAME:LINE" can be used
 as simple hyperlinks
* B3 label in tag to select all text
* The tag can also be B2'd to execute a script you're working on
 (MA automatically saves as executable, if a she-bang line exists)
* You can write directly into directory windows and sweep (or B2B1)
 to execute commands on files, use "Get" command to refresh
* You can also simply enter and B2 commands into an "+Errors" window
* Double-B1 after end of line selects whole line for execution
* Use unique marker to separate sections in guide files to quickly
 jump around through use of B3
All of MA's source code is hereby placed in the public domain
Acknowledgements:
 Special thanks to:
 Lucas Sköldqvist for various tips and suggestions.
 "Kooda" for fixing the completely broken implementation of
 pty.c, he also fixed a problem with paren-matching in
 Tk 8.6.
 "mujo" for adding several improvements and corrections.
Version history:
15
 - Changed "B" into a shell script that properly redirects all I/O
 so when invoked from a shell (like "win"), closing the shell
 will not terminate spawned MA instances.
 - Added a simplified variant of the "Zerox" command (Thanks to
 Sam Hunter for an initial implementation and advice).
 - The Windows keys can be used for backward and forward search.
14
 - Simplify registry, drop ma-eval program.
 - Executing ">..." or "|..." without selection drop extra newline 
 at end.
 - Dropped "Back", Ctrl-B3 searches backwards.
 - Scroll-mode is enabled by default for "+Error" output windows.
 - "Dirty" state is designated by darker tag color instead of font
 change to minimize text-movement in tag.
 - More simplifications.
 - B2 in "win" mode adds selection to current line, behaving more
 like acme.
 - Added C-r (repeat last line), C-p (select paragraph).
 - Fixed broken handling of result values from plumbing rules.
 - "<" and ">" are not considered word-characters.
 - search with ":/.../" selects whole matching range and
 doesn't warp the mouse.
 - reloading a file retains the current visible area.
 - updates of the tag retain the current selection in the tag,
 if one exists.
13
 - Fix quoting issue with plumbing (thanks to "sterni").
12
 - Selection of word under the mouse cursor does not include
 "," or ";".
 - Selecting an initial position when opening a fresh window
 tries harder to make the selection visible.
 - C-r selects to end of file.
 - ESC now records the position after a button press moves
 the insertion point (this is more according to how I
 understand the behaviour in sam/acme).
 - B3 on address that involves search starts the search at
 the insertion point, not at the start of the file.
11
 - Esc selects newly typed text since last mouse button release
 (not press).
 - Increased scroll amount for Prior/Next keys.
 - Added "-fixed" command line option.
 - After tag-relayout, sensure insertion point in body remains
 visible.
 - The "pty" program passed the exit-status through to the
 caller.
 - When parsing a command line, the command may be enclosed in
 single or double quotes.
 - Use %K for detecting closing paren/bracket/brace instead of
 %A (thanks to Kooda).
 - Added "Abort" command.
 - B2 on scroll bar takes center of "thumb" as reference point.
 - Added "Wrap" command.
 - Fixed bug in Broadcast procedure (used in "Putall")
10
 - Saving into a nonexistent directory failed with an error instead of creating
 directories as needed.
 - The cursor shape is now the default left-pointing arrow on all platforms
 (thanks to "mujo")
 - Undo/Redo always applies to window body (fixed by "mujo")
 - Double-click B1B2 mousechord works now ("mujo", again)
9
 - Fixed a bug in "plumb" that caused a successful exit status even
 if no rule matched.
 - Separated variable and fixed font states.
 - Reversed the scrollbar colors, as in acme/sam/rio.
 - The "Insert" key does filename-completion, as alternative to Ctrl-F.
 - B1/B3 in scrollbar has "autorepeat", using dynamically adjusted
 amount.
8
 - B2 in win mode is equivalent to "Send" command.
 - Reduced some unnecessary "Flash"ing.
 - Executing with redirection keeps the result selected.
 - Getting the effective selection worked only when target widget had focus,
 resulting in selection/pseudoselection confusion.
 - In "win" mode the "Interrupt" command inserts ^C into the input stream.
 - Directory view should now format columns correctly after window has been
 shown for the first time.
 - Fixed a problem with plumbing a string beginning with Tcl redirection
 characters.
 - If the result-string of a remote call via "ma-eval" is empty, no
 output is produced.
 - The registry resolved symlinks before locating a file.
 - Executing with "|" or "<" tries to keep visible area.
7
 - Added "Local" command (suggested by C-Keen).
 - Attempt to optimize <<Selection>> event handler which seems to be slow
 on ssome machines.
 - B2 can now be used to abort B3-sweeping.
 - When "scroll" mode is off, try to keep start of output received by every external
 command at top of screen.
 - Pressing <Delete> sends SIGINT instead of SIGKILL now.
 - The "pty" programm catches SIGINT and propagates it to the process group.
 - Location of existing windows via registry handles spaces in directory names
 correctly.
 - Filenames with single quote in label are correctly quoted using double quotes.
 - Execution with redirection always uses body selection or whole body.
 - Dropped the "Replace" command (use an external tools like sed(1) or "LR"
 from ma-utils).
 - Re-activation of directory window refreshes contents.
6
 - C-k on end of line just deletes the newline and doesn't overwrite the cut buffer.
 - On-demand update of tag for "Put", "Back".
 - added read and write hooks.
 - "Look" doesn't warp mouse pointer.
 - All MA windows that are not directory listings or output windows track "dirty" state.
 - "Put <name>" always saves, regardless of the type of window.
 - Dotfiles command for directories.
 - Added several hooks for integrating the directory editor (diredit.tcl).
 - New files have a default name ("<unnamed>").
 - Removed tag marker, "dirty" state is indicated by tag font style (italic).
 - Double-B1 on empty line does not highlight line.
 - Extracted plumbing into separate tool ("plumb").
 - If the label is changed and the file does not exist yet, save text even if unmodified.
 - Removed "Wrap" and default to char-wrapping.
 - Renaming and saving output window properly reregisters the window.
5
 - When the label is updated, set the windows' title accordingly (suggested by Lucas Sköldqvist.)
 - added termination_hook.
 - Always enable word-wrap in win mode.
 - Computing the word under the cursor ignores the label marker character.
 - Added "Back" command to move insertion mark back to old position after search.
 - Replaced pty.c with a version that doesn't eat CPU time and is much simpler (thanks to
 Kooda)
4
 - Corrected initial tag relayout.
 - Resizing scrolls to bottom if "scroll" mode is on.
 - Dropped "-noscroll" option, added "-scroll".
 - Filename completion adds final "/" for directory only if it doesn't need quoting.
 - Added "name_hook", moved "project" files into extension.
 - Replaces some message-boxes with marked text in +Errors window.
 - Revertion shows message when file is modified, similar to "Del".
 - "Wrap" command is shown in tag by default.
 - "Get FNAME" checks whether the current file is modified.
3
 - "New" starts new instance in current context.
 - "Send" just appends at end (as in acme).
 - Added "Putall".
 - final delimiter in "/.../" + "?...?" addresses is optional now.
 - switching to existing window via B3 warps mouse pointer to current selection
 or insertion point.
 - got rid of spurious newlines in tag that where sometimes added.
 - directory listing quotes with "\"", when filename includes "\''".
 - text in tag window wraps correctly when the window is resized.
 - ESC selects up to insertion point at last mouse click, not the clicked location.
 - the "dirty" marker is filtered out in most cases of clicking the label.
 - (mostly) correct handling of backspace when entering passwords in win-mode.
 - B1B2B3 leaves file unmodified.
 - C-k snarfs deleted text.
 - B1-doubleclick in the empty space after a text line selects the complete line.
2
 - added some improvements in built-in plumbing rules.
 - the registry logs its actions inside its own text body.
 - the scroll-area is grayed in "scroll" mode.
 - failure to open file outputs error in "+Errors" window.
 - auto-detection of line-end translation, CRNL line-temrinators are preserved.
 - fixed problems in some uses of "catch" which didn't properly evaluate their arguments.
 - directory listings quote filenames, when necessary.
 - running subprocesses are now not killed on termination.
 - added MA_LABEL environment variable for subprocesses.
 - a clicked word does not include parentheses or brackets/braces now.
 - the history file is now made user-accessible only when written.
 - added (crude) support for password entry in win-mode.
 - added "-fontstyle" option.
1
 - initial release.
[1] http://acme.cat-v.org/
[2] https://www.gnu.org/software/emacs/
[3] felix@call-with-current-continuation.org
[4] http://www.cs.yorku.ca/~oz/wily/
[5] http://www.cs.yorku.ca/~oz/wily/python.html
[6] http://www.linusakesson.net/programming/syntaxhighlighting/
[7] https://www.robertmelton.com/project/syntax-highlighting-off/