
Onward! ’22, December 8–10, 2022, Auckland, New Zealand Philippe Voinov, Manuel Rigger, and Zhendong Su
(AST). For some common edits, such as renaming a vari-
able and all usages, Integrated Development Environments
(IDEs) contain built-in refactorings that operate structurally.
Existing tools are discussed in detail in Section 6.
Textual tools (left half of Figure 1), such as multi-cursor
text editors or regular expressions, have many advantages
over structural tools. They use familiar concepts from single-
location text editing. Since these tools do not inspect the
syntax of a program, they work with any programming lan-
guage and in programs with invalid syntax. However, this
lack of syntactic understanding makes it complex or im-
possible to perform certain edits in multiple locations. For
example, since many operations in textual tools depend on
the way that a program is formatted, they require the user
to make adjustments to match their code style. Attempting
to use nd-replace with regular expressions to swap the
order of two arguments in every call to a function high-
lights these limitations: If the function calls are always on a
single line and the arguments themselves are syntactically
simple (e.g. numeric literals), then the regular expression is
simple. However, in the general case where a function call
spans multiple lines and its arguments may themselves be
function calls, correctly performing the edit would require
parsing the code. Multi-cursor text editors, editors where ev-
ery movement and text edit is replayed in multiple locations
simultaneously, provide an interactive editing experience
for multiple locations. They allow users to edit multiple lo-
cations using the same commands as for a single location,
letting users apply familiar concepts from conventional text
editors. However, the edits that they can express are limited.
Typically, only commands such as inserting text or moving
in whole words or lines are supported.
Structural tools (right half of Figure 1) can perform more
complex edits than textual tools, and provide commands
which can be reliably applied in many locations. However,
they only work with valid syntax and require explicit sup-
port for each programming language. AST-based refactoring
scripts are programs in a general purpose programming lan-
guage that directly manipulate an AST. They are used to
perform repetitive edits in large scale code bases. At this
scale, operating on an AST is signicantly more reliably
than textual operations. Additionally, since such scripts use
a general purpose programming language, they can encode
more complex editing logic than other tools. However, the
process of developing such scripts is completely dierent to
conventional code editing (the user must write a program to
edit their code, instead of editing it directly), making them
impractical for small-scale repetitive edits. Structural nd-
replace tools are the structural equivalent of nd-replace
with regular expressions. They are more reliable than textual
nd-replace, but require an understanding of the AST and
use a separate set of concepts than conventional text editing.
Additionally, both textual and structural nd-replace have
limited support for encoding logic, such as ltering which
locations should be edited.
At a high level, we propose to combine multi-cursor edit-
ing with structural editing commands. This preserves the
key advantages of multi-cursor text editors: multiple loca-
tions are edited in the same way as a single location and
results are immediately shown. However, by using structural
commands instead of textual commands, more complex edits
are supported, and edits can be performed reliably in many
locations regardless of formatting and nested syntax.
Our prototype editor, Forest, is a multi-cursor structural
editor for TypeScript. In Forest, cursors point to AST nodes.
The user navigates within the AST by using structural oper-
ations like “move to parent”. These operations work reliably
in situations where textual tools are ineective, such as with
complex nested syntax. To retain the strengths and familiar-
ity of text editors, insertions are performed by parsing typed
text. A cursor can be split (e.g., for each child of the selected
AST node) to create multiple cursors that handle editing
commands simultaneously. This allows users to perform
repetitive edits the same way as they would when editing a
single location. A novel hierarchy of cursors concept makes it
practical to work with cursors that were split multiple times.
To understand the strengths and weaknesses of multi-
cursor structural editing, we collected real-world AST-based
refactoring scripts and attempted to perform the correspond-
ing edits interactively in Forest. Of the 48 edits, 11 could
be performed without any signicant issues, and a further
17 would likely become practical with improvements to the
editor. This shows that developers could avoid writing some—
but not all—refactoring scripts and instead use a multi-cursor
structural editor to perform their edit interactively.
We make three main contributions:
•
We built Forest
1
— a structural editor prototype for
TypeScript. Forest is one of very few structural editors
for modern languages with complex syntax.
•
We extended Forest to support multiple cursors, with
special integration between multi-cursor editing and
structural editing. This is the only multi-cursor struc-
tural editor with such integration.
•
We evaluated how Forest compares to refactoring
scripts, showing that Forest can be used to perform
edits from some real-world refactoring scripts.
1Online version of Forest with interactive examples:
hps://forestonward2022.walr.is/
GitHub: hps://github.com/tehwalris/forest
Archive: hps://doi.org/10.5281/zenodo.7225442