History of Leo

This chapter discusses the history of Leo and tells the essential features of each version. Here are the most important dates in Leo’s history:

Beginnings

Leo grew out of my efforts to use Donald Knuth’s “CWEB system of Structured documentation.” I had known of literate programming since the mid 1980’s, but I never understood how to make it work for me. In November 1995 I started thinking about programming in earnest. Over the holidays I mused about making programs more understandable. In January 1996 the fog of confusion suddenly cleared. I summarized my thinking with the phrase, web are outlines in disguise. I suspected that outline views were the key to programming, but many details remained obscure.

Breakthrough

March 5, 1996, is the most important date in Leo’s history. While returning from a day of skiing, I discussed my thoughts with Rebecca. During that conversation I realized that I could use the MORE outliner as a prototype for a “programming outliner.” I immediately started work on my first outlined program. It quickly became apparent that outlines work: all my old problems with programming vanished. The @others directive dates from this day. I realized that MORE’s outlines could form the basis for Leo’s screen design. Rather than opening body text within the outline, as MORE does, I decided to use a separate body pane.

I hacked a translator called M2C which allowed me to use MORE to write real code. I would write code in MORE, copy the text to the clipboard in MORE format, then run M2C, which would convert the outline into C code. This process was useful, if clumsy. I called the language used in the outline SWEB, for simplified CWEB. Much later Leo started supporting the noweb language.

Apple and YellowBox

Throughout 1996 I created a version of Leo on the Macintosh in plain C and the native Mac Toolbox. This was a poor choice; I wasted a huge amount of time programming with these primitive tools. However, this effort convinced me that Leo was a great way to program.

Late in 1997 I wrote a Print command to typeset an outline. Printing (Weaving) is supposedly a key feature of literate programming. Imagine my surprise when I realized that such a “beautiful” program listing was almost unintelligible; all the structure inherent in the outline was lost! I saw clearly that typesetting, no matter how well done, is no substitute for explicit structure.

In 1998 I created a version of Leo using Apple’s YellowBox environment. Alas, Apple broke its promises to Apple developers. I had to start again.

Borland C++

I rewrote Leo for Borland C++ starting in May 1999. Borland C++ was much better than CodeWarrior C, but it was still C++. This version of Leo was the first version to use xml as the format of .leo files. The last version of Borland Leo, 3.12 Final went out the door July 17, 2003.

Discovering Python

I attended the Python conference in early 2001. In May of 2000 I began work on an wxWindows version of Leo. This did not work out, but something good did come from this effort. I spent a lot of time adding Python scripting to the wxWindows code and I became familiar with Python and its internals.

I really started to ‘get’ Python in September 2001. I wrote the white papers at about this time. Python solved all my programming problems. I rewrote Leo in Python in about two months! For the first time in my career I was no longer anxious while programming; it simply isn’t possible to create bad bugs in Python. The Python version of Leo was the first officially OpenSoftware version of Leo. The first functional version of Leo in Python was 0.05 alpha, December 17, 2001.

SourceForge

I registered the Leo project on SourceForge on March 10, 2003. It is certainly no accident that Leo started a new life shortly thereafter. Prior to SourceForge my interest in Leo had been waning.

Allowing sentinel lines in external files

In the summer of 2001 I began to consider using sentinel lines in external files. Previously I had thought that outline structure must be ‘protected’ by remaining inside .leo files. Accepting the possibility that sentinels might be corrupted opened vast new design possibilities. In retrospect, problems with sentinel almost never happen, but that wasn’t obvious at the time! The result of this design was known at first as Leo2. That terminology is extinct. I think of this version as the first version to support @file and automatic tangling and untangling.

Untangling @file is easy!

The biggest surprise in Leo’s history was the realization it is much easier to untangle files derived from @file. Indeed, the old tangle code created all sorts of problems that just disappear when using @file. The new Python version of Leo became fully operational in early 2002. It was probably about this time that I chose noweb as Leo’s preferred markup language. My decision not to support noweb’s escape sequences made Leo’s read code much more robust.

Leo 3.x: Continuous improvement

I spent 2002 taking advantages of Python’s tremendous power and safety. Many improvements were at last easy enough to do:

  • Nested @others directives appeared in 3.2.
  • Unicode support started in 3.3.
  • @first and @last appeared in 3.7
  • @asis and @nosent appeared in 3.8.
  • Incremental syntax coloring and incremental undo appeared in 3.9.
  • Paul Paterson created Leo’s plugin architecture sometime during this period. Plugins have been a driving force in Leo’s development because people can change how Leo works without altering Leo’s core.
  • 3.12 fixed a huge memory leak.
  • 3.12 Final, the last 3.x version, appeared July 17, 2003.

Leo 4.0: Eliminating error ‘recovery’

In late 2002 and throughout 2003 I worked on an entirely new file format. 4.0 final went out the door October 17, 2003 after almost a year intense design work trying to improve error recovery scheme used while reading external files. In the summer of 2003 I realized that orphan and @ignore’d nodes must be prohibited in @file trees. With this restriction, Leo could finally recreate @file trees in outlines using only the information in external files. This made the read code much more robust, and eliminated all the previous unworkable error recovery schemes. At last Leo was on a completely firm foundation.

