Leo is an easy to learn, powerful programming editor, data management tool and scripting environment for the Python language. Many people say that Leo is fun to use, even addicting.
Leo is a powerful & easy to learn. It’s a programming editor, data management tool, and python scripting environment.
Leo is freely available in source or binary form for all major platforms. You may download Leo from http://sourceforge.net/projects/leo/files/Leo/ Leo is Open Software and may be freely distributed.
Leo’s home page contains additional documentation and links to other resources. For another introduction to Leo, open the file quickstart.leo in the leo/doc folder.
This tutorial introduces the reader to the basic concepts and features of Leo. It helps to have Leo running for hands-on experience, but all examples here are self-contained, so the tutorial can be read off-line as well. See Leo’s Installation Guide. for detailed installation instructions. If you have problems installing Leo, please ask for help on Leo’s help forum.
This tutorial does not attempt to be comprehensive and cover every single feature of Leo, or even every commonly used feature. Instead, it introduces many of Leo’s most noteworthy features, and will give you a good idea of Leo’s flavor and style. After reading it, you will be able to use Leo in basic ways to create external files and organize data. You will then be ready to learn more about Leo’s many advanced features in Leo’s Users Guide.
Contents
If you do much work on computers, you’ll eventually want to organize lots of data. You may also want to automate tasks that operate on those data.
For example, you may want to organize photos into a photo album, or organize notes about interesting web sites. You might want organize your data, whether it be photos, notes or anything else, in various ways. You might want to include a particular photo in several slideshows, but not in all of your slideshows, and you might want to put that photo at the start of one slideshow, but in the middle of another.
Or you might be a computer programmer who wants to have all the data for a computer project in a single place. You want to organize the source files of your program along with related scripts, design notes, documentation, bug fixes and unit tests. And like the photographer who wants to organize slides in a variety of different slideshows, you want the organize all the data in your project in many task-oriented ways simultaneously. Finally, you would like to be able apply scripts to all the data in your project so you can automate project-specific tasks. You might even want to create scripts that analyze, modify and refactor the source code in your project.
Leo is just the tool for you.
Leo stores all its data in a tree of nodes, represented on the screen as an outline. Leo outline ares more flexible than usual: clones are nodes that may appear in multiple places within an outline. Using clones, Leo can act like a flexible filing cabinet in which nodes may be filed in many folders at once.
Any part of a Leo tree may generate an external file (a file on your computer’s file system). Leo defines simple, outline-oriented markup that tells Leo how to create the external file from an outline. Thus, a single Leo outline can contain all the files of a programming project or any other set of related files.
Any node in a Leo outline may contain a Python script. We call these scripts Leo scripts to emphasize that they are fully integrated with Leo. All of Leo is written in Python, so Leo scripts can use (or change!) any part of Leo while Leo is running. Furthermore, Leo scripts have easy access to all the data in any Leo outline. Because Leo scripts have full access to both Leo’s source code and Leo outlines, it is easy for Leo scripts to create new commands that act on any part of an outline. This is a big reason why Leo is so much fun to use. You don’t have to wait for somebody to add a new feature to Leo–you can do often do it yourself in a matter of minutes. Many of Leo’s commands started out this way.
Now that you have some insight into Leo, you’ll want to examine it in some more detail. Since the best way to learn a language is to use it, the tutorial invites you to play with Leo as you read.
Leo’s name used to be an acronym but that acronym is obsolete. However, the term Leonine describes how people treat data in “the world according to Leo”.
Leo’s main window, shown below, represents an entire project and is stored in a single Leo file, a file with a .leo extension. As you can see, the main window contains three panes: the outline pane at the top left, the log pane at the top right, and the body pane at the bottom. The window also contains an icon area at the very top, a status area and a mini-buffer at the very bottom.
Now that we are familiar with Leo’s main window, let’s see how to use Leo as a simple outliner.
You can use Leo as fairly typical outliner. Play around with some of the commands from the Outline menu:
You enter body text for any node by selecting the node’s headline in the outline pane and then typing in the body pane. Leo has a full range of editing commands that apply to the body pane.
You don’t have to store all outline data in Leo (.leo) files. Leo allows you to store outline data in external files called external files. This is useful for creating programming files, documentation files such as LaTeX files, and web pages.
Important: You can edit external files outside of Leo. Leo will update the outline to reflect those changes when Leo next opens the outline.
It is easy to create external files; just put @thin filename in a headline. That creates an @thin node. The @thin tree (the @thin node and all its descendants) corresponds to the external file filename. Leo writes a external file corresponding to the @thin tree to your hard drive when Leo saves your outline (.leo file). When opening a .leo file, Leo reads all the external files corresponding to @thin nodes in the outline.
A good rule of thumb is to use @thin nodes unless you have a specific reason to do otherwise. See Chapter 4: Writing Programs in Leo for a full discussions of the various ways of creating external files.
Important: You must tell Leo the order in which to write data from the @thin tree to the external file. The simplest way to specify the contents of a external file is to insert:
@all
in the body text of the @thin node. @all is a Leo directive.
When writing a external file, Leo writes the body text of the @thin node, replacing the @all directive by the body text of all the descendant nodes in outline order, the order that nodes appear on the screen when all nodes are expanded. Leo for Programmers discusses other, more flexible, ways of creating external files from @thin trees. Note: Leo copies headlines to the external file as comments. This means that headlines do not affect the meaning of external files and you can use headlines to contain whatever data you wish. Usually, headlines describe what’s in the node.
A clone is a node that appears in more than one place in the outline. Clones are marked with a small red arrow in the icon box. All clones of a node are actually the same node, so any change to one clone affects all clones. For example, inserting, moving or deleting any child of a clone will change all other clones on the screen.
Please take a few moments to experiment with clones. Create a node whose headline is A. Clone node A using the Clone Node command in Leo’s Outline menu.
Type some text into the body of either clone of A. The same text appears in the bodies of all other clones of A. Now insert a node, say B, as a child of any of the A nodes. All the A nodes now have a B child. See what happens if you clone B. See what happens if you insert, delete or move nodes that are children of A. Verify that when you delete the penultimate clone, the last clone becomes a regular node again.
Clones are much more than a cute feature. Clones allow multiple views of data to exist within a single outline. With Leo, there is no such thing as a single, “correct” view of data. You can have as many views of data as you like.
To create a new view of the data in your outline, just do the following:
For example, when I fix a bug in Leo, I create an ordinary node to represent the bug. This bug node is my view of all the data in Leo’s source code that relates to the bug. As I discover code related to the bug, I clone their nodes and move them under the bug node. I’ll also add ordinary nodes as children of the bug node. These nodes contain the original bug report, descriptions of how I fixed the bug, test data, or any other notes I might want to keep.
Once I have created the bug node, I concentrate only on that node and its children. I can examine the bug node and its children without having to jump around the outline. Everything I need is in one place. When I get around to actually fixing the bug I can do so by changing the clones. Again, I do not have to jump around the outline. It doesn’t matter how big or complex the entire outline is: I am only dealing with the bug node and its children. This extremely narrow focus makes it much easier to fix bugs.
By the way, I never have to remember to save external files. When I change any clone, Leo marks all instances of that clone throughout the entire outline as dirty (changed). When I save the Leo outline, Leo automatically writes all the external files that contain dirty nodes.
Views have an unlimited number of uses. Use them whenever you want to focus your attention on some smaller set of nodes. For example, I often create view nodes when studying other people’s code. The view node helps me concentrate on just the part of the code that interests me at the moment.
Leo directives control such things as syntax coloring, line wrapping within the body pane and the width of tabs. Leo directives may appear in headlines or body text. Leo directives start with ‘@’ in the leftmost column, followed by the name of the directive. The following directives are useful for non-programmers:
@language python
@tabwidth -4
@wrap
@nowrap
@color
@nocolor
@killcolor
@color, @nocolor and @killcolor control syntax coloring.
You can mix @nocolor and @color directives in a single node, but these directives apply to descendant nodes only if they are unambiguous, that is, only if the ancestor node contains exactly one @color or @nocolor directive.
@language sets the language used for syntax coloring.
@tabwidth sets the width of tabs.
Negative tab widths cause Leo to convert tabs to spaces and are highly recommended for Python programming.
@wrap and @nowrap enable or disable line wrapping the Leo’s body pane.
The previous sections have discussed the basics of Leo. The rest of this tutorial discusses topics related to programming and scripting.
running Python scripts inside Leo.
We call these scripts Leo scripts to emphasize that these scripts have full and easy access to all parts of Leo’s source code and all parts of the outline containing the scripts.
Scripting is one of Leo’s biggest strengths. Simple Python scripts can do a lot.
Because Leo is written entirely in
The following sections tell how to create external files that contain computer programs. Yes, you could create program files using the @all directive, but the following section explain how you can take advantage of power-user features designed specifically for computer programmers. Even if you don’t read manuals, please read the following short Quick start for programmers section.
@thin trees (parts of the outline whose headline starts with @thin) create external files containing your program. Within @thin trees you can write functional pseudo-code, like this:
<< imports >> (in body text)
This is a reference to a section called << imports >>. When writing a external file, Leo replaces all section references by their definition. You define sections with section definition nodes. A section definition node is a node whose headline starts with a section name:
<< imports >> (in a headline)
The body text of this node is its definition. For example:
import leo.core.leoGlobals as g
import sys
As you can see, section definitions can be fragments of code; they don’t have to be complete functions or methods.
Notes:
Section definition nodes must be descendants of the node containing the section reference. Leo’s syntax colorer underlines undefined section references.
Section definitions may contain references to other sections.
The @others directive is a special kind of section reference. Leo replaces the @others directive by the body text of all descendant nodes except section definition nodes. That’s how @others got its name. For example, the root node of Python external files typically is something like this:
<< docstring >>
<< imports >>
@others
The external file will contain the docstring, followed by the imports, followed by the the body text of all other nodes in the @file tree, in outline order.
A external file may contain multiple @others directives: Each @others directive expands to the body text of all descendant nodes, excluding any nodes (and their descendants) that contain other @others directives. In practice, using @others is easy.
You may precede section references (including the @others directive) with whitespace. When expanding the section references, Leo inserts the preceding whitespace before every expanded line. For example, the following will work properly in Python:
if path:
<< create or recreate temp file as needed >>
You now know enough to understand Leo’s source code. Hurray! The following sections discuss some relatively minor details. However, I recommend reading `Good style and bad`_; you might save yourself some extra work.
@auto trees allow you to edit external files that do not contain sentinels. Leo imports such external files every time Leo reads the .leo file.
This section covers all the details of programming with Leo that programmers new to Leo are likely to need. Chapter 4: Writing Programs in Leo is the full reference guide. I recommend avoiding that chapter until you have been programming with Leo for some time.
A section name has the form:
<< any text >>
Any text is just that: any sequence of text not containing ‘>>’. For example:
<< initialize ivars >>
Leo ignores case and whitespace in section names, so the following are all equivalent:
<< Peanut Butter & Jelly >>
<< peanut butter&jelly >>
<<peanut butter & jelly>>
<<peanutbutter&jelly>>
<<PEANUTBUTTER&JELLY>>
When << and >> are not paired on a line, they are treated as ordinary << and >> characters. Leo has no escape mechanism for section names. That is, paired << and >> characters on the same line always denote a section name, even within comments and strings. This means that << and >> characters that do not delimit a section name must be placed on separate lines. In practice, this requirement seldom causes problems.
The syntax of section names is based on Norman Ramsey’s noweb markup language, but without noweb’s escape conventions. Eliminating these escape conventions may seem odd, but it has turned out to be one of the best design decisions I ever made.
Doc parts are blocks of text that Leo treats as comments. Leo syntax colors doc parts as comments, and Leo converts doc parts into comments in external files. Doc parts start with an @ directive and continue until an @c directive or the end of the body text. For example:
@ This is a comment in a doc part.
Doc parts can span multiple lines.
The next line ends the doc part
@c
Doc parts are entirely optional; you could simply use comments in the language specified by the @language directive. Using doc parts for lengthy comments is convenient, however. Not only do you not need to specify comment delimiters, but Leo breaks doc parts into lines automatically. The @pagewidth directive specifies the width of those lines.
Notes:
In body text, everything not in a doc part is in a code part. If a node does not contain a doc part, the entire body text is a code part.
@doc is a synonym for @ and @code is a synonym for @c. However, @ and @c are preferred.
A doc part of the form:
@ %def identifiers
declares that the preceding code part contains the list of identifiers. Whitespace separate the identifiers; everything else is taken to be the identifiers. This construct is a convention of the noweb language, and will be of use only for those who want to create .nw output files for use with the official noweb system.
The following directives are commonly used by Leo programmers. See Chapter 4: Writing Programs in Leo for full details.
Important: Leo treats lines starting with @ as a normal code line unless the @ starts a Leo directive. In particular, Leo will output Python decorators correctly, provided the name of the decorator is not a Leo directive.
An orphan node is a descendant of an @thin node that will not be copied to the external file. Orphan nodes can arise because an @thin tree has no @others or @all directives. Sections that are defined but not used also create orphan nodes. Leo issues a warning when attempting to write an @thin tree containing orphan nodes, and does not save the external file. Instead Leo saves the information in the @thin tree in the .leo file. No information is lost; Leo will load the @thin tree from the .leo file the next time Leo opens the .leo file.
When writing external files, Leo stores information about the outline structure in special comments called sentinel lines. Sentinel lines are comment lines with ‘@’ following the comment delimiter. For example, here are some actual sentinel line for the external file containing Python code:
#@+leo-ver=4-thin
#@+node:ekr.20031218072017.2794:@thin leoColor.py
#@@language python
#@@tabwidth -4
#@@pagewidth 80
#@-node:ekr.20031218072017.2794:@thin leoColor.py
#@-leo
You must not change sentinel lines when editing a external file in another editor! Doing so will corrupt the external file and make it impossible for Leo to read it normally. If you do accidentally alter a sentinel line, don’t panic! Leo’s Import external file command can recover information from corrupted external files.
The main difference between @file trees, @thin trees (and other kinds of trees that create external files) is the kind of sentinel lines that Leo writes:
Chapter 4: Writing Programs in Leo discusses the various ways of creating external files. This is a highly complex subject: you should ignore these details at first. Just use @thin to create your external files.
Leo can support a style of programming similar to Literate Programming (LP). LP has a bad reputation in some quarters. That’s too bad; Leo fixes all the problems with traditional LP. See Chapter 6: Leo and Literate Programming in Leo’s Users Guide for more details. Please don’t let the words ‘Literate Programming’ get in the way of your using Leo effectively. That would be your mistake, and a big one.
The following paragraphs discuss what I call good Leo style, which means how you choose to organize your data, programs and scripts as outlines. These choices simply don’t exist with other editors, and the choices you make will influence how easy it is to work with your data. We say an organization is Leonine if it uses Leo effectively and naturally.
Newcomers to Leo often have questions about how to use Leo’s outline-oriented markup. The following paragraphs answer those questions and present a straightforward, easy-to-use style of organizing your scripts and programs. I developed this style within an hour of using the first prototype of Leo, and it has remained mostly unchanged ever since. You may want to modify this style to suit your particular needs. By all means, do so. With just a bit of experimentation, you should be able to your own Leonine style.
Newcomers to Leo frequently ask when to use the @others directive and when to use sections. It is good style to use section references only when the order of text within a external file matters. For example, Python programmers put docstrings and imports at the start of files. So the body text of @file nodes typically look something like this:
<< docstring >>
@language python
@tabwidth -4
<< imports >>
@others
This ensures that the docstring is first in the file, followed by imports, followed by everything else. Note that the order in which functions are defined in a file, or methods defined within a class, typically does not matter. Thus, it is good style to define classes like this:
class myClass:
<< class attributes >>
@others
It would be bad style to define a class like this:
class myClass:
<< class attributes >>
<< method 1 >>
<< method 2 >>
...
Not only does this over-specify the order in which methods are defined, but it requires lots of extra typing. Not only must you add a line for each method, but headlines must contain section names such as << method 1 >>, <<method 2>>, etc. When using @others it is good style simply to put the name of each method in the headline.
A few more words about style:
It is good style to put each class, function or method in its own node. This makes it easy to see the shape of your code.
It is good style to use organizer nodes to group related functions or methods. An organizer node has no content except maybe for comments. Like this:
+ myClass
+ birth and death
+ __init__
etc.
+ getters
etc.
+ setters
etc.
+ misc methods
etc.
(In this notation, ‘+’ denotes a headline.) This organization is far superior to using hideous comments like:
###########
# Getters #
###########
It is bad style to use @others in organizer nodes. There is no need to do so.
It is bad style to use @others when order does matter. The reason is that it is very easy to move nodes in a tree by mistake, say by alphabetizing nodes. One wants to make the meaning of a external file immune from such movements.
One last word about style. The world won’t end if you happen to use bad style by mistake: you just might cause a bit more work for yourself than was strictly necessary. Feel free to invent your own style of using Leo. Still, it would be wise to “know the rules before you break them.”
Leo is fully scriptable using the Python language. Leo can execute any body text as a Python script. To run the entire body text as a script, simply choose the node and execute the Execute Script command (Ctrl+B). If text is selected, the Execute Script command will run just the selected text as the script.
The Execute Script command preprocesses the script before executing it. Leo preprocesses scripts in exactly the same way that Leo writes external files. That is, Leo expands section references and processes @others directives before executing the script. This allows you to use all of Leo’s normal capabilities to organize your scripts. Note: test.leo contains dozens of examples of using Leo outline structure to organize stand-alone scripts.
Your Python scripts can easily access data in an outline. For example, the following script will print all the headlines in an outline:
for p in c.all_positions():
print ' '*p.level(),p.h
Your scripts can use outline structure to avoid having to parse data. With a little forethought you can arrange outlines to make scripts easier to write. The example above is only the beginning of what scripts can do. See Chapter 7: Scripting Leo with Python for a complete discussion of scripting.
Plugins are Python modules that change how Leo works, yet are not part of Leo’s core code. Leo’s user have contributed dozens of plugins that have extended Leo’s capabilities in many new directions. The file leoPlugins.leo contains all plugins that are included in Leo distributions.
Plugins and other parts of Leo can get options from @settings trees, outlines whose headline is @settings. When opening a .leo file, Leo looks for @settings trees in the outline being opened and also in various leoSettings.leo files. @settings trees allow plugins to get options without any further support from Leo’s core code. For a full discussion of @settings trees, see Chapter 8: Customizing Leo.
LeoPyRef.leo (in the core subdirectory of the leo folder) contains almost all of Leo’s source code. It provides hundreds of examples of everything discussed here. This file will repay close study. For full details on all aspects of Leo see LeoDocs.leo or Leo’s Users Guide.