2 |
- |
1 |
<?xml version="1.0" encoding="utf-8"?>
|
|
|
2 |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
|
3 |
"http://www.w3.org/TR/html4/loose.dtd">
|
|
|
4 |
<html>
|
|
|
5 |
<head>
|
|
|
6 |
<meta http-equiv=Content-Type content="text/html; charset=utf8">
|
|
|
7 |
<title>Acme: A User Interface for Programmers</title>
|
|
|
8 |
</meta>
|
|
|
9 |
</head>
|
|
|
10 |
<body>
|
|
|
11 |
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
|
|
|
12 |
<p style="margin-top: 0; margin-bottom: 0.21in"></p>
|
|
|
13 |
|
|
|
14 |
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
|
|
|
15 |
<span style="font-size: 12pt"><b>Acme: A User Interface for Programmers</b></span></p>
|
|
|
16 |
<p style="margin-top: 0; margin-bottom: 0.21in"></p>
|
|
|
17 |
|
|
|
18 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
19 |
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
|
|
|
20 |
<span style="font-size: 10pt"><i></i></span><span style="font-size: 10pt"><i>Rob Pike</i></span><span style="font-size: 10pt"><i></i></span></p>
|
|
|
21 |
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
|
|
|
22 |
<span style="font-size: 10pt"><i></i></span><span style="font-size: 10pt"><i>rob@plan9.bell-labs.com</i></span><span style="font-size: 10pt"><i></i></span></p>
|
|
|
23 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
24 |
|
|
|
25 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
26 |
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
|
|
|
27 |
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
|
|
|
28 |
<span style="font-size: 10pt"><i>ABSTRACT</i></span></p>
|
|
|
29 |
<p style="margin-top: 0; margin-bottom: 0.19in"></p>
|
|
|
30 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
31 |
|
|
|
32 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
33 |
|
|
|
34 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
35 |
|
|
|
36 |
<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.00in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
37 |
<span style="font-size: 10pt">A hybrid of window system, shell, and editor, Acme gives text-oriented
|
|
|
38 |
applications a clean, expressive, and consistent style of interaction.
|
|
|
39 |
Traditional window systems support interactive client programs and offer libraries of
|
|
|
40 |
pre-defined operations such as pop-up menus
|
|
|
41 |
and buttons to promote a consistent
|
|
|
42 |
user interface among the clients.
|
|
|
43 |
Acme instead provides its clients with a fixed user interface and
|
|
|
44 |
simple conventions to encourage its uniform use.
|
|
|
45 |
Clients access the facilities of Acme through a file system interface;
|
|
|
46 |
Acme is in part a file server that exports device-like files that may be
|
|
|
47 |
manipulated to access and control the contents of its windows.
|
|
|
48 |
Written in a concurrent programming language,
|
|
|
49 |
Acme is structured as a set of communicating processes that neatly subdivide
|
|
|
50 |
the various aspects of its tasks: display management, input, file server, and so on.
|
|
|
51 |
</span><span style="font-size: 10pt"></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
52 |
<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
53 |
<span style="font-size: 10pt">Acme attaches distinct functions to the three mouse buttons:
|
|
|
54 |
the left selects text;
|
|
|
55 |
the middle executes textual commands;
|
|
|
56 |
and the right combines context search and file opening
|
|
|
57 |
functions to integrate the various applications and files in
|
|
|
58 |
the system.
|
|
|
59 |
</span><span style="font-size: 10pt"></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
60 |
<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
61 |
<span style="font-size: 10pt">Acme works well enough to have developed
|
|
|
62 |
a community that uses it exclusively.
|
|
|
63 |
Although Acme discourages the traditional style of interaction
|
|
|
64 |
based on typescript windows—teletypes—its
|
|
|
65 |
users find Acme’s other services render
|
|
|
66 |
typescripts obsolete.
|
|
|
67 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
68 |
|
|
|
69 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
70 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
71 |
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
|
|
|
72 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
73 |
<span style="font-size: 10pt"><b>History and motivation
|
|
|
74 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
75 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
76 |
<span style="font-size: 10pt">The usual typescript style of interaction with
|
|
|
77 |
Unix and its relatives is an old one.
|
|
|
78 |
The typescript—an intermingling of textual commands and their
|
|
|
79 |
output—originates with the scrolls of paper on teletypes.
|
|
|
80 |
The advent of windowed terminals has given each user what
|
|
|
81 |
amounts to an array of teletypes, a limited and unimaginative
|
|
|
82 |
use of the powers of bitmap displays and mice.
|
|
|
83 |
Systems like the Macintosh
|
|
|
84 |
that do involve the mouse as an integral part of the interaction
|
|
|
85 |
are geared towards general users, not experts, and certainly
|
|
|
86 |
not programmers.
|
|
|
87 |
Software developers, at least on time-sharing systems, have been left behind.
|
|
|
88 |
</span></p><center><table width=60% cellspacing=0 cellpadding=0 border=0><tr height=1> <td width=1 bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td width=1 bgcolor=#000000 /></tr><tr height=10> <td width=1 bgcolor=#000000 /> <td width=10 /> <td /> <td width=10 /> <td width=1 bgcolor=#000000 /></tr>
|
|
|
89 |
<tr>
|
|
|
90 |
<td width=1 bgcolor=#000000 /><td width=10 /><td>
|
|
|
91 |
<center><a href="acme.fig1.gif"><img src="acme.fig1.gif" /></a></center>
|
|
|
92 |
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
93 |
<span style="font-size: 10pt">Figure 1. A small Acme screen—normally it runs on a larger display—demonstrating
|
|
|
94 |
some of the details discussed in the text.
|
|
|
95 |
The right column contains some guide files,
|
|
|
96 |
a mailbox presented by Acme’s mail program,
|
|
|
97 |
the columnated display of files in Acme’s own source directory,
|
|
|
98 |
a couple of windows from the OED browser,
|
|
|
99 |
a debugger window,
|
|
|
100 |
and an error window showing diagnostics from a compilation.
|
|
|
101 |
The left column holds a couple of source files
|
|
|
102 |
(</span><span style="font-size: 10pt"><tt>dat.h</tt></span><span style="font-size: 10pt">
|
|
|
103 |
and
|
|
|
104 |
</span><span style="font-size: 10pt"><tt>acme.l</tt></span><span style="font-size: 10pt">),
|
|
|
105 |
another debugger window displaying a stack trace,
|
|
|
106 |
and a third source file
|
|
|
107 |
(</span><span style="font-size: 10pt"><tt>time.l</tt></span><span style="font-size: 10pt">).
|
|
|
108 |
</span><span style="font-size: 10pt"><tt>Time.l</tt></span><span style="font-size: 10pt">
|
|
|
109 |
was opened from the debugger by clicking the right mouse button
|
|
|
110 |
on a line in the stack window;
|
|
|
111 |
the mouse cursor landed on the offending line of
|
|
|
112 |
</span><span style="font-size: 10pt"><tt>acme.l</tt></span><span style="font-size: 10pt">
|
|
|
113 |
after a click on the compiler message.
|
|
|
114 |
</span></p></td>
|
|
|
115 |
<td width=10 /><td width=1 bgcolor=#000000 />
|
|
|
116 |
</tr>
|
|
|
117 |
<tr height=10><td width=1 bgcolor=#000000 /> <td width=10 /><td /><td width=10 /> <td width=1 bgcolor=#000000 /></tr><tr height=1> <td width=1 bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td width=1 bgcolor=#000000 /></tr>
|
|
|
118 |
</table></center>
|
|
|
119 |
<p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
120 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
121 |
<span style="font-size: 10pt">Some programs have mouse-based editing of
|
|
|
122 |
text files and typescripts;
|
|
|
123 |
ones I have built include
|
|
|
124 |
the window systems
|
|
|
125 |
</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">
|
|
|
126 |
[Pike88]
|
|
|
127 |
and
|
|
|
128 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">
|
|
|
129 |
[Pike91]
|
|
|
130 |
and the text editor
|
|
|
131 |
Sam [Pike87].
|
|
|
132 |
These have put the programmer’s mouse to some productive work,
|
|
|
133 |
but not wholeheartedly. Even experienced users of these programs
|
|
|
134 |
often retype text that could be grabbed with the mouse,
|
|
|
135 |
partly because the menu-driven interface is imperfect
|
|
|
136 |
and partly because the various pieces are not well enough integrated.
|
|
|
137 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
138 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
139 |
<span style="font-size: 10pt">Other programs—EMACS [Stal93] is the prime example—offer a high
|
|
|
140 |
degree of integration but with a user interface built around the
|
|
|
141 |
ideas of cursor-addressed terminals that date from the 1970’s.
|
|
|
142 |
They are still keyboard-intensive and
|
|
|
143 |
dauntingly complex.
|
|
|
144 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
145 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
146 |
<span style="font-size: 10pt">The most ambitious attempt to face these issues was the Cedar
|
|
|
147 |
system, developed at Xerox [Swei86].
|
|
|
148 |
It combined a new programming language, compilers,
|
|
|
149 |
window system, even microcode—a complete system—to
|
|
|
150 |
construct a productive, highly
|
|
|
151 |
integrated and interactive environment
|
|
|
152 |
for experienced users of compiled languages.
|
|
|
153 |
Although successful internally, the system was so large
|
|
|
154 |
and so tied to specific hardware that it never fledged.
|
|
|
155 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
156 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
157 |
<span style="font-size: 10pt">Cedar was, however, the major inspiration for Oberon [Wirt89],
|
|
|
158 |
a system of similar scope but much smaller scale.
|
|
|
159 |
Through careful selection of Cedar’s ideas, Oberon shows
|
|
|
160 |
that its lessons can be applied to a small, coherent system
|
|
|
161 |
that can run efficiently on modest hardware.
|
|
|
162 |
In fact, Oberon probably
|
|
|
163 |
errs too far towards simplicity: a single-process system
|
|
|
164 |
with weak networking, it seems an architectural throwback.
|
|
|
165 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
166 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
167 |
<span style="font-size: 10pt">Acme is a new program,
|
|
|
168 |
a combined window system, editor, and shell,
|
|
|
169 |
that applies
|
|
|
170 |
some of the ideas distilled by Oberon.
|
|
|
171 |
Where Oberon uses objects and modules within a programming language (also called Oberon),
|
|
|
172 |
Acme uses files and commands within an existing operating system (Plan 9).
|
|
|
173 |
Unlike Oberon, Acme does not yet have support for graphical output, just text.
|
|
|
174 |
At least for now, the work on Acme has concentrated on
|
|
|
175 |
producing the smoothest user interface possible for a programmer
|
|
|
176 |
at work.
|
|
|
177 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
178 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
179 |
<span style="font-size: 10pt">The rest of this paper describes Acme’s interface,
|
|
|
180 |
explains how programs can access it,
|
|
|
181 |
compares it to existing systems,
|
|
|
182 |
and finally presents some unusual aspects of its implementation.
|
|
|
183 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
184 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
185 |
<span style="font-size: 10pt"><b>User interface
|
|
|
186 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
187 |
<center><table width=60% cellspacing=0 cellpadding=0 border=0><tr height=1> <td width=1 bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td width=1 bgcolor=#000000 /></tr><tr height=10> <td width=1 bgcolor=#000000 /> <td width=10 /> <td /> <td width=10 /> <td width=1 bgcolor=#000000 /></tr>
|
|
|
188 |
<tr>
|
|
|
189 |
<td width=1 bgcolor=#000000 /><td width=10 /><td>
|
|
|
190 |
<center><a href="acme.fig2.gif"><img src="acme.fig2.gif" /></a></center>
|
|
|
191 |
<p style="line-height: 1.2em; text-indent: 0.35in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
192 |
<span style="font-size: 10pt">Figure 2. An Acme window showing a section of code.
|
|
|
193 |
The upper line of text is the tag containing the file name,
|
|
|
194 |
relevant commands, and a scratch area (right of the vertical bar);
|
|
|
195 |
the lower portion of the window is the
|
|
|
196 |
body, or contents, of the file.
|
|
|
197 |
Here the scratch area contains a command for the middle button
|
|
|
198 |
(</span><span style="font-size: 10pt"><tt>mk</tt></span><span style="font-size: 10pt">)
|
|
|
199 |
and a word to search for with the right button
|
|
|
200 |
(</span><span style="font-size: 10pt"><tt>cxfidalloc</tt></span><span style="font-size: 10pt">).
|
|
|
201 |
The user has just
|
|
|
202 |
clicked the right button on
|
|
|
203 |
</span><span style="font-size: 10pt"><tt>cxfidalloc</tt></span><span style="font-size: 10pt">
|
|
|
204 |
and Acme has searched for the word, highlighted it,
|
|
|
205 |
and moved the mouse cursor there. The file has been modified:
|
|
|
206 |
the center of the layout box is black and the command
|
|
|
207 |
</span><span style="font-size: 10pt"><tt>Put</tt></span><span style="font-size: 10pt">
|
|
|
208 |
appears in the tag.
|
|
|
209 |
</span></p></td>
|
|
|
210 |
<td width=10 /><td width=1 bgcolor=#000000 />
|
|
|
211 |
</tr>
|
|
|
212 |
<tr height=10><td width=1 bgcolor=#000000 /> <td width=10 /><td /><td width=10 /> <td width=1 bgcolor=#000000 /></tr><tr height=1> <td width=1 bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td bgcolor=#000000 /> <td width=10 bgcolor=#000000 /> <td width=1 bgcolor=#000000 /></tr>
|
|
|
213 |
</table></center>
|
|
|
214 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
215 |
<span style="font-size: 10pt">Acme windows are arrayed in columns (Figure 1) and are used more
|
|
|
216 |
dynamically than in an environment like X Windows or
|
|
|
217 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">
|
|
|
218 |
[Sche86, Pike91].
|
|
|
219 |
The system frequently creates them automatically and the user
|
|
|
220 |
can order a new one with a single mouse button click.
|
|
|
221 |
The initial placement of a new window is determined
|
|
|
222 |
automatically, but the user may move an existing window anywhere
|
|
|
223 |
by clicking or dragging a
|
|
|
224 |
</span><span style="font-size: 10pt"><i>layout box</i></span><span style="font-size: 10pt">
|
|
|
225 |
in the upper left corner of
|
|
|
226 |
the window.
|
|
|
227 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
228 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
229 |
<span style="font-size: 10pt">Acme windows have two parts: a
|
|
|
230 |
</span><span style="font-size: 10pt"><i>tag</i></span><span style="font-size: 10pt">
|
|
|
231 |
holding a single line of text,
|
|
|
232 |
above a
|
|
|
233 |
</span><span style="font-size: 10pt"><i>body</i></span><span style="font-size: 10pt">
|
|
|
234 |
holding zero or more lines (Figure 2).
|
|
|
235 |
The body typically contains an image of a file being edited
|
|
|
236 |
or the editable output of a
|
|
|
237 |
program, analogous to an
|
|
|
238 |
EMACS shell
|
|
|
239 |
window. The tag contains
|
|
|
240 |
the name of the window
|
|
|
241 |
(usually the name of the associated
|
|
|
242 |
file or directory), some built-in commands, and a scratch area to hold arbitrary text.
|
|
|
243 |
If a window represents a directory, the name in the tag ends with
|
|
|
244 |
a slash and the body contains a list of the names of the files
|
|
|
245 |
in the directory.
|
|
|
246 |
Finally, each non-empty body holds a scroll bar at the left of the text.
|
|
|
247 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
248 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
249 |
<span style="font-size: 10pt">Each column of windows also has a layout box and a tag.
|
|
|
250 |
The tag has no special meaning, although Acme pre-loads it with a few
|
|
|
251 |
built-in commands.
|
|
|
252 |
There is also a tag across the whole display, also loaded with
|
|
|
253 |
helpful commands and a list of active processes started
|
|
|
254 |
by Acme.
|
|
|
255 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
256 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
257 |
<span style="font-size: 10pt">Typing with the keyboard and selecting with the left button are as in
|
|
|
258 |
many other systems, including the Macintosh,
|
|
|
259 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">,
|
|
|
260 |
and Sam.
|
|
|
261 |
The middle and right buttons are used, somewhat like the left button,
|
|
|
262 |
to ‘sweep’ text, but the indicated text is treated in a way
|
|
|
263 |
that depends on the text’s location—</span><span style="font-size: 10pt"><i>context</i></span><span style="font-size: 10pt">—as well as its content.
|
|
|
264 |
This context, based on the directory of the file containing the text,
|
|
|
265 |
is a central component of Acme’s style of interaction.
|
|
|
266 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
267 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
268 |
<span style="font-size: 10pt">Acme has no single notion of ‘current directory’.
|
|
|
269 |
Instead, every command, file name,
|
|
|
270 |
action, and so on is interpreted or executed in the directory named by the
|
|
|
271 |
tag of the window containing the command. For example, the string
|
|
|
272 |
</span><span style="font-size: 10pt"><tt>mammals</tt></span><span style="font-size: 10pt">
|
|
|
273 |
in a window labeled
|
|
|
274 |
</span><span style="font-size: 10pt"><tt>/lib/</tt></span><span style="font-size: 10pt">
|
|
|
275 |
or
|
|
|
276 |
</span><span style="font-size: 10pt"><tt>/lib/insects</tt></span><span style="font-size: 10pt">
|
|
|
277 |
will be interpreted as the file name
|
|
|
278 |
</span><span style="font-size: 10pt"><tt>/lib/mammals</tt></span><span style="font-size: 10pt">
|
|
|
279 |
if such a file exists.
|
|
|
280 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
281 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
282 |
<span style="font-size: 10pt">Throughout Acme, the middle mouse button is used to execute commands
|
|
|
283 |
and the right mouse button is used to locate and select files and text.
|
|
|
284 |
Even when there are no true files on which to operate—for example
|
|
|
285 |
when editing mail messages—Acme and its applications use
|
|
|
286 |
consistent extensions of these basic functions.
|
|
|
287 |
This idea is as vital to Acme as icons are to the Macintosh.
|
|
|
288 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
289 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
290 |
<span style="font-size: 10pt">The middle button executes commands: text swept with the button
|
|
|
291 |
pressed is underlined; when the button is released, the underline is
|
|
|
292 |
removed and the indicated text is executed.
|
|
|
293 |
A modest number of commands are recognized as built-ins: words like
|
|
|
294 |
</span><span style="font-size: 10pt"><tt>Cut</tt></span><span style="font-size: 10pt">,
|
|
|
295 |
</span><span style="font-size: 10pt"><tt>Paste</tt></span><span style="font-size: 10pt">,
|
|
|
296 |
and
|
|
|
297 |
</span><span style="font-size: 10pt"><tt>New</tt></span><span style="font-size: 10pt">
|
|
|
298 |
name
|
|
|
299 |
functions performed directly by Acme.
|
|
|
300 |
These words often appear in tags to make them always available,
|
|
|
301 |
but the tags are not menus: any text anywhere in Acme may be a command.
|
|
|
302 |
For example, in the tag or body of any window one may type
|
|
|
303 |
</span><span style="font-size: 10pt"><tt>Cut</tt></span><span style="font-size: 10pt">,
|
|
|
304 |
select it with the left button, use the middle button to execute it,
|
|
|
305 |
and watch it disappear again.
|
|
|
306 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
307 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
308 |
<span style="font-size: 10pt">If the middle button indicates a command that is not recognized as a built-in,
|
|
|
309 |
it is executed in the directory
|
|
|
310 |
named by the tag of the window holding the text.
|
|
|
311 |
Also, the file to be executed is searched for first in that directory.
|
|
|
312 |
Standard input is connected to
|
|
|
313 |
</span><span style="font-size: 10pt"><tt>/dev/null</tt></span><span style="font-size: 10pt">,
|
|
|
314 |
but standard and error outputs are connected to an Acme window,
|
|
|
315 |
created if needed, called
|
|
|
316 |
</span><span style="font-size: 10pt"><i>dir</i></span><span style="font-size: 10pt"><tt>/+Errors</tt></span><span style="font-size: 10pt"> where
|
|
|
317 |
</span><span style="font-size: 10pt"><i>dir</i></span><span style="font-size: 10pt">
|
|
|
318 |
is the directory of the window.
|
|
|
319 |
(Programs that need interactive input use a different interface, described below.)
|
|
|
320 |
A typical use of this is to type
|
|
|
321 |
</span><span style="font-size: 10pt"><tt>mk</tt></span><span style="font-size: 10pt">
|
|
|
322 |
(Plan 9’s
|
|
|
323 |
</span><span style="font-size: 10pt"><tt>make</tt></span><span style="font-size: 10pt">)
|
|
|
324 |
in the scratch area in the tag of a C source window, say
|
|
|
325 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/sam/regexp.c</tt></span><span style="font-size: 10pt">,
|
|
|
326 |
and execute it.
|
|
|
327 |
Output, including compiler errors, appears in the window labeled
|
|
|
328 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/sam/+Errors</tt></span><span style="font-size: 10pt">,
|
|
|
329 |
so file names in the output are associated with the windows and directory
|
|
|
330 |
holding the source.
|
|
|
331 |
The
|
|
|
332 |
</span><span style="font-size: 10pt"><tt>mk</tt></span><span style="font-size: 10pt">
|
|
|
333 |
command remains in the tag, serving as a sort of menu item for the associated
|
|
|
334 |
window.
|
|
|
335 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
336 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
337 |
<span style="font-size: 10pt">Like the middle button, the right button is used to indicate text by sweeping it out.
|
|
|
338 |
The indicated text is not a command, however, but the argument of a generalized
|
|
|
339 |
search operator.
|
|
|
340 |
If the text, perhaps after appending it to the directory of the window containing it,
|
|
|
341 |
is the name of an existing file, Acme creates a new window to hold the file
|
|
|
342 |
and reads it in. It then moves the mouse cursor to that window. If the file is
|
|
|
343 |
already loaded into Acme, the mouse motion happens but no new window is made.
|
|
|
344 |
For example, indicating the string
|
|
|
345 |
</span><span style="font-size: 10pt"><tt>sam.h</tt></span><span style="font-size: 10pt">
|
|
|
346 |
in
|
|
|
347 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
348 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
349 |
<span style="font-size: 9pt"><tt>#include "sam.h"</tt></span></p>
|
|
|
350 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
351 |
|
|
|
352 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
353 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
354 |
<span style="font-size: 10pt">in a window on the file
|
|
|
355 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/sam/regexp.c</tt></span><span style="font-size: 10pt">
|
|
|
356 |
will open the file
|
|
|
357 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/sam/sam.h</tt></span><span style="font-size: 10pt">.
|
|
|
358 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
359 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
360 |
<span style="font-size: 10pt">If the file name is followed immediately by a colon and a legal address in
|
|
|
361 |
Sam notation (for example a line number or a regular expression delimited in
|
|
|
362 |
slashes or a comma-separated compound of such addresses), Acme highlights
|
|
|
363 |
the target of that address in the file and places the mouse there. One may jump to
|
|
|
364 |
line 27 of
|
|
|
365 |
</span><span style="font-size: 10pt"><tt>dat.h</tt></span><span style="font-size: 10pt">
|
|
|
366 |
by indicating with the right button the text
|
|
|
367 |
</span><span style="font-size: 10pt"><tt>dat.h:27</tt></span><span style="font-size: 10pt">.
|
|
|
368 |
If the file is not already open, Acme loads it.
|
|
|
369 |
If the file name is null, for example if the indicated string is
|
|
|
370 |
</span><span style="font-size: 10pt"><tt>:/^main/</tt></span><span style="font-size: 10pt">,
|
|
|
371 |
the file is assumed to be that of the window containing the string.
|
|
|
372 |
Such strings, when typed and evaluated in the tag of a window, amount to
|
|
|
373 |
context searches.
|
|
|
374 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
375 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
376 |
<span style="font-size: 10pt">If the indicated text is not the name of an existing file, it is taken to be literal
|
|
|
377 |
text and is searched for in the body of the window containing the text, highlighting
|
|
|
378 |
the result as if it were the result of a context search.
|
|
|
379 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
380 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
381 |
<span style="font-size: 10pt">For the rare occasion when a file name
|
|
|
382 |
</span><span style="font-size: 10pt"><i>is</i></span><span style="font-size: 10pt">
|
|
|
383 |
just text to search for, it can be selected with the left button and used as the
|
|
|
384 |
argument to a built-in
|
|
|
385 |
</span><span style="font-size: 10pt"><tt>Look</tt></span><span style="font-size: 10pt">
|
|
|
386 |
command that always searches for literal text.
|
|
|
387 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
388 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
389 |
<span style="font-size: 10pt"><b>Nuances and heuristics
|
|
|
390 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
391 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
392 |
<span style="font-size: 10pt">A user interface should not only provide the necessary functions, it should also
|
|
|
393 |
</span><span style="font-size: 10pt"><i>feel</i></span><span style="font-size: 10pt">
|
|
|
394 |
right.
|
|
|
395 |
In fact, it should almost not be felt at all; when one notices a
|
|
|
396 |
user interface, one is distracted from the job at hand [Pike88].
|
|
|
397 |
To approach this invisibility, some of Acme’s properties and features
|
|
|
398 |
are there just to make the others easy to use.
|
|
|
399 |
Many are based on a fundamental principle of good design:
|
|
|
400 |
let the machine do the work.
|
|
|
401 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
402 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
403 |
<span style="font-size: 10pt">Acme tries to avoid needless clicking and typing.
|
|
|
404 |
There is no ‘click-to-type’, eliminating a button click.
|
|
|
405 |
There are no pop-up or pull-down menus, eliminating the mouse action needed to
|
|
|
406 |
make a menu appear.
|
|
|
407 |
The overall design is intended to make text on the screen useful without
|
|
|
408 |
copying or retyping; the ways in which this happens involve
|
|
|
409 |
the combination of many aspects of the interface.
|
|
|
410 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
411 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
412 |
<span style="font-size: 10pt">Acme tiles its windows and places them automatically
|
|
|
413 |
to avoid asking the user to place and arrange them.
|
|
|
414 |
For this policy to succeed, the automatic placement must behave well enough
|
|
|
415 |
that the user is usually content with the location of a new window.
|
|
|
416 |
The system will never get it right all the time, but in practice most
|
|
|
417 |
windows are used at least for a while where Acme first places them.
|
|
|
418 |
There have been several complete rewrites of the
|
|
|
419 |
heuristics for placing a new window,
|
|
|
420 |
and with each rewrite the system became
|
|
|
421 |
noticeably more comfortable. The rules are as follows, although
|
|
|
422 |
they are still subject to improvement.
|
|
|
423 |
The window appears in the ‘active’ column, that most recently used for typing or
|
|
|
424 |
selecting.
|
|
|
425 |
Executing and searching do not affect the choice of active column,
|
|
|
426 |
so windows of commands and such do not draw new windows towards them,
|
|
|
427 |
but rather let them form near the targets of their actions.
|
|
|
428 |
Output (error) windows always appear towards the right, away from
|
|
|
429 |
edited text, which is typically kept towards the left.
|
|
|
430 |
Within the column, several competing desires are balanced to decide where
|
|
|
431 |
and how large the window should be:
|
|
|
432 |
large blank spaces should be consumed;
|
|
|
433 |
existing text should remain visible;
|
|
|
434 |
existing large windows should be divided before small ones;
|
|
|
435 |
and the window should appear near the one containing the action that caused
|
|
|
436 |
its creation.
|
|
|
437 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
438 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
439 |
<span style="font-size: 10pt">Acme binds some actions to chords of mouse buttons.
|
|
|
440 |
These include
|
|
|
441 |
</span><span style="font-size: 10pt"><tt>Cut</tt></span><span style="font-size: 10pt">
|
|
|
442 |
and
|
|
|
443 |
</span><span style="font-size: 10pt"><tt>Paste</tt></span><span style="font-size: 10pt">
|
|
|
444 |
so these common operations can be done without
|
|
|
445 |
moving the mouse.
|
|
|
446 |
Another is a way to apply a command in one window to text (often a file name)
|
|
|
447 |
in another, avoiding the actions needed to assemble the command textually.
|
|
|
448 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
449 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
450 |
<span style="font-size: 10pt">Another way Acme avoids the need to move the mouse is instead to move the cursor
|
|
|
451 |
to where it is likely to be used next. When a new window is made, Acme
|
|
|
452 |
moves the cursor to the new window; in fact, to the selected text in that window.
|
|
|
453 |
When the user deletes a newly made window, the cursor is
|
|
|
454 |
returned to the point it was before the window was made,
|
|
|
455 |
reducing the irritation of windows that pop up to report annoying errors.
|
|
|
456 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
457 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
458 |
<span style="font-size: 10pt">When a window is moved, Acme moves the cursor to the layout box in
|
|
|
459 |
its new place, to permit further adjustment without moving the mouse.
|
|
|
460 |
For example, when a click of the left mouse button on the layout box grows
|
|
|
461 |
the window, the cursor moves to the new location of the box so repeated clicks,
|
|
|
462 |
without moving the mouse, continue to grow it.
|
|
|
463 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
464 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
465 |
<span style="font-size: 10pt">Another form of assistance the system can offer is to supply precision in
|
|
|
466 |
pointing the mouse. The best-known form of this is ‘double-clicking’ to
|
|
|
467 |
select a word rather than carefully sweeping out the entire word.
|
|
|
468 |
Acme provides this feature, using context to decide whether to select
|
|
|
469 |
a word, line, quoted string, parenthesized expression, and so on.
|
|
|
470 |
But Acme takes the idea much further by applying it to execution
|
|
|
471 |
and searching.
|
|
|
472 |
A
|
|
|
473 |
</span><span style="font-size: 10pt"><i>single</i></span><span style="font-size: 10pt">
|
|
|
474 |
click, that is, a null selection, with either the middle or right buttons,
|
|
|
475 |
is expanded automatically to indicate the appropriate text containing
|
|
|
476 |
the click. What is appropriate depends on the context.
|
|
|
477 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
478 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
479 |
<span style="font-size: 10pt">For example, to execute a single-word command
|
|
|
480 |
such as
|
|
|
481 |
</span><span style="font-size: 10pt"><tt>Cut</tt></span><span style="font-size: 10pt">,
|
|
|
482 |
it is not necessary to sweep the entire word; just clicking the button once with
|
|
|
483 |
the mouse pointing at the word is sufficient. ‘Word’
|
|
|
484 |
means the largest string of likely file name characters surrounding the location
|
|
|
485 |
of the click: click on a file name, run that program.
|
|
|
486 |
On the right button, the rules are more complicated because
|
|
|
487 |
the target of the click might be a file name, file name with address,
|
|
|
488 |
or just plain text. Acme examines the text near the click to find
|
|
|
489 |
a likely file name;
|
|
|
490 |
if it finds one, it checks that it names an existing file (in the directory named in the tag, if the name is relative)
|
|
|
491 |
and if so, takes that as the result, after extending it with any address
|
|
|
492 |
that may be present. If there is no file with that name, Acme
|
|
|
493 |
just takes the largest alphanumeric string under the click.
|
|
|
494 |
The effect is a natural overloading of the button to refer to plain text as
|
|
|
495 |
well as file names.
|
|
|
496 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
497 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
498 |
<span style="font-size: 10pt">First, though, if the click occurs over the left-button-selected text in the window,
|
|
|
499 |
that text is taken to be what is selected.
|
|
|
500 |
This makes it easy to skip through the occurrences of a string in a file: just click
|
|
|
501 |
the right button
|
|
|
502 |
on some occurrence of the text in the window (perhaps after typing it in the tag)
|
|
|
503 |
and click once for each subsequent occurrence. It isn’t even necessary to move
|
|
|
504 |
the mouse between clicks; Acme does that.
|
|
|
505 |
To turn a complicated command into a sort of menu item, select it:
|
|
|
506 |
thereafter, clicking the middle button on it will execute the full command.
|
|
|
507 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
508 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
509 |
<span style="font-size: 10pt">As an extra feature, Acme recognizes file names in angle brackets
|
|
|
510 |
</span><span style="font-size: 10pt"><tt><></tt></span><span style="font-size: 10pt">
|
|
|
511 |
as names of files in standard directories of include files,
|
|
|
512 |
making it possible for instance to look at
|
|
|
513 |
</span><span style="font-size: 10pt"><tt><stdio.h></tt></span><span style="font-size: 10pt">
|
|
|
514 |
with a single click.
|
|
|
515 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
516 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
517 |
<span style="font-size: 10pt">Here’s an example to demonstrate how the actions and defaults work together.
|
|
|
518 |
Assume
|
|
|
519 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/sam/regexp.c</tt></span><span style="font-size: 10pt">
|
|
|
520 |
is
|
|
|
521 |
open and has been edited. We write it (execute
|
|
|
522 |
</span><span style="font-size: 10pt"><tt>Put</tt></span><span style="font-size: 10pt">
|
|
|
523 |
in the tag; once the file is written, Acme removes the word from the tag)
|
|
|
524 |
and type
|
|
|
525 |
</span><span style="font-size: 10pt"><tt>mk</tt></span><span style="font-size: 10pt">
|
|
|
526 |
in the tag. We execute
|
|
|
527 |
</span><span style="font-size: 10pt"><tt>mk</tt></span><span style="font-size: 10pt">
|
|
|
528 |
and get some errors, which appear in a new window labeled
|
|
|
529 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/sam/+Errors</tt></span><span style="font-size: 10pt">.
|
|
|
530 |
The cursor moves automatically to that window.
|
|
|
531 |
Say the error is
|
|
|
532 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
533 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
534 |
<span style="font-size: 9pt"><tt>main.c:112: incompatible types on assignment to ‘pattern’</tt></span></p>
|
|
|
535 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
536 |
|
|
|
537 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
538 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
539 |
<span style="font-size: 10pt">We move the mouse slightly and click the right button
|
|
|
540 |
at the left of the error message; Acme
|
|
|
541 |
makes a new window, reads
|
|
|
542 |
</span><span style="font-size: 10pt"><tt>/sys/src/cmd/main.c</tt></span><span style="font-size: 10pt">
|
|
|
543 |
into it, selects line 112
|
|
|
544 |
and places the mouse there, right on the offending line.
|
|
|
545 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
546 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
547 |
<span style="font-size: 10pt"><b>Coupling to existing programs
|
|
|
548 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
549 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
550 |
<span style="font-size: 10pt">Acme’s syntax for file names and addresses makes it easy for other programs
|
|
|
551 |
to connect automatically to Acme’s capabilities. For example, the output of
|
|
|
552 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
553 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
554 |
<span style="font-size: 9pt"><tt>grep -n variable *.[ch]</tt></span></p>
|
|
|
555 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
556 |
|
|
|
557 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
558 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
559 |
<span style="font-size: 10pt">can be used to help Acme step through the occurrences of a variable in a program;
|
|
|
560 |
every line of output is potentially a command to open a file.
|
|
|
561 |
The file names need not be absolute, either: the output
|
|
|
562 |
appears in a window labeled with the directory in which
|
|
|
563 |
</span><span style="font-size: 10pt"><tt>grep</tt></span><span style="font-size: 10pt">
|
|
|
564 |
was run, from which Acme can derive the full path names.
|
|
|
565 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
566 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
567 |
<span style="font-size: 10pt">When necessary, we have changed the output of some programs,
|
|
|
568 |
such as compiler error messages, to match
|
|
|
569 |
Acme’s syntax.
|
|
|
570 |
Some might argue that it shouldn’t be necessary to change old programs,
|
|
|
571 |
but sometimes programs need to be updated when systems change,
|
|
|
572 |
and consistent output benefits people as well as programs.
|
|
|
573 |
A historical example is the retrofitting of standard error output to the
|
|
|
574 |
early Unix programs when pipes were invented.
|
|
|
575 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
576 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
577 |
<span style="font-size: 10pt">Another change was to record full path names in
|
|
|
578 |
the symbol table of executables, so line numbers reported by the debugger
|
|
|
579 |
are absolute names that may be used directly by Acme; it’s not necessary
|
|
|
580 |
to run the debugger in the source directory. (This aids debugging
|
|
|
581 |
even without Acme.)
|
|
|
582 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
583 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
584 |
<span style="font-size: 10pt">A related change was to add lines of the form
|
|
|
585 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
586 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
587 |
<span style="font-size: 9pt"><tt>#pragma src "/sys/src/libregexp"</tt></span></p>
|
|
|
588 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
589 |
|
|
|
590 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
591 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
592 |
<span style="font-size: 10pt">to header files; coupled with Acme’s ability to locate a header file,
|
|
|
593 |
this provides a fast, keyboardless way to get the source associated with a library.
|
|
|
594 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
595 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
596 |
<span style="font-size: 10pt">Finally, Acme directs the standard output of programs it runs to
|
|
|
597 |
windows labeled by the directory in which the program is run.
|
|
|
598 |
Acme’s splitting of the
|
|
|
599 |
output into directory-labeled windows is a small feature that has a major effect:
|
|
|
600 |
local file names printed by programs can be interpreted directly by Acme.
|
|
|
601 |
By indirectly coupling the output of programs to the input,
|
|
|
602 |
it also simplifies the management of software that occupies multiple
|
|
|
603 |
directories.
|
|
|
604 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
605 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
606 |
<span style="font-size: 10pt"><b>Coupling to new programs
|
|
|
607 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
608 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
609 |
<span style="font-size: 10pt">Like many Plan 9 programs,
|
|
|
610 |
Acme offers a programmable interface to
|
|
|
611 |
other programs by acting as a file server.
|
|
|
612 |
The best example of such a file server is the window system
|
|
|
613 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">
|
|
|
614 |
[Pike91],
|
|
|
615 |
which exports files with names such as
|
|
|
616 |
</span><span style="font-size: 10pt"><tt>screen</tt></span><span style="font-size: 10pt">,
|
|
|
617 |
</span><span style="font-size: 10pt"><tt>cons</tt></span><span style="font-size: 10pt">,
|
|
|
618 |
and
|
|
|
619 |
</span><span style="font-size: 10pt"><tt>mouse</tt></span><span style="font-size: 10pt">
|
|
|
620 |
through which applications may access the I/O capabilities of the windows.
|
|
|
621 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">
|
|
|
622 |
provides a
|
|
|
623 |
</span><span style="font-size: 10pt"><i>distinct</i></span><span style="font-size: 10pt">
|
|
|
624 |
set of files for each window and builds a private file name space
|
|
|
625 |
for the clients running ‘in’ each window;
|
|
|
626 |
clients in separate windows see distinct files with the same names
|
|
|
627 |
(for example
|
|
|
628 |
</span><span style="font-size: 10pt"><tt>/dev/mouse</tt></span><span style="font-size: 10pt">).
|
|
|
629 |
Acme, like the process file system [PPTTW93], instead associates each
|
|
|
630 |
window with a directory of files; the files of each window are visible
|
|
|
631 |
to any application.
|
|
|
632 |
This difference reflects a difference in how the systems are used:
|
|
|
633 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">
|
|
|
634 |
tells a client what keyboard and mouse activity has happened in its window;
|
|
|
635 |
Acme tells a client what changes that activity wrought on any window it asks about.
|
|
|
636 |
Putting it another way,
|
|
|
637 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">
|
|
|
638 |
enables the construction of interactive applications;
|
|
|
639 |
Acme provides the interaction for applications.
|
|
|
640 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
641 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
642 |
<span style="font-size: 10pt">The root of
|
|
|
643 |
Acme’s file system is mounted using Plan 9 operations on the directory
|
|
|
644 |
</span><span style="font-size: 10pt"><tt>/mnt/acme</tt></span><span style="font-size: 10pt">.
|
|
|
645 |
In
|
|
|
646 |
that root directory appears a directory for each window, numbered with the window’s identifier,
|
|
|
647 |
analogous to a process identifier, for example
|
|
|
648 |
</span><span style="font-size: 10pt"><tt>/mnt/acme/27</tt></span><span style="font-size: 10pt">.
|
|
|
649 |
The window’s directory
|
|
|
650 |
contains 6 files:
|
|
|
651 |
</span><span style="font-size: 10pt"><tt>/mnt/acme/27/addr</tt></span><span style="font-size: 10pt">,
|
|
|
652 |
</span><span style="font-size: 10pt"><tt>body</tt></span><span style="font-size: 10pt">,
|
|
|
653 |
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">,
|
|
|
654 |
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">,
|
|
|
655 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">,
|
|
|
656 |
and
|
|
|
657 |
</span><span style="font-size: 10pt"><tt>tag</tt></span><span style="font-size: 10pt">.
|
|
|
658 |
The
|
|
|
659 |
</span><span style="font-size: 10pt"><tt>body</tt></span><span style="font-size: 10pt">
|
|
|
660 |
and
|
|
|
661 |
</span><span style="font-size: 10pt"><tt>tag</tt></span><span style="font-size: 10pt">
|
|
|
662 |
files contain the text of the respective parts of the window; they may be
|
|
|
663 |
read to recover the contents. Data written to these files is appended to the text;
|
|
|
664 |
</span><span style="font-size: 10pt"><tt>seeks</tt></span><span style="font-size: 10pt">
|
|
|
665 |
are ignored.
|
|
|
666 |
The
|
|
|
667 |
</span><span style="font-size: 10pt"><tt>addr</tt></span><span style="font-size: 10pt">
|
|
|
668 |
and
|
|
|
669 |
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
|
|
|
670 |
files provide random access to the contents of the body.
|
|
|
671 |
The
|
|
|
672 |
</span><span style="font-size: 10pt"><tt>addr</tt></span><span style="font-size: 10pt">
|
|
|
673 |
file is written to set a character position within the body; the
|
|
|
674 |
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
|
|
|
675 |
file may then be read to recover the contents at that position,
|
|
|
676 |
or written to change them.
|
|
|
677 |
(The tag is assumed
|
|
|
678 |
small and special-purpose enough not to need special treatment.
|
|
|
679 |
Also,
|
|
|
680 |
</span><span style="font-size: 10pt"><tt>addr</tt></span><span style="font-size: 10pt">
|
|
|
681 |
indexes by character position, which is not the same as byte offset
|
|
|
682 |
in Plan 9’s multi-byte character set [Pike93]).
|
|
|
683 |
The format accepted by the
|
|
|
684 |
</span><span style="font-size: 10pt"><tt>addr</tt></span><span style="font-size: 10pt">
|
|
|
685 |
file is exactly the syntax of addresses within the user interface,
|
|
|
686 |
permitting regular expressions, line numbers, and compound addresses
|
|
|
687 |
to be specified. For example, to replace the contents of lines 3 through 7,
|
|
|
688 |
write the text
|
|
|
689 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
690 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
691 |
<span style="font-size: 9pt"><tt>3,7</tt></span></p>
|
|
|
692 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
693 |
|
|
|
694 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
695 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
696 |
<span style="font-size: 10pt">to the
|
|
|
697 |
</span><span style="font-size: 10pt"><tt>addr</tt></span><span style="font-size: 10pt">
|
|
|
698 |
file, then write the replacement text to the
|
|
|
699 |
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
|
|
|
700 |
file. A zero-length write deletes the addressed text; further writes extend the replacement.
|
|
|
701 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
702 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
703 |
<span style="font-size: 10pt">The control file,
|
|
|
704 |
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">,
|
|
|
705 |
may be written with commands to effect actions on the window; for example
|
|
|
706 |
the command
|
|
|
707 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
708 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
709 |
<span style="font-size: 9pt"><tt>name /adm/users</tt></span></p>
|
|
|
710 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
711 |
|
|
|
712 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
713 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
714 |
<span style="font-size: 10pt">sets the name in the tag of the window to
|
|
|
715 |
</span><span style="font-size: 10pt"><tt>/adm/users</tt></span><span style="font-size: 10pt">.
|
|
|
716 |
Other commands allow deleting the window, writing it to a file, and so on.
|
|
|
717 |
Reading the
|
|
|
718 |
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
|
|
|
719 |
file recovers a fixed-format string containing 5 textual numbers—the window
|
|
|
720 |
identifier, the number of characters in the tag, the number in the body,
|
|
|
721 |
and some status information—followed by the text of the tag, up to a newline.
|
|
|
722 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
723 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
724 |
<span style="font-size: 10pt">The last file,
|
|
|
725 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">,
|
|
|
726 |
is the most unusual.
|
|
|
727 |
A program reading a window’s
|
|
|
728 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">
|
|
|
729 |
file is notified of all changes to the text of the window, and
|
|
|
730 |
is asked to interpret all middle- and right-button actions.
|
|
|
731 |
The data passed to the program is fixed-format and reports
|
|
|
732 |
the source of the action (keyboard, mouse, external program, etc.),
|
|
|
733 |
its location (what was pointed at or modified), and its nature (change,
|
|
|
734 |
search, execution, etc.).
|
|
|
735 |
This message, for example,
|
|
|
736 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
737 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
738 |
<span style="font-size: 9pt"><tt>MI15 19 0 4 time</tt></span></p>
|
|
|
739 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
740 |
|
|
|
741 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
742 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
743 |
<span style="font-size: 10pt">reports that actions of the mouse
|
|
|
744 |
(</span><span style="font-size: 10pt"><tt>M</tt></span><span style="font-size: 10pt">)
|
|
|
745 |
inserted in the body (capital
|
|
|
746 |
</span><span style="font-size: 10pt"><tt>I</tt></span><span style="font-size: 10pt">)
|
|
|
747 |
the 4 characters of
|
|
|
748 |
</span><span style="font-size: 10pt"><tt>time</tt></span><span style="font-size: 10pt">
|
|
|
749 |
at character positions 15 through 19; the zero is a flag word.
|
|
|
750 |
Programs may apply their own interpretations of searching and
|
|
|
751 |
execution, or may simply reflect the events back to Acme,
|
|
|
752 |
by writing them back to the
|
|
|
753 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">
|
|
|
754 |
file, to have the default interpretation applied.
|
|
|
755 |
Some examples of these ideas in action are presented below.
|
|
|
756 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
757 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
758 |
<span style="font-size: 10pt">Notice that changes to the window are reported
|
|
|
759 |
after the fact; the program is told about them but is not required to act
|
|
|
760 |
on them. Compare this to a more traditional interface in which a program
|
|
|
761 |
is told, for example, that a character has been typed on the keyboard and
|
|
|
762 |
must then display and interpret it.
|
|
|
763 |
Acme’s style stems from the basic model of the system, in which any
|
|
|
764 |
number of agents—the keyboard, mouse, external programs
|
|
|
765 |
writing to
|
|
|
766 |
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
|
|
|
767 |
or
|
|
|
768 |
</span><span style="font-size: 10pt"><tt>body</tt></span><span style="font-size: 10pt">,
|
|
|
769 |
and so on—may
|
|
|
770 |
change the contents of a window.
|
|
|
771 |
The style is efficient: many programs are content
|
|
|
772 |
to have Acme do most of the work and act only when the editing is completed.
|
|
|
773 |
An example is the Acme mail program, which can ignore the changes
|
|
|
774 |
made to a message being composed
|
|
|
775 |
and just read its body when asked to send it.
|
|
|
776 |
A disadvantage is that some traditional ways of working are impossible.
|
|
|
777 |
For example, there is no way ‘to turn off echo’: characters appear on the
|
|
|
778 |
screen and are read from there; no agent or buffer stands between
|
|
|
779 |
the keyboard and the display.
|
|
|
780 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
781 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
782 |
<span style="font-size: 10pt">There are a couple of other files made available by Acme in its root directory
|
|
|
783 |
rather than in the directory of each window.
|
|
|
784 |
The text file
|
|
|
785 |
</span><span style="font-size: 10pt"><tt>/mnt/acme/index</tt></span><span style="font-size: 10pt">
|
|
|
786 |
holds a list of all window names and numerical identifiers,
|
|
|
787 |
somewhat analogous to the output of the
|
|
|
788 |
</span><span style="font-size: 10pt"><tt>ps</tt></span><span style="font-size: 10pt">
|
|
|
789 |
command for processes.
|
|
|
790 |
The most important, though, is
|
|
|
791 |
</span><span style="font-size: 10pt"><tt>/mnt/acme/new</tt></span><span style="font-size: 10pt">,
|
|
|
792 |
a directory that makes new windows, similar to the
|
|
|
793 |
</span><span style="font-size: 10pt"><tt>clone</tt></span><span style="font-size: 10pt">
|
|
|
794 |
directory in the Plan 9 network devices [Pres93].
|
|
|
795 |
The act of opening any file in
|
|
|
796 |
</span><span style="font-size: 10pt"><tt>new</tt></span><span style="font-size: 10pt">
|
|
|
797 |
creates a new Acme window; thus the shell command
|
|
|
798 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
799 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
800 |
<span style="font-size: 9pt"><tt>grep -n var *.c > /mnt/acme/new/body</tt></span></p>
|
|
|
801 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
802 |
|
|
|
803 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
804 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
805 |
<span style="font-size: 10pt">places its output in the body of a fresh window.
|
|
|
806 |
More sophisticated applications may open
|
|
|
807 |
</span><span style="font-size: 10pt"><tt>new/ctl</tt></span><span style="font-size: 10pt">,
|
|
|
808 |
read it to discover the new window’s identifier, and then
|
|
|
809 |
open the window’s other files in the numbered directory.
|
|
|
810 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
811 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
812 |
<span style="font-size: 10pt"><b>Acme-specific programs
|
|
|
813 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
814 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
815 |
<span style="font-size: 10pt">Although Acme is in part an attempt to move beyond typescripts,
|
|
|
816 |
they will probably always have utility.
|
|
|
817 |
The first program written for Acme was therefore one
|
|
|
818 |
to run a shell or other traditional interactive application
|
|
|
819 |
in a window, the Acme analog of
|
|
|
820 |
</span><span style="font-size: 10pt"><tt>xterm</tt></span><span style="font-size: 10pt">.
|
|
|
821 |
This program,
|
|
|
822 |
</span><span style="font-size: 10pt"><tt>win</tt></span><span style="font-size: 10pt">,
|
|
|
823 |
has a simple structure:
|
|
|
824 |
it acts as a two-way intermediary between Acme and the shell,
|
|
|
825 |
cross-connecting the standard input and output of the shell to the
|
|
|
826 |
text of the window.
|
|
|
827 |
The style of interaction is modeled after
|
|
|
828 |
</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">
|
|
|
829 |
[Pike88]: standard output is added to the window at the
|
|
|
830 |
</span><span style="font-size: 10pt"><i>output point;</i></span><span style="font-size: 10pt">
|
|
|
831 |
text typed after the output point
|
|
|
832 |
is made available on standard input when a newline is typed.
|
|
|
833 |
After either of these actions, the output point is advanced.
|
|
|
834 |
This is different from the working of a regular terminal,
|
|
|
835 |
permitting cut-and-paste editing of an input line until the newline is typed.
|
|
|
836 |
Arbitrary editing may be done to any text in the window.
|
|
|
837 |
The implementation of
|
|
|
838 |
</span><span style="font-size: 10pt"><tt>win</tt></span><span style="font-size: 10pt">,
|
|
|
839 |
using the
|
|
|
840 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">,
|
|
|
841 |
</span><span style="font-size: 10pt"><tt>addr</tt></span><span style="font-size: 10pt">,
|
|
|
842 |
and
|
|
|
843 |
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
|
|
|
844 |
files, is straightforward.
|
|
|
845 |
</span><span style="font-size: 10pt"><tt>Win</tt></span><span style="font-size: 10pt">
|
|
|
846 |
needs no code for handling the keyboard and mouse; it just monitors the
|
|
|
847 |
contents of the window. Nonetheless, it allows Acme’s full editing to be
|
|
|
848 |
applied to shell commands.
|
|
|
849 |
The division of labor between
|
|
|
850 |
</span><span style="font-size: 10pt"><tt>win</tt></span><span style="font-size: 10pt">
|
|
|
851 |
and
|
|
|
852 |
</span><span style="font-size: 10pt"><tt>Acme</tt></span><span style="font-size: 10pt">
|
|
|
853 |
contrasted with
|
|
|
854 |
</span><span style="font-size: 10pt"><tt>xterm</tt></span><span style="font-size: 10pt">
|
|
|
855 |
and the X server demonstrates how much work Acme handles automatically.
|
|
|
856 |
</span><span style="font-size: 10pt"><tt>Win</tt></span><span style="font-size: 10pt">
|
|
|
857 |
is implemented by a single source file 560 lines long and has no graphics code.
|
|
|
858 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
859 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
860 |
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Win</tt></span><span style="font-size: 10pt">
|
|
|
861 |
uses the middle and right buttons to connect itself in a consistent way
|
|
|
862 |
with the rest of Acme.
|
|
|
863 |
The middle button still executes commands, but in a style more suited
|
|
|
864 |
to typescripts. Text selected with the middle button is treated as if
|
|
|
865 |
it had been typed after the output point, much as a similar feature in
|
|
|
866 |
</span><span style="font-size: 10pt"><tt>xterm</tt></span><span style="font-size: 10pt">
|
|
|
867 |
or
|
|
|
868 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">,
|
|
|
869 |
and therefore causes it to be ‘executed’ by the application running in the window.
|
|
|
870 |
Right button actions are reflected back to Acme but refer to the appropriate
|
|
|
871 |
files because
|
|
|
872 |
</span><span style="font-size: 10pt"><tt>win</tt></span><span style="font-size: 10pt">
|
|
|
873 |
places the name of the current directory in the tag of the window.
|
|
|
874 |
If the shell is running, a simple shell function replacing the
|
|
|
875 |
</span><span style="font-size: 10pt"><tt>cd</tt></span><span style="font-size: 10pt">
|
|
|
876 |
command can maintain the tag as the shell navigates the file system.
|
|
|
877 |
This means, for example, that a right button click on a file mentioned in an
|
|
|
878 |
</span><span style="font-size: 10pt"><tt>ls</tt></span><span style="font-size: 10pt">
|
|
|
879 |
listing opens the file within Acme.
|
|
|
880 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
881 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
882 |
<span style="font-size: 10pt">Another Acme-specific program is a mail reader that begins by presenting,
|
|
|
883 |
in a window, a listing of the messages in the user’s mailbox, one per line.
|
|
|
884 |
Here the middle and right button actions are modified to refer to
|
|
|
885 |
mail commands
|
|
|
886 |
and messages, but the change feels natural.
|
|
|
887 |
Clicking the right button on a line creates a new window and displays the
|
|
|
888 |
message there, or, if it’s already displayed, moves the mouse to that window.
|
|
|
889 |
The metaphor is that the mailbox is a directory whose constituent files are messages.
|
|
|
890 |
The mail program also places some relevant commands in the tag lines of
|
|
|
891 |
the windows; for example, executing the word
|
|
|
892 |
</span><span style="font-size: 10pt"><tt>Reply</tt></span><span style="font-size: 10pt">
|
|
|
893 |
in a message’s tag creates a new window
|
|
|
894 |
in which to compose a message to the sender of the original;
|
|
|
895 |
</span><span style="font-size: 10pt"><tt>Post</tt></span><span style="font-size: 10pt">
|
|
|
896 |
then dispatches it.
|
|
|
897 |
In such windows, the addressee is just a list of names
|
|
|
898 |
on the first line of the body, which may be edited to add or change recipients.
|
|
|
899 |
The program also monitors the mailbox, updating the ‘directory’ as new messages
|
|
|
900 |
arrive.
|
|
|
901 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
902 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
903 |
<span style="font-size: 10pt">The mail program is as simple as it sounds; all the work of interaction,
|
|
|
904 |
editing, and management of the display is done by Acme.
|
|
|
905 |
The only
|
|
|
906 |
difficult sections of the 1200
|
|
|
907 |
lines of code concern honoring the external protocols for managing
|
|
|
908 |
the mailbox and connecting to
|
|
|
909 |
</span><span style="font-size: 10pt"><tt>sendmail</tt></span><span style="font-size: 10pt">.
|
|
|
910 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
911 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
912 |
<span style="font-size: 10pt">One of the things Acme does not provide directly is a facility like
|
|
|
913 |
Sam’s command language to enable actions such as global substitution;
|
|
|
914 |
within Acme, all editing is done manually.
|
|
|
915 |
It is easy, though, to write external programs for such tasks.
|
|
|
916 |
In this, Acme comes closer to the original intent of Oberon:
|
|
|
917 |
a directory,
|
|
|
918 |
</span><span style="font-size: 10pt"><tt>/acme/edit</tt></span><span style="font-size: 10pt">,
|
|
|
919 |
contains a set of tools for repetitive editing and a template
|
|
|
920 |
or ‘guide’ file that gives examples
|
|
|
921 |
of its use.
|
|
|
922 |
Acme’s editing guide,
|
|
|
923 |
</span><span style="font-size: 10pt"><tt>/acme/edit/guide</tt></span><span style="font-size: 10pt">,
|
|
|
924 |
looks like this:
|
|
|
925 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
926 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
927 |
<span style="font-size: 9pt"><tt>e file | x ’/regexp/’ | c ’replacement’</tt></span></p>
|
|
|
928 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
929 |
<span style="font-size: 9pt"><tt>e file:’0,$’ | x ’/.*word.*\n/’ | p -n</tt></span></p>
|
|
|
930 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
931 |
<span style="font-size: 9pt"><tt>e file | pipe command args ...</tt></span></p>
|
|
|
932 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
933 |
|
|
|
934 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
935 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
936 |
<span style="font-size: 10pt">The syntax is reminiscent of Sam’s command language, but here the individual
|
|
|
937 |
one-letter commands are all stand-alone programs connected by pipes.
|
|
|
938 |
Passed along the pipes are addresses, analogous to structural expressions
|
|
|
939 |
in Sam terminology.
|
|
|
940 |
The
|
|
|
941 |
</span><span style="font-size: 10pt"><tt>e</tt></span><span style="font-size: 10pt">
|
|
|
942 |
command, unlike that of Sam, starts the process by generating the address
|
|
|
943 |
(default dot, the highlighted selection) in the named files.
|
|
|
944 |
The other commands are as in Sam:
|
|
|
945 |
</span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
|
|
|
946 |
prints the addressed text on standard output (the
|
|
|
947 |
</span><span style="font-size: 10pt"><tt>-n</tt></span><span style="font-size: 10pt">
|
|
|
948 |
option is analogous to that of
|
|
|
949 |
</span><span style="font-size: 10pt"><tt>grep</tt></span><span style="font-size: 10pt">,
|
|
|
950 |
useful in combination with the right mouse button);
|
|
|
951 |
</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
|
|
|
952 |
matches a regular expression to the addressed (incoming) text,
|
|
|
953 |
subdividing the text;
|
|
|
954 |
</span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">
|
|
|
955 |
replaces the text; and so on. Thus, global substitution throughout a file,
|
|
|
956 |
which would be expressed in Sam as
|
|
|
957 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
958 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
959 |
<span style="font-size: 9pt"><tt>0,$ x/regexp/ c/replacement/</tt></span></p>
|
|
|
960 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
961 |
|
|
|
962 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
963 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
964 |
<span style="font-size: 10pt">in Acme’s editor becomes
|
|
|
965 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
966 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
967 |
<span style="font-size: 9pt"><tt>e ’file:0,$’ | x ’/regexp/’ | c ’replacement’</tt></span></p>
|
|
|
968 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
969 |
|
|
|
970 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
971 |
<p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
972 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
973 |
<span style="font-size: 10pt">To use the Acme editing commands, open
|
|
|
974 |
</span><span style="font-size: 10pt"><tt>/acme/edit/guide</tt></span><span style="font-size: 10pt">,
|
|
|
975 |
use the mouse and keyboard to edit one of the commands to the right form,
|
|
|
976 |
and execute it with the middle button.
|
|
|
977 |
Acme’s context rules find the appropriate binaries in
|
|
|
978 |
</span><span style="font-size: 10pt"><tt>/acme/edit</tt></span><span style="font-size: 10pt">
|
|
|
979 |
rather than
|
|
|
980 |
</span><span style="font-size: 10pt"><tt>/bin</tt></span><span style="font-size: 10pt">;
|
|
|
981 |
the effect is to turn
|
|
|
982 |
</span><span style="font-size: 10pt"><tt>/acme/edit</tt></span><span style="font-size: 10pt">
|
|
|
983 |
into a toolbox containing tools and instructions (the guide file) for their use.
|
|
|
984 |
In fact, the source for these tools is also there, in the directory
|
|
|
985 |
</span><span style="font-size: 10pt"><tt>/acme/edit/src</tt></span><span style="font-size: 10pt">.
|
|
|
986 |
This setup allows some control of the file name space for binary programs;
|
|
|
987 |
not only does it group related programs, it permits the use of common
|
|
|
988 |
names for uncommon jobs. For example, the single-letter names would
|
|
|
989 |
be unwise in a directory in everyone’s search path; here they are only
|
|
|
990 |
visible when running editing commands.
|
|
|
991 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
992 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
993 |
<span style="font-size: 10pt">In Oberon,
|
|
|
994 |
such a collection would be called a
|
|
|
995 |
</span><span style="font-size: 10pt"><i>tool</i></span><span style="font-size: 10pt">
|
|
|
996 |
and would consist
|
|
|
997 |
of a set of entry points in a module and a menu-like piece of text containing
|
|
|
998 |
representative commands that may be edited to suit and executed.
|
|
|
999 |
There is, in fact, a tool called
|
|
|
1000 |
</span><span style="font-size: 10pt"><tt>Edit</tt></span><span style="font-size: 10pt">
|
|
|
1001 |
in Oberon.
|
|
|
1002 |
To provide related functionality,
|
|
|
1003 |
Acme exploits the directory and file structure of the underlying
|
|
|
1004 |
system, rather than the module structure of the language;
|
|
|
1005 |
this fits well with Plan 9’s
|
|
|
1006 |
file-oriented philosophy.
|
|
|
1007 |
Such tools are central to the working of Oberon but they are
|
|
|
1008 |
less used in Acme, at least so far.
|
|
|
1009 |
The main reason is probably that Acme’s program interface permits
|
|
|
1010 |
an external program to remain executing in the background, providing
|
|
|
1011 |
its own commands as needed (for example, the
|
|
|
1012 |
</span><span style="font-size: 10pt"><tt>Reply</tt></span><span style="font-size: 10pt">
|
|
|
1013 |
command in the mail program); Oberon uses tools to
|
|
|
1014 |
implement such services because its must invoke
|
|
|
1015 |
a fresh program for each command.
|
|
|
1016 |
Also,
|
|
|
1017 |
Acme’s better integration allows more
|
|
|
1018 |
basic functions to be handled internally; the right mouse button
|
|
|
1019 |
covers a lot of the basic utility of the editing tools in Oberon.
|
|
|
1020 |
Nonetheless, as more applications are written for Acme,
|
|
|
1021 |
many are sure to take this Oberon tool-like form.
|
|
|
1022 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1023 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1024 |
<span style="font-size: 10pt"><b>Comparison with other systems
|
|
|
1025 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1026 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1027 |
<span style="font-size: 10pt">Acme’s immediate ancestor is Help [Pike92], an experimental system written
|
|
|
1028 |
a few years ago as a first try at exploring some of Oberon’s ideas
|
|
|
1029 |
in an existing operating system.
|
|
|
1030 |
Besides much better engineering, Acme’s advances over Help
|
|
|
1031 |
include the actions of the right button (Help had nothing comparable),
|
|
|
1032 |
the ability to connect long-running programs to the user interface
|
|
|
1033 |
(Help had no analog of the
|
|
|
1034 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">
|
|
|
1035 |
file),
|
|
|
1036 |
and the small but important change to split command output into
|
|
|
1037 |
windows labeled with the directory in which the commands run.
|
|
|
1038 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1039 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1040 |
<span style="font-size: 10pt">Most of Acme’s style, however, derives from the user interface and window
|
|
|
1041 |
system of Oberon [Wirt89, Reis91].
|
|
|
1042 |
Oberon includes a programming language and operating system,
|
|
|
1043 |
which Acme instead borrows from an existing system, Plan 9.
|
|
|
1044 |
When I first saw Oberon, in 1988, I was struck by the
|
|
|
1045 |
simplicity of its user interface, particularly its lack of menus
|
|
|
1046 |
and its elegant use of multiple mouse buttons.
|
|
|
1047 |
The system seemed restrictive, though—single process,
|
|
|
1048 |
single language, no networking, event-driven programming—and
|
|
|
1049 |
failed to follow through on some of its own ideas.
|
|
|
1050 |
For example, the middle mouse button had to be pointed accurately and
|
|
|
1051 |
the right button was essentially unused.
|
|
|
1052 |
Acme does follow through:
|
|
|
1053 |
to the basic idea planted by Oberon, it adds
|
|
|
1054 |
the ability to run on different operating systems and hardware,
|
|
|
1055 |
connection to existing applications including
|
|
|
1056 |
interactive ones such as shells and debuggers,
|
|
|
1057 |
support for multiple processes,
|
|
|
1058 |
the right mouse button’s features,
|
|
|
1059 |
the default actions and context-dependent properties
|
|
|
1060 |
of execution and searching,
|
|
|
1061 |
and a host of little touches such as moving the mouse cursor that make the system
|
|
|
1062 |
more pleasant.
|
|
|
1063 |
At the moment, though, Oberon does have one distinct advantage: it incorporates
|
|
|
1064 |
graphical programs well into its model, an issue Acme has not yet faced.
|
|
|
1065 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1066 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1067 |
<span style="font-size: 10pt">Acme shares with the Macintosh a desire to use the mouse well and it is
|
|
|
1068 |
worth comparing the results.
|
|
|
1069 |
The mouse on the Macintosh has a single button, so menus are essential
|
|
|
1070 |
and the mouse must frequently move a long way
|
|
|
1071 |
to reach the appropriate function.
|
|
|
1072 |
An indication that this style has trouble is that applications provide
|
|
|
1073 |
keyboard sequences to invoke menu selections and users often prefer them.
|
|
|
1074 |
A deeper comparison is that the Macintosh uses pictures where Acme uses text.
|
|
|
1075 |
In contrast to pictures, text can be edited quickly, created on demand,
|
|
|
1076 |
and fine-tuned to the job at hand; consider adding an option to a command.
|
|
|
1077 |
It is also self-referential; Acme doesn’t need menus because any text can be
|
|
|
1078 |
in effect a menu item.
|
|
|
1079 |
The result is that, although a Macintosh screen is certainly prettier and probably
|
|
|
1080 |
more attractive, especially to beginners, an Acme screen is more dynamic
|
|
|
1081 |
and expressive, at least for programmers and experienced users.
|
|
|
1082 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1083 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1084 |
<span style="font-size: 10pt">For its role in the overall system,
|
|
|
1085 |
Acme most resembles EMACS [Stal93].
|
|
|
1086 |
It is tricky to compare Acme to EMACS, though, because there are
|
|
|
1087 |
many versions of EMACS and, since it is fully programmable, EMACS
|
|
|
1088 |
can in principle do anything Acme does.
|
|
|
1089 |
Also, Acme is much younger and therefore has not
|
|
|
1090 |
had the time to acquire as many features.
|
|
|
1091 |
The issue therefore is less what the systems can be programmed to do than
|
|
|
1092 |
how they are used.
|
|
|
1093 |
The EMACS versions that come closest to Acme’s style are those that
|
|
|
1094 |
have been extended to provide a programming environment, usually
|
|
|
1095 |
for a language such as LISP [Alle92, Lucid92].
|
|
|
1096 |
For richness of the existing interface, these EMACS versions are certainly superior to Acme.
|
|
|
1097 |
On the other hand, Acme’s interface works equally well already for a variety
|
|
|
1098 |
of languages; for example, one of its most enthusiastic users works almost
|
|
|
1099 |
exclusively in Standard ML, a language nothing like C.
|
|
|
1100 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1101 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1102 |
<span style="font-size: 10pt">Where Acme excels is in the smoothness of its interface.
|
|
|
1103 |
Until recently, EMACS did not support the mouse especially well,
|
|
|
1104 |
and even with the latest version providing features such as ‘extents’
|
|
|
1105 |
that can be programmed to behave much like Acme commands,
|
|
|
1106 |
many users don’t bother to upgrade.
|
|
|
1107 |
Moreover, in the versions that provide extents,
|
|
|
1108 |
most EMACS packages don’t take advantage of them.
|
|
|
1109 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1110 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1111 |
<span style="font-size: 10pt">The most important distinction is just that
|
|
|
1112 |
EMACS is fundamentally keyboard-based, while
|
|
|
1113 |
Acme is mouse-based.
|
|
|
1114 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1115 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1116 |
<span style="font-size: 10pt">People who try Acme find it hard to go back to their previous environment.
|
|
|
1117 |
Acme automates so much that to return to a traditional interface
|
|
|
1118 |
is to draw attention to the extra work it requires.
|
|
|
1119 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1120 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1121 |
<span style="font-size: 10pt"><b>Concurrency in the implementation
|
|
|
1122 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1123 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1124 |
<span style="font-size: 10pt">Acme is about 8,000 lines of code in Alef, a concurrent object-oriented language syntactically similar to C [Alef].
|
|
|
1125 |
Acme’s structure is a set of communicating
|
|
|
1126 |
processes in a single address space.
|
|
|
1127 |
One subset of the processes drives the display and user interface,
|
|
|
1128 |
maintaining the windows; other processes forward mouse and keyboard
|
|
|
1129 |
activity and implement the file server interface for external programs.
|
|
|
1130 |
The language and design worked out well;
|
|
|
1131 |
as explained elsewhere [Pike89, Gans93, Reppy93],
|
|
|
1132 |
user interfaces built with concurrent systems
|
|
|
1133 |
can avoid the clumsy
|
|
|
1134 |
top-level event loop typical of traditional interactive systems.
|
|
|
1135 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1136 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1137 |
<span style="font-size: 10pt">An example of the benefits of the multi-process style
|
|
|
1138 |
is the management of the state of open
|
|
|
1139 |
files held by clients of the file system interface.
|
|
|
1140 |
The problem is that some I/O requests,
|
|
|
1141 |
such as reading the
|
|
|
1142 |
</span><span style="font-size: 10pt"><tt>event</tt></span><span style="font-size: 10pt">
|
|
|
1143 |
file, may block if no data is available, and the server must
|
|
|
1144 |
maintain the state of (possibly many) requests until data appears.
|
|
|
1145 |
For example,
|
|
|
1146 |
in
|
|
|
1147 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">,
|
|
|
1148 |
a single-process window system written in C, pending requests were queued in
|
|
|
1149 |
a data structure associated with each window.
|
|
|
1150 |
After activity in the window that might complete pending I/O,
|
|
|
1151 |
the data structure was scanned for requests that could now finish.
|
|
|
1152 |
This structure did not fit well with the rest of the program and, worse,
|
|
|
1153 |
required meticulous effort
|
|
|
1154 |
to guarantee correct behavior under all conditions
|
|
|
1155 |
(consider raw mode, reads of partial lines, deleting a window,
|
|
|
1156 |
multibyte characters, etc.).
|
|
|
1157 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1158 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1159 |
<span style="font-size: 10pt">Acme instead creates a new dedicated process
|
|
|
1160 |
for each I/O request.
|
|
|
1161 |
This process coordinates with the rest of the system
|
|
|
1162 |
using Alef’s synchronous communication;
|
|
|
1163 |
its state implicitly encodes the state of
|
|
|
1164 |
the I/O request and obviates the need for queuing.
|
|
|
1165 |
The passage of the request through Acme proceeds as follows.
|
|
|
1166 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1167 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1168 |
<span style="font-size: 10pt">Acme contains a file server process, F, that executes a
|
|
|
1169 |
</span><span style="font-size: 10pt"><tt>read</tt></span><span style="font-size: 10pt">
|
|
|
1170 |
system call to receive a Plan 9 file protocol (9P) message from the client [AT&T92].
|
|
|
1171 |
The client blocks until Acme answers the request.
|
|
|
1172 |
F communicates with an allocation process, M,
|
|
|
1173 |
to acquire an object of type
|
|
|
1174 |
</span><span style="font-size: 10pt"><tt>Xfid</tt></span><span style="font-size: 10pt">
|
|
|
1175 |
(‘executing fid’; fid is a 9P term)
|
|
|
1176 |
to hold the request.
|
|
|
1177 |
M sits in a loop (reproduced in Figure 2) waiting for either a request for
|
|
|
1178 |
a new
|
|
|
1179 |
</span><span style="font-size: 10pt"><tt>Xfid</tt></span><span style="font-size: 10pt">
|
|
|
1180 |
or notification that an existing one has finished its task.
|
|
|
1181 |
When an
|
|
|
1182 |
</span><span style="font-size: 10pt"><tt>Xfid</tt></span><span style="font-size: 10pt">
|
|
|
1183 |
is created, an associated process, X,
|
|
|
1184 |
is also made.
|
|
|
1185 |
M queues idle
|
|
|
1186 |
</span><span style="font-size: 10pt"><tt>Xfids</tt></span><span style="font-size: 10pt">,
|
|
|
1187 |
allocating new ones only when the list is empty.
|
|
|
1188 |
Thus, there is always a pool of
|
|
|
1189 |
</span><span style="font-size: 10pt"><tt>Xfids</tt></span><span style="font-size: 10pt">,
|
|
|
1190 |
some executing, some idle.
|
|
|
1191 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1192 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1193 |
<span style="font-size: 10pt">The
|
|
|
1194 |
</span><span style="font-size: 10pt"><tt>Xfid</tt></span><span style="font-size: 10pt">
|
|
|
1195 |
object contains a channel,
|
|
|
1196 |
</span><span style="font-size: 10pt"><tt>Xfid.c</tt></span><span style="font-size: 10pt">,
|
|
|
1197 |
for communication with its process;
|
|
|
1198 |
the unpacked message; and some associated functions,
|
|
|
1199 |
mostly corresponding to 9P messages such as
|
|
|
1200 |
</span><span style="font-size: 10pt"><tt>Xfid.write</tt></span><span style="font-size: 10pt">
|
|
|
1201 |
to handle a 9P write request.
|
|
|
1202 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1203 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1204 |
<span style="font-size: 10pt">The file server process F parses the message to see its nature—open,
|
|
|
1205 |
close, read, write, etc. Many messages, such as directory
|
|
|
1206 |
lookups, can be handled immediately; these are responded to directly
|
|
|
1207 |
and efficiently
|
|
|
1208 |
by F without invoking the
|
|
|
1209 |
</span><span style="font-size: 10pt"><tt>Xfid</tt></span><span style="font-size: 10pt">,
|
|
|
1210 |
which is therefore maintained until the next message.
|
|
|
1211 |
When a message, such as a write to the display, requires the attention
|
|
|
1212 |
of the main display process and interlocked access to its data structures,
|
|
|
1213 |
F enables X
|
|
|
1214 |
by sending a function pointer on
|
|
|
1215 |
</span><span style="font-size: 10pt"><tt>Xfid.c</tt></span><span style="font-size: 10pt">.
|
|
|
1216 |
For example, if the message is a write, F executes
|
|
|
1217 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
1218 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1219 |
<span style="font-size: 9pt"><tt>x->c <-= Xfid.write;</tt></span></p>
|
|
|
1220 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1221 |
|
|
|
1222 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
1223 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1224 |
<span style="font-size: 10pt">which sends
|
|
|
1225 |
the address of
|
|
|
1226 |
</span><span style="font-size: 10pt"><tt>Xfid.write</tt></span><span style="font-size: 10pt">
|
|
|
1227 |
on
|
|
|
1228 |
</span><span style="font-size: 10pt"><tt>Xfid.c</tt></span><span style="font-size: 10pt">,
|
|
|
1229 |
waking up X.
|
|
|
1230 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1231 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1232 |
<span style="font-size: 10pt">The
|
|
|
1233 |
</span><span style="font-size: 10pt"><tt>Xfid</tt></span><span style="font-size: 10pt">
|
|
|
1234 |
process, X, executes a simple loop:
|
|
|
1235 |
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
1236 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1237 |
<span style="font-size: 9pt"><tt>void</tt></span></p>
|
|
|
1238 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1239 |
<span style="font-size: 9pt"><tt>Xfid.ctl(Xfid *x)</tt></span></p>
|
|
|
1240 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1241 |
<span style="font-size: 9pt"><tt>{</tt></span></p>
|
|
|
1242 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1243 |
<span style="font-size: 9pt"><tt> for(;;){</tt></span></p>
|
|
|
1244 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1245 |
<span style="font-size: 9pt"><tt> (*<-x->c)(x); /* receive and execute message */</tt></span></p>
|
|
|
1246 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1247 |
<span style="font-size: 9pt"><tt> bflush(); /* synchronize bitmap display */</tt></span></p>
|
|
|
1248 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1249 |
<span style="font-size: 9pt"><tt> cxfidfree <-= x; /* return to free list */</tt></span></p>
|
|
|
1250 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1251 |
<span style="font-size: 9pt"><tt> }</tt></span></p>
|
|
|
1252 |
<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1253 |
<span style="font-size: 9pt"><tt>}</tt></span></p>
|
|
|
1254 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1255 |
|
|
|
1256 |
<p style="margin-top: 0; margin-bottom: 0.08in"></p>
|
|
|
1257 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1258 |
<span style="font-size: 10pt">Thus X
|
|
|
1259 |
will wake up with the address of a function to call (here
|
|
|
1260 |
</span><span style="font-size: 10pt"><tt>Xfid.write</tt></span><span style="font-size: 10pt">)
|
|
|
1261 |
and execute it; once that completes, it returns itself to the pool of
|
|
|
1262 |
free processes by sending its address back to the allocator.
|
|
|
1263 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1264 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1265 |
<span style="font-size: 10pt">Although this sequence may seem complicated, it is just a few lines
|
|
|
1266 |
of code and is in fact far simpler
|
|
|
1267 |
than the management of the I/O queues in
|
|
|
1268 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">.
|
|
|
1269 |
The hard work of synchronization is done by the Alef run time system.
|
|
|
1270 |
Moreover, the code worked the first time, which cannot be said for the code in
|
|
|
1271 |
</span><span style="font-size: 10pt"><tt>8½</tt></span><span style="font-size: 10pt">.
|
|
|
1272 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1273 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1274 |
<span style="font-size: 10pt"><b>Undo
|
|
|
1275 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1276 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1277 |
<span style="font-size: 10pt">Acme provides a general undo facility like that of Sam, permitting
|
|
|
1278 |
textual changes to be unwound arbitrarily.
|
|
|
1279 |
The implementation is superior to Sam’s, though,
|
|
|
1280 |
with much higher performance and the ability to ‘redo’ changes.
|
|
|
1281 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1282 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1283 |
<span style="font-size: 10pt">Sam uses
|
|
|
1284 |
a multi-pass algorithm that builds
|
|
|
1285 |
a transcript of changes to be made simultaneously
|
|
|
1286 |
and then executes them atomically.
|
|
|
1287 |
This was thought necessary because the elements of a repetitive
|
|
|
1288 |
command such as a global substitution should all be applied to the same
|
|
|
1289 |
initial file and implemented simultaneously; forming the complete
|
|
|
1290 |
transcript before executing any of the changes avoids the
|
|
|
1291 |
cumbersome management of addresses in a changing file.
|
|
|
1292 |
Acme, however, doesn’t have this problem; global substitution
|
|
|
1293 |
is controlled externally and may be made incrementally by exploiting
|
|
|
1294 |
an observation: if the changes are sorted in address order and
|
|
|
1295 |
executed in reverse, changes will not invalidate the addresses of
|
|
|
1296 |
pending changes.
|
|
|
1297 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1298 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1299 |
<span style="font-size: 10pt">Acme therefore avoids the initial transcript. Instead, changes are applied
|
|
|
1300 |
directly to the file, with an undo transcript recorded in a separate list.
|
|
|
1301 |
For example, when text is added to a window, it is added directly and a record
|
|
|
1302 |
of what to delete to restore the state is appended to the undo list.
|
|
|
1303 |
Each undo action and the file are marked with a sequence number;
|
|
|
1304 |
actions with the same sequence number are considered a unit
|
|
|
1305 |
to be undone together.
|
|
|
1306 |
The invariant state of the structure
|
|
|
1307 |
is that the last action in the undo list applies to the current state of the file,
|
|
|
1308 |
even if that action is one of a related set from, for example, a global substitute.
|
|
|
1309 |
(In Sam, a related set of actions needed to be undone simultaneously.)
|
|
|
1310 |
To undo an action, pop the last item on the undo list, apply it to the file,
|
|
|
1311 |
revert it, and append it to a second, redo list.
|
|
|
1312 |
To redo an action, do the identical operation with the lists interchanged.
|
|
|
1313 |
The expensive operations occur
|
|
|
1314 |
only when actually undoing; in normal editing the overhead is minor.
|
|
|
1315 |
For example, Acme reads files about seven times faster than Sam, partly
|
|
|
1316 |
because of this improvement and partly because of a cleaner implementation.
|
|
|
1317 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1318 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1319 |
<span style="font-size: 10pt">Acme uses a temporary file to hold the text, keeping in memory only the
|
|
|
1320 |
visible portion, and therefore can edit large files comfortably
|
|
|
1321 |
even on small-memory machines such as laptops.
|
|
|
1322 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1323 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1324 |
<span style="font-size: 10pt"><b>Future
|
|
|
1325 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1326 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1327 |
<span style="font-size: 10pt">Acme is still under development.
|
|
|
1328 |
Some things are simply missing.
|
|
|
1329 |
For example, Acme should support non-textual graphics, but this is being
|
|
|
1330 |
deferred until it can be done using a new graphics model being developed
|
|
|
1331 |
for Plan 9. Also, it is undecided how Acme’s style of interaction should best be
|
|
|
1332 |
extended to graphical applications.
|
|
|
1333 |
On a smaller scale, although the system feels smooth and comfortable,
|
|
|
1334 |
work continues to tune the heuristics and
|
|
|
1335 |
try new ideas for the user interface.
|
|
|
1336 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1337 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1338 |
<span style="font-size: 10pt">There need to be more programs that use Acme. Browsers for
|
|
|
1339 |
Usenet and AP News articles, the Oxford English Dictionary, and other
|
|
|
1340 |
such text sources exist, but more imaginative applications will
|
|
|
1341 |
be necessary to prove that Acme’s approach is viable.
|
|
|
1342 |
One that has recently been started is an interface to the debugger Acid [Wint94],
|
|
|
1343 |
although it is still
|
|
|
1344 |
unclear what form it will ultimately take.
|
|
|
1345 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1346 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1347 |
<span style="font-size: 10pt">Acme shows that it is possible to make a user interface a stand-alone component
|
|
|
1348 |
of an interactive environment. By absorbing more of the interactive
|
|
|
1349 |
functionality than a simple window system, Acme off-loads much of the
|
|
|
1350 |
computation from its applications, which helps keep them small and
|
|
|
1351 |
consistent in their interface. Acme can afford to dedicate
|
|
|
1352 |
considerable effort to making that interface as good as possible; the result
|
|
|
1353 |
will benefit the entire system.
|
|
|
1354 |
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1355 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1356 |
<span style="font-size: 10pt">Acme is complete and useful enough to attract users.
|
|
|
1357 |
Its comfortable user interface,
|
|
|
1358 |
the ease with which it handles multiple tasks and
|
|
|
1359 |
programs in multiple directories,
|
|
|
1360 |
and its high level of integration
|
|
|
1361 |
make it addictive.
|
|
|
1362 |
Perhaps most telling,
|
|
|
1363 |
Acme shows that typescripts may not be the most
|
|
|
1364 |
productive interface to a time-sharing system.
|
|
|
1365 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1366 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1367 |
<span style="font-size: 10pt"><b>Acknowledgements
|
|
|
1368 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1369 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1370 |
<span style="font-size: 10pt">Howard Trickey, Acme’s first user, suffered buggy versions gracefully and made
|
|
|
1371 |
many helpful suggestions. Chris Fraser provided the necessary insight for the Acme editing
|
|
|
1372 |
commands.
|
|
|
1373 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1374 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1375 |
<span style="font-size: 10pt"><b>References
|
|
|
1376 |
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
|
|
|
1377 |
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1378 |
<span style="font-size: 10pt">[Alef] P. Winterbottom,
|
|
|
1379 |
‘‘Alef Language Reference Manual’’,
|
|
|
1380 |
</span><span style="font-size: 10pt"><i>Plan 9 Programmer’s Manual,
|
|
|
1381 |
</i></span><span style="font-size: 10pt">AT&T Bell Laboratories,
|
|
|
1382 |
Murray Hill, NJ,
|
|
|
1383 |
1992;
|
|
|
1384 |
revised in this volume.
|
|
|
1385 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1386 |
<span style="font-size: 10pt">[Alle92]
|
|
|
1387 |
</span><span style="font-size: 10pt"><i>Allegro Common Lisp user Guide, Vol 2,
|
|
|
1388 |
</i></span><span style="font-size: 10pt">Chapter 14, "The Emacs-Lisp Interface".
|
|
|
1389 |
March 1992.
|
|
|
1390 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1391 |
<span style="font-size: 10pt">[AT&T92] Plan 9 Programmer’s manual, Murray Hill, New Jersey, 1992.
|
|
|
1392 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1393 |
<span style="font-size: 10pt">[Far89] Far too many people, XTERM(1), Massachusetts Institute of Technology, 1989.
|
|
|
1394 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1395 |
<span style="font-size: 10pt">[Gans93] Emden R. Gansner and John H. Reppy, ‘‘A Multi-threaded Higher-order User Interface Toolkit’’, in
|
|
|
1396 |
</span><span style="font-size: 10pt"><i>Software Trends, Volume 1,
|
|
|
1397 |
User Interface Software,
|
|
|
1398 |
</i></span><span style="font-size: 10pt">Bass and Dewan (Eds.),
|
|
|
1399 |
John Wiley & Sons 1993,
|
|
|
1400 |
pp. 61-80.
|
|
|
1401 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1402 |
<span style="font-size: 10pt">[Lucid92] Richard Stallman and Lucid, Inc.,
|
|
|
1403 |
</span><span style="font-size: 10pt"><i>Lucid GNU EMACS Manual,
|
|
|
1404 |
</i></span><span style="font-size: 10pt">March 1992.
|
|
|
1405 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1406 |
<span style="font-size: 10pt">[Pike87] Rob Pike, ‘‘The Text Editor </span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’’, Softw. - Pract. and Exp., Nov 1987, Vol 17 #11, pp. 813-845; reprinted in this volume.
|
|
|
1407 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1408 |
<span style="font-size: 10pt">[Pike88] Rob Pike, ‘‘Window Systems Should Be Transparent’’, Comp. Sys., Summer 1988, Vol 1 #3, pp. 279-296.
|
|
|
1409 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1410 |
<span style="font-size: 10pt">[Pike89] Rob Pike, ‘‘A Concurrent Window System’’, Comp. Sys., Spring 1989, Vol 2 #2, pp. 133-153.
|
|
|
1411 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1412 |
<span style="font-size: 10pt">[PPTTW93] Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom, ‘‘The Use of Name Spaces in Plan 9’’,
|
|
|
1413 |
Op. Sys. Rev., Vol. 27, No. 2, April 1993, pp. 72-76,
|
|
|
1414 |
reprinted in this volume.
|
|
|
1415 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1416 |
<span style="font-size: 10pt">[Pike91] Rob Pike, ‘‘8½, the Plan 9 Window System’’, USENIX Summer Conf. Proc., Nashville, June, 1991, pp. 257-265,
|
|
|
1417 |
reprinted in this volume.
|
|
|
1418 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1419 |
<span style="font-size: 10pt">[Pike92] Rob Pike, ‘‘A Minimalist Global User Interface’’, Graphics Interface ’92 Proc., Vancouver, 1992, pp. 282-293. An earlier version appeared under the same title in USENIX Summer Conf. Proc., Nashville, June, 1991, pp. 267-279.
|
|
|
1420 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1421 |
<span style="font-size: 10pt">[Pike93] Rob Pike and Ken Thompson, ‘‘Hello World or Καλημέρα κόσμε or
|
|
|
1422 |
</span><span style="font-size: 10pt">こんにちは 世界</span><span style="font-size: 10pt">’’, USENIX Winter Conf. Proc., San Diego, 1993, pp. 43-50,
|
|
|
1423 |
reprinted in this volume.
|
|
|
1424 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1425 |
<span style="font-size: 10pt">[Pres93] Dave Presotto and Phil Winterbottom, ‘‘The Organization of Networks in Plan 9’’, Proc. Usenix Winter 1993, pp. 271-287, San Diego, CA,
|
|
|
1426 |
reprinted in this volume.
|
|
|
1427 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1428 |
<span style="font-size: 10pt">[Reis91] Martin Reiser, </span><span style="font-size: 10pt"><i>The Oberon System,</i></span><span style="font-size: 10pt"> Addison Wesley, New York, 1991.
|
|
|
1429 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1430 |
<span style="font-size: 10pt">[Reppy93] John H. Reppy,
|
|
|
1431 |
‘‘CML: A higher-order concurrent language’’, Proc. SIGPLAN’91 Conf. on Programming, Lang. Design and Impl., June, 1991, pp. 293-305.
|
|
|
1432 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1433 |
<span style="font-size: 10pt">[Sche86] Robert W. Scheifler and Jim Gettys,
|
|
|
1434 |
‘‘The X Window System’’,
|
|
|
1435 |
ACM Trans. on Graph., Vol 5 #2, pp. 79-109.
|
|
|
1436 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1437 |
<span style="font-size: 10pt">[Stal93] Richard Stallman,
|
|
|
1438 |
</span><span style="font-size: 10pt"><i>Gnu Emacs Manual, 9th edition, Emacs version 19.19,
|
|
|
1439 |
</i></span><span style="font-size: 10pt">MIT.
|
|
|
1440 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1441 |
<span style="font-size: 10pt">[Swei86] Daniel Sweinhart, Polle Zellweger, Richard Beach, and Robert Hagmann,
|
|
|
1442 |
‘‘A Structural View of the Cedar Programming Environment’’,
|
|
|
1443 |
ACM Trans. Prog. Lang. and Sys., Vol. 8, No. 4, pp. 419-490, Oct. 1986.
|
|
|
1444 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1445 |
<span style="font-size: 10pt">[Wint94], Philip Winterbottom, ‘‘Acid: A Debugger based on a Language’’, USENIX Winter Conf. Proc., San Francisco, CA, 1993,
|
|
|
1446 |
reprinted in this volume.
|
|
|
1447 |
</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1448 |
<span style="font-size: 10pt">[Wirt89] N. Wirth and J. Gutknecht, ‘‘The Oberon System’’, Softw. - Prac. and Exp., Sep 1989, Vol 19 #9, pp 857-894.
|
|
|
1449 |
</span></p><p style="margin-top: 0; margin-bottom: 0.50in"></p>
|
|
|
1450 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1451 |
<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1452 |
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>Notes</b></span><span style="font-size: 10pt">
|
|
|
1453 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1454 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1455 |
|
|
|
1456 |
<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.00in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
|
|
|
1457 |
<span style="font-size: 10pt">Originally appeared in
|
|
|
1458 |
</span><span style="font-size: 10pt"><i>Proc. of the Winter 1994 USENIX Conf.,
|
|
|
1459 |
</i></span><span style="font-size: 10pt">pp. 223-234,
|
|
|
1460 |
San Francisco, CA
|
|
|
1461 |
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1462 |
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
|
|
|
1463 |
|
|
|
1464 |
</body>
|
|
|
1465 |
</html>
|
|
|
1466 |
|