Leo 4.1: The debut of gnx’s

Leo first used gnx’s (global node indices) as a foolproof way of associating nodes in .leo files with nodes in external files. At the time, there was still intense discussions about protecting the logical consistency of outlines. @thin was later to solve all those problems, but nobody knew that then.

Leo 4.2: Complete at last

Leo 4.2 Final went out the door September 20, 2004. This surely is one of the most significant dates in Leo’s history:

  • This marked the end worries about consistency of outlines and external files: Leo recreates all essential information from thin external files, so there is nothing left in the .leo file to get out of synch.

  • Thin external files use gnx’s extensively. This simplifies the file format and

    makes thin external files more cvs friendly.

  • A sensational scripting plugin showed how to create script buttons. This has lead to improvements in the Execute Script command and other significant improvements in Unit testing.

  • As if this were not enough, 4.2 marked the ‘great divide’ in Leo’s internal data structures. Before 4.2, Leo every node in the outline had its own vnode. This was a big performance problem: clone operations had to traverse the entire outline! 4.2 represents clones by sharing subtrees. Changing Leo’s fundamental data structures while retaining compatibility with old scripts was engineering work of which the entire Leo community can be proud. Scripting Leo with Python tells how the position class makes this happen. This was a cooperative effort. Kent Tenney and Bernhard Mulder made absolutely crucial contributions. Kent pointed out that it is a tnode, not a vnode that must form the root of the shared data. Bernhard showed that iterators are the way to avoid creating huge numbers of positions.

Leo 4.2 marked so many significant changes. I often find it hard to remember what life with Leo was like before it.

Leo 4.3 Settings

Leo 4.3 corrected many problems with leoConfig.txt. Instead, Leo gets settings from one or more leoSettings.leo files. This version also introduced a way to changed settings using a settings dialog. However, the settings dialog proved not to be useful (worse, it inhibited design) and the settings dialog was retired in Leo 4.4.

Leo 4.4 The minibuffer and key bindings

Leo 4.4 was a year-long effort to incorporate an Emacs-style minibuffer and related commands into Leo. Thinking in terms of minibuffer commands frees my thinking. Leo 4.4 also featured many improvements in how keys are bound to commands, including per-pane bindings and user-defined key-binding modes.

Development on long-delayed projects accelerated after 4.4 final went out the door. Recent projects include:

  • Controlling syntax coloring with jEdit’s xml language-description files.
  • Support for debugging scripts using external debuggers.
  • Modifying Leo’s vnodes and tnodes so that Leo’s data can be used with ZODB.
  • Using pymacs to write Leo scripts within Emacs.
  • Using the leoBridge module to embed Leo support in other programs.
  • Using Leo to run unit tests.

Leo 4.4.x Improvements

This series of releases featured hundreds of improvements. The highlights were truly significant:

  • Added the leoBridge module. See Embedding Leo with the leoBridge Module.
  • Added support for @enabled-plugins and @open-with nodes in settings files.
  • Added support for ZODB. See Using ZODB with Leo.
  • Added leoPymacs module. See Leo and Emacs.
  • Added perfect import of external files with @auto nodes.
  • Used the sax parser to .leo files. This allows the format of .leo files to be expanded easily.
  • Added support for myLeoSettings.leo.
  • Supported multiple editors in body pane.
  • Added the jEdit_colorizer plugin. See Controlling Syntax Coloring.
  • Many other new plugins.

For a complete list, see the What’s New chapter.

Leo 4.5 @shadow files

Added support for @shadow files. This was a major breakthrough. See the Using @shadow chapter for full details.

Leo 4.6 Caching, Qt and more

This version of Leo featured more significant improvements:

  • Added support for the Qt gui. This was a major project that significantly improves the look and feel of Leo.
  • A file-caching scheme produced spectacular improvements in the speed of loading Leo outlines.
  • Added support for @auto-rst nodes. These import reStructuredText (rST) files so that the files can be “round-tripped” without introducing extraneous changes. This makes Leo a superb environment for using rST.
  • Added support for @edit nodes.

Leo 4.7 The one node world and Python 3k

Leo 4.7 accomplishes something I long thought to be impossible: the unification of vnodes and tnodes. tnodes now longer exist: vnodes contain all data. The Aha that made this possible is that iterators and positions allow a single node to appear in more than one place in a tree traversal.

This is one of the most significant developments in Leo’s history. At last the endless confusion between vnodes and tnodes is gone. At the most fundamental level, Leo’s data structures are as simple as possible. This makes them as general and as powerful as possible!

This version successfully produced a common code base that can run on both Python 2.x and Python 3.x.

Leo 4.8 Simple sentinels & better data recovery

Leo 4.8 simplified Leo’s sentinels as much as possible. Leo’s sentinel lines look very much like Emacs org-mode comment lines, except for the addition of gnx’s.

This version also produced a fundamentally important addition to Leo’s error recovery. Leo now shows “Resurrected” and “Recovered” nodes when loading an outline. These nodes protect against data loss, and also implicitly warn when unusual data-changing events occur. Creating this scheme is likely the final chapter in the epic saga of error recovery in Leo.

Previous topic

Designing with Leo

Next topic

Theory of Operation