Leo in 10 Minutes¶
This chapter introduces Leo’s most important features and terminology.
Here is a screenshot of Leo’s main window:
Leo’s main window consists of an icon area just below the menus, an outline pane at the top left, a log pane at the top right, a body pane at the bottom left, and an optional viewrendered pane at the bottom right. The minibuffer and status line lie at the bottom of the main window.
The log pane contains several tabs. The Log tab shows messages from Leo, the Find Tab shows the status of Leo’s Find/Replace commands. Other tabs may also appear in the log pane: The Spell Tab controls Leo’s spell-checking. The Completion Tab shows available typing completions.
Leo stores all data in nodes. Nodes have headlines, shown in the outline pane, and body text. The body pane shows the body text of the presently selected node, the node whose headline is selected in the outline pane. Headlines have an icon box indicating a nodes status. For example, the icon box has a black border when the node has been changed.
Leo is a full-featured outliner, with commands to insert, delete, move, hoist, promote and demote nodes.
Clones are a unique feature of Leo. Any outline node may be cloned. Cloned nodes are actually the same node, but they appear in different places in the outline. Changes to any clone affect all other clones of that node, including their descendants. For example, suppose the A` nodes are clones of each other:
- A` - B - C - D - A` - B - C
Moving C right gives this outline:
- A` - B - C - D - A` - B - C
Clones allow you to create multiple views of data within a single outline. For example, Leo’s clone-find commands create clones of all found nodes, moving the newly-created clones so they are all children of an organizer node describing the search. The organizer node is a new view of the outline’s data, one focused on the found nodes!
Leo directives control Leo’s operations. Directives start with
@ in the leftmost column of body text. Directives apply to descendants until overridden in descendant nodes.
The @color, nocolor and nocolor-node directives control syntax coloring. Note: Nodes containing multiple color directives do not affect coloring of descendant nodes:
@color @nocolor @nocolor-node
The @language directive tells which language is in effect:
@language python @language c @language rest # restructured text @language plain # plain text: no syntax coloring.
The @pagewidth directive set page width (used when formatting paragraphs). The @tabwidth directive controls tabbing. Negative tab widths (recommended for Python) convert tabs to spaces:
@pagewidth 100 @tabwidth -4 @tabwidth 8
The @wrap and @nowrap enable or disable line wrapping in the body pane:
The @first directive ensures that lines appear at the very start of an external file. See the next section. Multiple @first directives are allowed, and these directives must be the very first lines of body text:
@first # -*- coding: utf-8 -*- @first #! /usr/bin/env python
Leo has many other directives, described in the directives reference page.
An @file node is a node whose headline starts with @file followed by a path to an external file. @file trees represent external files on your file system. Leo updates @file nodes when you change external files outside of Leo. When saving an outline, Leo writes all changed @file trees to their external files:
@file leoNodes.py @file ../../notes.txt
Leo’s markup tells Leo how to create external files from @file trees. Markup may appear in any body text, and must appear in the body of the @file node itself.
There are two kinds of markup: section references (<< this is my section >>) and the @others directive. Section references refer to named nodes, nodes whose headlines look like a section reference. @others refers to all other (unnamed) nodes. Here is the body text of a typical @file node for a python file:
@first # -*- coding: utf-8 -*- '''whatever.py''' << imports >> @others # That's all, folks @language python @tabwidth
Child nodes must define the << import >> node and the methods of the Controller class.
When writing this file, Leo writes the first two lines:
@first # -*- coding: utf-8 -*- '''whatever.py'''
followed by the body text of the << imports>> node, followed by the body text of all other nodes, in outline order, followed by the comment # That’s all, folks.
When writing file trees, Leo writes sentinel comments into external files. These comments represent outline structure. When writing an @file tree to a .leo file, Leo writes only the root @file node. To avoid sentinels, use @clean instead of @file:
@clean leoNodes.py @clean ../../notes.txt
There is a small cost to @clean: Leo writes the entire @clean tree to the .leo file.
Leo uses outlines for just about everything, including configuring Leo:
- leo/config/leoSettings.leo contains Leo’s default global settings. Don’t change this file unless you are one of Leo’s developers.
- ~/myLeoSettings.leo contains your personal settings. Leo will not create this file automatically: you should create it yourself. Settings in myLeoSettings.leo override (or add to) the default settings in leoSettings.leo.
- Any other .leo file may also contain local settings. Local settings apply only to that file and override all other settings.
Settings nodes specify settings. These nodes must be descendants of an @settings node. Moving a settings node out from the @settings tree disables the setting. Headlines start with @ followed by a type, and possibly a value. Here are some examples, with body text shown indented from headlines:
For more information, see Leo’s configuration guide.
Leo plugins are Python programs that extend what Leo can do. Plugins reside in the leo/plugins folder. @enabled-plugins settings node enable plugins. Leo has dozens of plugins, including:
- bookmarks.py manages and shows bookmarks.
- contextmenu.py shows a context menu when you right-click a headline.
- mod_scripting.py supports @button and @command nodes.
- quicksearch.py Adds Nav tab for searching.
- todo.py provides to-do list and simple project-management capabilities.
- valuespace.py adds outline-oriented spreadsheet capabilities.
- viewrendered.py creates the rendering pane and renders content in it.
Non-programmers: feel free to skip this part.
Leo’s markup applies to scripts as well as external files. Leo’s execute-script command composes the script from the selected node, using Leo’s markup. For example: this body text defines the top-level part of a script:
'''My script''' << imports >> class Controller: # Child nodes define the methods of this class. @others Controller(c).run # c *is* defined.
The execute-script command pre-defines three names: c, g, and p. c is the commander of the outline in which the script executes. g is the
leo.core.leoGlobals module, containing dozens of useful functions and classes. p is the position of the presently selected node.
The Commander class defines both a scripting API and a DOM (Document Object Module) giving complete access to all data in an outline. For example:
''' Print all headlines of the outline, properly indented, with the number of characters in each node's body text. ''' # c.all_positions() is a python generator yielding all positions, in outline order. for p in c.all_positions(): print('%3s %s %s' % ( len(p.b), # p.b is p's body text. ' '*p.level(), # p.level() is p's indentation level. p.h, # p.h is p's headline. )
For more information, see Leo’s scripting tutorial.
@test nodes create unit tests. @test nodes automatically convert the body to a subclass of unittest.TestCase. Run these tests with one of Leo’s
<Alt-X>run<tab> gives the full list. Here one of Leo’s actual unit tests:
@test c.positionExists for all nodes # In the headline for p in c.all_positions(): assert c.positionExists(p)
Within @test nodes, c, g, and p are predefined as usual. In addition, self is the instance of unittest.TestCase created by the @test node. For example:
For more details, see Leo’s unit-testing reference.
Autocompletion reminds you of all members (functions, methods, ivars, etc.) contained in objects in Leo’s source code, and in Python’s standard library modules.
Alt-1 (toggle-autocompleter) enables and disables autocompletion. Note: Autocompletion can be enabled only when @language python is in effect.
For example, typing just “c.atF” (in the body pane, with autocompletion enabled) automatically inserts “c.atFileCommands” into the body pane, because “c.atFileCommands” is the only possible completion of “c.atF”.
As another example, typing “at.writeA” will show (in an autocompleter tab in the Log pane) all of the write commands in leoAtFile.py:
writeAll:method writeAllHelper:method writeAtAutoNodes:method writeAtAutoNodesHelper:method writeAtShadowNodes:method writeAtShadowNodesHelper:method
When a single completion is shown, typing ‘?’ will show the docstring for a method. For example, “c.atFileCommands.write?” shows:
Write a 4.x derived file. root is the position of an @<file> node
Calltips show the expected arguments to functions and methods.
Alt-2 (toggle-calltips) enables and disables calltips.
( shows calltips, when @language python is in effect.
Ctrl-G (keyboard-quit) exits calltips. Calltips work for any Python function or method, including Python’s global functions. Examples:
g.toUnicode( g.toUnicode(s, encoding, reportErrors=False c.widgetWantsFocusNow( c.widgetWantsFocusNow(w reduce( reduce(function, sequence[, initial]) -> value
Leo is a full-featured outliner with the following special features:
- Directives control how Leo works.
- @file and @clean nodes create external files.
- myLeoSettings.leo specifies your personal settings.
- Plugins extend Leo. @enabled-plugins settings nodes enable plugins.
- Leo has an easy-to-use scripting API, giving full access to all data in the outline.
- @button and @command nodes define scripts that can be applied to other nodes.
- @test nodes create unit tests.
- Alt-1 enables autocompletion.