lab 59 - acme SAC


lab 59 - acme stand alone complex


A project that's been on my mind for quite a while is to package Inferno's acme as a stand alone editor. I only had Windows in mind as a target host, but the work should be quite easy to reproduce on other hosts.

I wanted the editor to blend well with the host system, and work as a substitute for other popular programmer editors such as vim, emacs, or jedit. Acme and Inferno being already stable and mature, there were only a few things I felt needed to be in place for this to work.

  • cut & paste between the host and acme (lab 55)
  • acme to resize with the host window
  • dead simple packaging and install of acme on windows.

This lab covers the code to do the acme resize with host windows.

I copied the code from /emu/port/devpointer.c and made devwmsz.c. The code is almost identical except for the name changes. This device holds a short queue of window resize events and serves a file /dev/wmsize that's the same format as /dev/pointer with x and y fields representing the width and height of the host window.

I modified acme directly to support this new device instead of modifying wm modules, which might have been more appropriate, I'm not sure. I added a new thread to /acme/gui.b to listen for resize events and resize the acme window appropriately.

startwmsize(): chan of Rect
 rchan := chan of Rect;
 fd := sys->open("/dev/wmsize", Sys->OREAD);
 if(fd == nil)
  return rchan;
 sync := chan of int;
 spawn wmsizeproc(sync, fd, rchan);
 return rchan;

wmsizeproc(sync: chan of int, 
 fd: ref Sys->FD, ptr: chan of Rect)
 sync <-= sys->pctl(0, nil);

 b:= array[Wmsize] of byte;
 while(sys->read(fd, b, len b) > 0){
  p := bytes2rect(b);
  if(p != nil)
   ptr <-= *p;

/appl/acme/gui.b:/^eventproc/ responds to the new event on the channel from wmsizeproc,

 wmsize := startwmsize();
 for(;;) alt{
 wmsz := <-wmsize =>
  win.image = win.screen.newwindow(wmsz, 
   Draw->Refnone, Draw->Nofill);
  p := ref zpointer;
  mainwin = win.image;
  p.buttons = Acme->M_RESIZE;
  cmouse <-= p;

I copied similar code into /appl/wm/wm.b so the standard window manager resizes with the host window (included in this lab's files). After using it a little I think I prefer it not resizing.

I use Acme:SAC as my main environment now, opening up another Inferno session when I want to do graphics work. I think the smoother integration with the host window system is a big win. It feels more like just an editor, neatly hiding a very powerful operating system behind it. I think Acme is one of the jewels of Inferno. Packaging it in this way may lead more people to discover Inferno through Acme. It could provide an easier introduction to the system and allow new users to start doing real work with Acme within a few clicks of downloading the package.

I've created a page for the Acme:SAC download where I'll post updates as I try to improve the packaging. The download is based on the emu from 20060227 Inferno release and my dried dung inferno tree.

Acme: Stand Alone Complex


Tony said…
That has to be one of the cooler hacks I have seen. Using "Get" on /dev/snarf just kinda freaked me out at first. WOW!!
Anonymous said…
where can i find out how/if i can use some advanced edit techniques in acme, e.g. folding (esp. hierarchically), syntax coloring / checking / prompting, mapping Fn-keys, having multiple viewports on the same buffer, dragging text blocks, etc.?

caerwyn said…
you should start by reading the acme(1) manual page, and the paper by Rob Pike.

to find out more about advanced editing techniques read Pike's paper on structural regular expressions and maybe even the sam tutorial, which mostly applies to the acme Edit command.

getting a little deeper into the system, you should read about plumbing which is integrated into acme.

getting deeper still, you'll need to discover more about the Inferno OS upon which this acme implementation is based. because then you can do scripting and plugins to Acme.

Popular posts from this blog

lab 110 - inferno archive edition

lab 107 - midiplay

lab 111 - wavloop