plugins Package

plugins Package

FileActions Module

Defines actions taken when double-clicking on @<file> nodes and supports @file-ref nodes.

The double-click-icon-box command on any kind of @<file> node writes out the file if changes have been made since the last save, and then runs a script on it, which is retrieved from the outline.

Scripts are located in a node whose headline is FileActions. This node can be anywhere in the outline. If there is more than one such node, the first one in outline order is used.

The children of that node are expected to contain a file pattern in the headline and the script to be executed in the body. The file name is matched against the patterns (which are Unix-style shell patterns), and the first matching node is selected. If the filename is a path, only the last item is matched.

Execution of the scripts is similar to the “Execute Script” command in Leo. The main difference is that the namespace in which the scripts are run contains these elements:

  • ‘c’ and ‘g’ and ‘p’: as in the regular execute script command.
  • ‘filename’: the filename from the @file directive.
  • ‘shellScriptInWindow’, a utility function that runs a shell script in an
    external windows, thus permitting programs to be called that require user interaction

File actions are implemented for all kinds @<file> nodes. There is also a new node type @file-ref for referring to files purely for the purpose of file actions, Leo does not do anything with or to such files.

leo.plugins.FileActions.applyFileAction(p, filename, c)[source]
leo.plugins.FileActions.doFileAction(filename, c)[source]

Return True if the plugin has loaded successfully.

leo.plugins.FileActions.onIconDoubleClick(tag, keywords)[source]
leo.plugins.FileActions.shellScriptInWindow(c, script)[source]

active_path Module

Synchronizes @path nodes with folders.

If a node is named ‘@path <path_to_folder>’, the content (file and folder names) of the folder and the children of that node will synchronized whenever you double-click the node.

For files not previously seen in a folder a new node will appear on top of the children list (with a mark).

Folders appear in the list as /foldername/. If you double click on the folder node, it will have children added to it based on the contents of the folder on disk. These folders have the @path’ directive as the first line of their body text.

When files are deleted from the folder and the list is updated by double clicking the files will appear in the list as filename (or /foldername/).

You can describe files and directories in the body of the nodes.

You can organize files and directories with organizer nodes, an organizer node name cannot contain with ‘/’.

Files and folders can be created by entering a node with the required name as its headline (must start and/or end with “/” for a folder) and then double clicking on the node.

@auto nodes can be set up for existing files can be loaded by double clicking on the node. If you prefer @shadow or something else use the “active_path_attype” setting, without the “@”.

There are commands on the Plugins active_path submenu:

  • show path - show the current path
  • set absolute path - changes a node “/dirname/” to “@path /absolute/path/to/dirname”.
  • purge vanished (recursive) - remove entries
  • update recursive - recursive load of directories, use with caution on large file systems
  • pick dir - select a folder interactively to make a new top level @path node
  • mark-content - mark outline content in the @path tree, as opposed to filesystem content. Useful if you want to delete the @path tree to check for content not on the filesystem first

If you want to use an input other than double clicking a node set active_path_event to a value like ‘hypercclick1’ or ‘headrclick1’.

There are @settings for ignoring directory entries and automatically loading files. is used, rather than re.match, so patterns need only match part of the filename, not the whole filename.

The body of the @setting @data active_path_ignore is a list of regex patterns, one per line. Directory entries matching any pattern in the list will be ignored. The names of directories used for matching will have forward slashes around them (‘/dirname/’), so patterns can use this to distinguish between directories and files.

The body of the @setting @data active_path_autoload is a list of regex patterns, one per line. File entries matching any pattern in the list will be loaded automatically. This works only with files, not directories (but you can load directories recursively anyway).

Autoloading can be toggled with active-path-toggle-autoload, autoloading defaults to initially on unless @bool active-path-do-autoload = False.

Set @bool active_path_load_docstring = True to have active_path load the docstring of .py files automatically. These nodes start with the special string:


which must be left intact if you want active path to be able to double-click load the file later.

@float active_path_timeout_seconds (default 10.) controls the maximum time active_path will spend on a recursive operation.

@int active_path_max_size (default 1000000) controls the maximum size file active_path will open without query.

Per Folder file/folder inclusion and exclusion by adding flags to the body of an active path folder (either @ or /*/), can include multiple inc= and exc= flags:

  • excdirs - excludes all directories
  • excfiles - excludes all files
  • inc= - a single item or comma separated list of strings to include in the list of files/folders
  • exc= - a single item or comma separated list of strings to exclude in the list of files/folders
  • re - search using regular expressions (otherwise a case-sensitive ‘in’ comparison)

active_path is a rewrite of the at_directory plugin to use @path directives (which influence @auto and other @file type directives), and to handle sub-folders more automatically.

leo.plugins.active_path.active_path_act_on_node(event, p=None)

act_on_node handler for

leo.plugins.active_path.attachToCommander(t, k)[source]
leo.plugins.active_path.checkIncExc(item, inc, exc, regEx)[source]

Primary logic to check if an item is in either the include or exclude list

leo.plugins.active_path.cmd_ActOnNode(event, p=None)[source]

act_on_node handler for


Recursive update, with expansions.


cmd_MarkContent - mark nodes in @path sub-tree with non-filesystem content

i.e. not organizer nodes (no body), subdirs (body starts with @path) vanished file placeholders, or @<file> nodes.


cmd_PickDir - Show user a folder picker to create


Remove files never loaded, i.e. no kind of @file node.


Remove files never loaded, i.e. no kind of @file node.


Remove files no longer present, i.e. “filename” entries.


Remove files no longer present, i.e. “filename” entries.

leo.plugins.active_path.cmd_SetNodeToAbsolutePath(event, p=None)[source]

Change “/dirname/” to “@path /absolute/path/to/dirname”.


Change “/dirname/” to “@path /absolute/path/to/dirname”, recursively


Just show the path to the current file/directory node in the log pane.


cmd_ToggleAutoLoad - toggle autoloading behavior


Recursive update, no new expansions.

leo.plugins.active_path.createDir(c, parent, d)[source]

Ask if we should create a new folder

leo.plugins.active_path.createFile(c, parent, d)[source]

Ask if we should create a new file

leo.plugins.active_path.deleteChildren(p, cond, dtor=None)[source]
leo.plugins.active_path.deleteDescendents(p, cond, dtor=None, descendAnyway=False, _culls=0)[source]

Children of p, some of which may be in organizer nodes

In the following example nodeA’s children are nodes B, F, and G:

leo.plugins.active_path.getPath(c, p)[source]
leo.plugins.active_path.inAny(item, group, regEx=False)[source]

Helper function to check if word from list is in a string

leo.plugins.active_path.inReList(txt, lst)[source]

Return True if the plugin has loaded successfully.


really isEligibleToBecomeAFileNode

leo.plugins.active_path.onSelect(tag, keywords)[source]

Determine if a file or directory node was clicked, and the path

leo.plugins.active_path.openDir(c, parent, d)[source]

Expand / refresh an existing folder

Note: With the addition of per folder inclusion/exclusion a check is done against both the current list of nodes and against the files/folders as they exist on the system. This check must be done in both places to keep the node list in sync with the file system while respecting the inc/exc lists - John Lunzer

leo.plugins.active_path.openFile(c, parent, d, autoload=False)[source]

Open an existing file

leo.plugins.active_path.popup_entry(c, p, menu)[source]

Populate the Path submenu of the popup.

leo.plugins.active_path.query(c, s)[source]

Return yes/no answer from user for question s


Recursive descent.

leo.plugins.active_path.subDir(d, p)[source]
leo.plugins.active_path.sync_node_to_folder(c, parent, d, updateOnly=False, recurse=False)[source]

Decide whether we’re opening or creating a file or a folder

add_directives Module

Allows users to define new @direcives.

leo.plugins.add_directives.addPluginDirectives(tag, keywords)[source]

Add all new directives to g.globalDirectiveList


Return True if the plugin has loaded successfully.

leo.plugins.add_directives.scanPluginDirectives(tag, keywords)[source]

Add a tuple (d,v,s,k) to list for every directive d found

at_folder Module

Synchronizes @folder nodes with folders.

If a node is named ‘@folder <path_to_folder>’, the content (filenames) of the folder and the children of that node will be sync. Whenever a new file is put there, a new node will appear on top of the children list (with mark). So that I can put my description (annotation) as the content of that node. In this way, I can find any files much easier from leo.

Moreover, I add another feature to allow you to group files(in leo) into children of another group. This will help when there are many files in that folder. You can logically group it in leo (or even clone it to many groups), while keep every files in a flat/single directory on your computer.


Return True if the plugin has loaded successfully.

leo.plugins.at_folder.onSelect(tag, keywords)[source]
leo.plugins.at_folder.sync_node_to_folder(c, parent, d)[source]

at_produce Module

Executes commands in nodes whose body text starts with @produce.

WARNING: trying to execute a non-existent command will hang Leo.

To use, put in the body text of a node:

@produce echo hi

This plugin creates two new commands: at-produce-all and at-produce-selected.

at-produce-all scans the entire tree for body text containing @produce. at-produce-selected just scans the selected tree.

Whatever follows @produce is executed as a command.

@produce commands are executed in the order they are found, that is, in outline order.

The at-produce commands produce a log node as the last top-level node of the outline. Any output, including error messages, should be there.

This plugin is not intended as a replacement for make or Ant, but as a simple substitute when that machinery is overkill.

leo.plugins.at_produce.addMenu(tag, keywords)[source]

Produce two new entries at the end of the Outlines menu.

leo.plugins.at_produce.getList(c, all)[source]

Return a list of all @produce lines in body texts in an outline. all = True: scan c’s entire outline. all = False: scan c.p and its descendants.


Return True if the plugin has loaded successfully.

leo.plugins.at_produce.produce_selected_f(event)[source], all)[source]

Run all @produce nodes in a separate thread. Report progress via a timer in this thread.

leo.plugins.at_produce.runList(c, aList)[source]

Run all commands in aList (in a separate thread). Do not change Leo’s outline in this thread!

leo.plugins.at_produce.timer_callback_helper(c, t, timer)[source]

All drawing must be done in the main thread.

at_view Module

attrib_edit Module

baseNativeTree Module

bibtex Module

Creates a BibTex file from an @bibtex <filename>’ tree.

Nodes of the form ‘@<x> key’ create entries in the file.

When the user creates a new node (presses enter in headline text) the plugin automatically inserts a template for the entry in the body pane.

The ‘templates’ dict in the << globals >> section defines the template. The default, the template creates all required entries.

Double-clicking the @bibtex node writes the file. For example, the following outline:

-@bibtex biblio.bib
 +@book key,
  author = {A. Uthor},
  year = 1999

creates the following ‘biblio.bib’ file:

author = {A. Uthor},
year= 1999}
@string nodes define strings and may contain multiple entries. The plugin writes

all @string nodes at the start of the file. For example, the following outline:

-@bibtext biblio.bib
  j1 = {Journal1}
 +@article AUj1
  author = {A. Uthor},
  journal = j1
  j2 = {Journal2}
  j3 = {Journal3}

creates the following file:

@string{j1 = {Journal1}}
@string{j2 = {Journal2}}
@string{j3 = {Journal3}}

author = {A. Uthor},
journal = j1}

Headlines that do not start with ‘@’ are organizer nodes: the plugin does not write organizer nodes, but does write descendant nodes.

BibTeX files can be imported by creating an empty node with @bibtex filename’ in the headline. Double-clicking it will read the file and parse it into a @bibtex tree. No syntax checks are made: the file is expected to be a valid BibTeX file.


Return True if the plugin has loaded successfully.

leo.plugins.bibtex.onHeadKey(tag, keywords)[source]

Write template for the entry in body pane.

If body pane is empty, get template for the entry from a dictionary ‘templates ‘ and write it in the body pane.

20141127 - note headkey2 now only fires on Enter, no need to check which key brought us here.

leo.plugins.bibtex.onIconDoubleClick(tag, keywords)[source]

Read or write a bibtex file when the node is double-clicked.

Write the @bibtex tree as bibtex file when the root node is double-clicked. If it has no child nodes, read bibtex file.

leo.plugins.bibtex.readBibTexFileIntoTree(c, fn, p)[source]

Import a BibTeX file into a @bibtex tree.

leo.plugins.bibtex.writeTreeAsBibTex(c, fn, root)[source]

Write root’s subtree to bibFile.

bigdash Module

bookmarks Module

bzr_qcommands Module

Adds a context menu to each node containing all the commands in the bzr Qt interface. Bzr is invoked based on the path of the current node.


leo.plugins.bzr_qcommands.bzr_qcommands(c, p, menu)[source]

see module docs.


Return True if the plugin has loaded successfully.

chapter_hoist Module

codewisecompleter Module

colorize_headlines Module

Manipulates appearance of individual tree widget items. (Qt only).

This plugin is mostly an example of how to change the appearance of headlines. As such, it does a relatively mundane chore of highlighting @thin, @auto, @shadow nodes in bold.

leo.plugins.colorize_headlines.colorize_headlines_visitor(c, p, item)[source]

Changes @thin, @auto, @shadow to bold


Return True if the plugin has loaded successfully.

contextmenu Module

ctagscompleter Module

cursesGui Module

datenodes Module

Allows users to insert headlines containing dates.

‘Date nodes’ are nodes that have dates in their headlines. They may be added to the outline one at a time, a month’s-worth at a time, or a year’s-worth at a time. The format of the labels (headlines) is configurable.

There are options to omit Saturdays and Sundays.

An ‘Insert Date Nodes …’ submenu will be created (by default) in the ‘Outline’ menu. This menu can be suppressed by using either of the following settings:

  • @bool suppress-datenodes-menus
  • @bool suppress-all-plugins-menus

The following commands are available for use via the minibuffer or in @menu/@popup settings.

  • datenodes-today
  • datenodes-this-month
  • datenodes-this-year
class leo.plugins.datenodes.DateNodes(c)[source]

Bases: object

Main DateNodes class

boolean_settings = ['datenodes_month_node_omit_saturdays', 'datenodes_month_node_omit_sundays', 'datenodes_year_node_omit_saturdays', 'datenodes_year_node_omit_sundays']
default_settings = {'datenodes_body_text': 'To do...', 'datenodes_day_node_headline': '%Y-%m-%d', 'datenodes_month_node_day_headline': '%d: %A', 'datenodes_month_node_month_headline': '%B %Y', 'datenodes_month_node_omit_saturdays': True, 'datenodes_month_node_omit_sundays': True, 'datenodes_year_node_day_headline': '%d: %A', 'datenodes_year_node_month_headline': '%B', 'datenodes_year_node_omit_saturdays': True, 'datenodes_year_node_omit_sundays': True, 'datenodes_year_node_year_headline': '%Y'}

Return True if the plugin has loaded successfully.

leo.plugins.datenodes.on_create(tag, keywords)[source]

debugger_pudb Module

Makes g.pdb() enter the Pudb debugger instead of pdb.

Pudb is a full-screen Python debugger:


Return True if the plugin has loaded successfully.

dragdropgoodies Module

dtest Module

Sends code to the doctest module and reports the result.

When the Dtest plugin is enabled, the dtest command is active. Typing:

Alt-X dtest

will run doctest on a file consisting of the current node and it’s children. If text is selected only the selection is tested.

From Wikipedia:

'Doctest' is a module included in the Python programming language's
standard library that allows for easy generation of tests based on
output from the standard Python interpreter. - doctest page - Jim Fulton’s presentation:

Literate Testing:
Automated Testing with doctest
class leo.plugins.dtest.DT(tag, keywords)[source]

Bases: leo.core.leoPlugins.BaseLeoPlugin

Sends code to the doctest module and reports the result If text is selected, tests only the selection.

>>> print("hello world")
hello world
>>>'hello world')
>>> print(c.p.h)
>>> import notfound
Traceback (most recent call last):
ImportError: No module named notfound

The handler for dtest


Return True if the plugin has loaded successfully.

dump_globals Module

Dumps Python globals at startup.


Return True if the plugin has loaded successfully.

leo.plugins.dump_globals.onStart(tag, keywords)[source]

empty_leo_file Module

Allows Leo to open any empty file as a minimal .leo file.


Return True if the plugin has loaded successfully.

leo.plugins.empty_leo_file.onOpen(tag, keywords)[source]

enable_gc Module

Enables debugging and tracing for Python’s garbage collector.


Return True if the plugin has loaded successfully.

leo.plugins.enable_gc.onStart(tag, keywords)[source]

expfolder Module

Adds @expfolder nodes that represent folders in the file system.

The double-click-icon-box command on an @expfolder node reads the files in the directory at the path specified and creates child nodes for each file in the subfolder. Subdirectories are made into child @expfolder nodes so the tree can be easily traversed. If files have extensions specified in the expfolder.ini file they are made into @text nodes so the content of the files can be easily loaded into leo and edited. Double clicking a second time will delete all child nodes and refresh the directory listing. If there are any changed @text nodes contained inside you will be prompted about saving them.

The textextensions field on the expfolder Properties page contains a list of extensions which will be made into @text nodes, separated by spaces.

For the @text and @expfolder nodes to interact correctly, the textnode plugin must load before the expfolder plugin. This can be set using the Plugin Manager’s Plugin Load Order pane.


Return True if the plugin has loaded successfully.

leo.plugins.expfolder.on_icondclick(tag, keywords)[source]

free_layout Module

ftp Module

geotag Module

Tags nodes with latitude and longitude.

class leo.plugins.geotag.geotag_Controller(c)[source]

Bases: object

A per-commander class that manages geotagging.

static getAttr(p)[source]

Return True if the plugin has loaded successfully.

leo.plugins.geotag.onCreate(tag, key)[source]
leo.plugins.geotag.onQuit(tag, key)[source]

gitarchive Module

Store snapshots of outline in git.

leo.plugins.gitarchive.contfile(c, p)[source]

Return True if the plugin has loaded successfully.

graphcanvas Module

gtkDialogs Module

gtkGui Module

import_cisco_config Module

Allows the user to import Cisco configuration files.

Adds the “File:Import:Import Cisco Configuration” menu item. The plugin will:

  1. Create a new node, under the current node, where the configuration will be written. This node will typically have references to several sections (see below).
  2. Create sections (child nodes) for the indented blocks present in the original config file. These child nodes will have sub-nodes grouping similar blocks (e.g. there will be an ‘interface’ child node, with as many sub-nodes as there are real interfaces in the configuration file).
  3. Create sections for the custom keywords specified in the customBlocks[] list in importCiscoConfig(). You can modify this list to specify different keywords. DO NOT put keywords that are followed by indented blocks (these are taken care of by point 2 above). The negated form of the keywords (for example, if the keyword is ‘service’, the negated form is ‘no service’) is also included in the sections.
  4. Not display consecutive empty comment lines (lines with only a ‘!’).

All created sections are alphabetically ordered.

leo.plugins.import_cisco_config.create_import_cisco_menu(tag, keywords)[source]

Return True if the plugin has loaded successfully.

initinclass Module

Modifies the Python @auto importer so that the importer puts the __init__ method (ctor) into the body of the class node.

This makes it easier to keep the instance variable docs in the class docstring in sync. with the ivars as manipulated by __init__, saves repeating explanations in both places.

Note that this is done after the consistency checks by the @auto import code, so using this plugin is at your own risk. It will change the order of declarations if other methods are declared before __init__.

leo.plugins.initinclass.InitInClass(tag, keywords)[source]

Move __init__ into the class node body in python @auto imports


Return True if the plugin has loaded successfully.

interact Module

internal_ipkernel Module

ipython Module

ironPythonGui Module

jinjarender Module

Render @jinja nodes.

  • sudo apt-get install python-jinja2

Create headline like this:

@jinja ~/foo.txt

Select the node and do alt-x act-on-node

Conceptually, acts like @nosent - tree is parsed, template is expanded and content is written to the file.

Requires “valuespace” plugin. Fetches vars from valuespace.

class leo.plugins.jinjarender.JinjaCl(c)[source]

Bases: object


Return True if the plugin has loaded successfully.

leo.plugins.jinjarender.jinja_act_on_node(c, p, event)[source]
leo.plugins.jinjarender.jinja_render(template, fname, d)[source]
leo.plugins.jinjarender.untangle(c, p)[source]

leoOPML Module

A plugin to read and write Leo outlines in .opml ( format.

The OPML plugin creates two new commands that read and write Leo outlines in OPML format. The read-opml-file command creates a Leo outline from an .opml file. The write-opml-file command writes the present Leo outline to an .opml file.

Various settings control what gets written to .opml files, and in what format. As usual, you specify settings for the OPML plugin using leoSettings.leo. The settings for the OPML are found in the node: @settings–>Plugins–>opml plugin.

Here are the settings that control the format of .opml files. The default values are shown.

  • @string opml_namespace = leo:com:leo-opml-version-1

The namespace urn for the xmlns attribute of <opml> elements. This value typically is not used, but it should refer to Leo in some way.

  • @bool opml_use_outline_elements = True
  • If True, Leo writes body text to <leo:body> elements nested in <outline> elements. Otherwise, Leo writes body text to leo:body attributes of <outline> elements.
  • @string opml_version = 2.0

The opml version string written to the <OPML> element. Use 2.0 unless there is a specific reason to use 1.0.

  • @bool opml_write_body_text = True

Leo writes body text to the OPML file only if this is True.

  • @bool opml_write_leo_details = True

If True, Leo writes the native attributes of Leo’s <v> elements as attributes of the opml <outline> elements.

The native attributes of <v> elements are a, t, vtag (new), tnodeList, marks, expanded and descendentTnodeUnknownAttributes.

  • @bool opml_write_leo_globals_attributes = True

If True, Leo writes body_outline_ratio` and global_window_position attributes to the <head> element of the .opml file.

  • @bool opml_write_ua_attributes

If True, write unknownAttributes NOTE: ua_attributes are not currently read from opml.

  • @bool opml_expand_ua_dictionary

If True, expand an unknownAttriubte ‘x’ of type dict to ‘ua_x_key0’, ‘ua_x_key1’ etc. WARNING: using this feature may prevent reading these ua_attributes from opml, if that feature is implemented in the future.

  • @bool opml_skip_ua_dictionary_blanks

If True, when expanding as above, skip blank dict entries.

class leo.plugins.leoOPML.NodeClass[source]

Bases: object

A class representing one outline element.

Use getters to access the attributes, properties and rules of this mode.

class leo.plugins.leoOPML.OpmlController(c)[source]

Bases: object

The controller class for this plugin.


Clean control characters from s. s may be a bytes or a (unicode) string.

createChildren(c, node, parent_v)[source]

Create c.tnodesDict by from self.generated_gnxs by converting VNode entries to tnodes.

createVnode(c, node, v=None)[source]
createVnodes(c, dummyRoot)[source]

Important: this method and its helpers are low-level code corresponding to link/unlink methods in Modify this with extreme care.

dumpTree(root, dummy=True)[source]
handleVnodeAttributes(node, v)[source]

Write the c.p as OPML, using the owner’s put method.


Read the opml file.


Open a Leo window containing the contents of an .opml file.


Write fileName as an OPML file.


Save a Leo outline to an OPMLfile.

class leo.plugins.leoOPML.PutToOPML(owner)[source]

Bases: object

Write c.p’s tree as OPML, using the owner’s put method.


Init all configuration settings.


Put the selected outline as OPML. All elements and attributes prefixed by ‘leo:’ are leo-specific. All other elements and attributes are specified by the OPML 1 spec.


Put the OPML header, including attributes for globals, prefs and find settings.


Put the properly encoded <?xml> element.


Put the tnodeList attribute of p.v


write unknownAttributes with various levels of expansion

class leo.plugins.leoOPML.SaxContentHandler(c, inputFileName)[source]

Bases: xml.sax.saxutils.XMLGenerator

A sax content handler class that reads OPML files.


Convert the attributes to a list of g.Bunches. attrs: an Attributes item passed to startElement.

attrsToString(attrs, sep='\n')[source]

Convert the attributes to a string.

attrs: an Attributes item passed to startElement.

sep: the separator charater between attributes.


End a <leo:body> element.

endElementNS(name, qname)[source]
printStartElement(name, attrs)[source]
processingInstruction(target, data)[source]

Start a <leo:body> element.

startElement(name, attrs)[source]
startElementNS(name, qname, attrs)[source]

Return True if the plugin has loaded successfully.

leo.plugins.leoOPML.onCreate(tag, keys)[source]

leo_interface Module

Allows the user to browse XML documents in Leo.

This plugin implements an interface to XML generation, so that the resulting file can be processed by leo.

class leo_file represents the whole leo file. class leo_node has a headline and body text.

See the end of this file for a minimal example on how to use these classes.

If you encounter the first of a set of clones, create a leo_node. If you encounter the same set of clones later, create a leo_clone node and refer back to the first element.

class leo.plugins.leo_interface.LeoNode[source]

Bases: object

Abstrace class for generating xml.

mark(file, marker, func, newline=True)[source]
mark_with_attributes(file, marker, attribute_list, func, newline=True)[source]
mark_with_attributes_short(file, marker, attribute_list)[source]

Return True if the plugin has loaded successfully.

class leo.plugins.leo_interface.leo_clone(orig)[source]

Bases: leo.plugins.leo_interface.node_with_parent

Class representing a clone.

The (only) data of a clone is the reference to a leo_node.

When you encounter the first clone of a set of clones, generate a leo_node. The second clone should then reference this leo_node, and contain no other data.

Since clones are indistinguishable, there is really not much to do in this class.

class leo.plugins.leo_interface.leo_file[source]

Bases: leo.plugins.leo_interface.LeoNode

Leo specific class representing a file.

class leo.plugins.leo_interface.leo_node(headline='', body='')[source]

Bases: leo.plugins.leo_interface.LeoNode, leo.plugins.leo_interface.node_with_parent

Leo specific class representing a node.

These nodes correspond to tnodes in LEO. They have a headline and a body.

They also represent the (only) vnode in an outline without clones.

count = 0
class leo.plugins.leo_interface.node_with_parent[source]

Bases: object


leo_pdf Module

This NOT a Leo plugin: this is a docutils writer for .pdf files.

That file uses the reportlab module to convert html markup to pdf.

The original code written by Engelbert Gruber.

Rewritten by Edward K. Ream for the Leo rst3 plugin.

class leo.plugins.leo_pdf.Bunch(**keywords)[source]

Bases: object

A class that represents a colection of things.

Especially useful for representing a collection of related variables.

get(key, theDefault=None)[source]
class leo.plugins.leo_pdf.PDFTranslator(writer, doctree)[source]

Bases: docutils.nodes.NodeVisitor

createParagraph(text, style='Normal', bulletText=None)[source]

Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.

dumpNode(node, tag='')[source]

Encode special characters in text & return.


Create and b.setLink for visit/depart_label.


Return the most recent bunch having the indicated kind, or None.


Invisible nodes should be ignored.


Duplicate the munging done (somewhere in docutils) of section names.

This allows us to use the nameids attribute in the document element.

putHead(start, style='Normal', bulletText=None)[source]
putTail(start, style='Normal', bulletText=None)[source]
starttag(node, tagname, suffix='\n', caller='', **attributes)[source]
visit_admonition(node, name)[source]
visit_docinfo_item(node, name)[source]

Generate code for a footnote reference.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.


Invisible nodes should be ignored.

class leo.plugins.leo_pdf.Writer[source]

Bases: docutils.writers.Writer

createParagraphsFromIntermediateFile(s, story, visitor)[source]
output = None
settings_spec = ('PDF-Specific Options', None, (('Specify a stylesheet URL, used verbatim. Overrides --stylesheet-path. Either --stylesheet or --stylesheet-path must be specified.', ['--stylesheet'], {'overrides': 'stylesheet_path', 'metavar': '<URL>'}), ('Specify a stylesheet file, relative to the current working directory. The path is adjusted relative to the output HTML file. Overrides --stylesheet.', ['--stylesheet-path'], {'overrides': 'stylesheet', 'metavar': '<file>'}), ('Format for footnote references: one of "superscript" or "brackets". Default is "brackets".', ['--footnote-references'], {'default': 'brackets', 'metavar': '<FORMAT>', 'choices': ['superscript', 'brackets']})))
supported = ('pdf', 'rlpdf')

Do final translation of self.document into self.output.


alias of leo.plugins.leo_pdf.Bunch

class leo.plugins.leo_pdf.dummyPDFTranslator(writer, doctree, contents)[source]

Bases: docutils.nodes.NodeVisitor


Synthesize calls to reportlab.platypus.para.Paragraph from an intermediate file.


Encode special characters in text & return.

putParaFromIntermediateFile(lines, style)[source]

Returns a stylesheet object


A wrapper for changing docutils get_language method.


This file may be distributed in Leo’s plugin folder, but this file is NOT a Leo plugin!

The init method returns False to tell Leo’s plugin manager and unit tests to skip this file.

leo_to_html Module

Converts a leo outline to an html web page.

This plugin takes an outline stored in Leo and converts it to html which is then either saved in a file or shown in a browser. It is based on the original leoToHTML 1.0 plugin by Dan Rahmel which had bullet list code by Mike Crowe.

The outline can be represented as a bullet list, a numbered list or using html <h?> type headings. Optionally, the body text may be included in the output.

If desired, only the current node will be included in the output rather than the entire outline.

An xhtml header may be included in the output, in which case the code will be valid XHTML 1.0 Strict.

The plugin is fully scriptable as all its functionality is available through a Leo_to_HTML object which can be imported and used in scripts.

Menu items and @settings

If this plugin loads properly, the following menu items should appear in your File > Export… menu in Leo:

Save Outline as HTML  (equivalent to export-html)
Save Node as HTML     (equivalent to export-html-node)
Show Outline as HTML  (equivalent to show-html)
Show Node as HTML     (equivalent to show-html-node)

Unless the following appears in an @setting tree:

@bool leo_to_html_no_menus = True

in which case the menus will not be created. This is so that the user can use @menu and @item to decide which commands will appear in the menu and where.


Several commands will also be made available

will export to a file according to current settings.
will export to a file using bullet type ‘*’ which can be number, bullet or head.

The following commands will start a browser showing the html.

will show the outline according to current settings.
will show the outline using bullet type ‘*’ which can be number, bullet or head.

The following commands are the same as above except only the current node is converted:




As of Mar. 2014 regular Leo @string settings starting with leo_to_html_ are checked first, before the .ini file. E.g. @string leo_to_html_flagjustheadlines = No has the same effect as flagjustheadlines = No in the .ini, and takes precedence.

There are several settings that can appear in the leo_to_html.ini properties file in leo’s plugins folder or be set via the Plugins > leo_to_html > Properties… menu. These are:

The path to the folder where you want to store the generated html file. Default: c:\
Default: ‘Yes’ to include only headlines in the output.
Default: ‘Yes’ to ignore @file nodes.
Yes to include xhtml doctype declarations and make the file valid XHTML 1.0 Strict. Otherwise only a simple <html> tag is used although the output will be xhtml compliant otherwise. Default: Yes

If this is ‘bullet’ then the output will be in the form of a bulleted list. If this is ‘number’ then the output will be in the form of a numbered list. If this is ‘heading’ then the output will use <h?> style headers.

Anything else will result in <h?> type tags being used where ‘?’ will be a digit starting at 1 and increasing up to a maximum of six depending on depth of nesting. Default: number


Set this to the command needed to launch a browser on your system or leave it blank to use your systems default browser.

If this is an empty string or the browser can not be launched using this command then python’s webbrowser module will be tried. Using a bad command here will slow down the launch of the default browser, better to leave it blank. Default: empty string


At present, the file leo/plugins/leo_to_html.ini contains configuration settings. In particular, the default export path, “c:” must be changed for *nix systems.

class leo.plugins.leo_to_html.Leo_to_HTML(c=None)[source]

Bases: object

This class provides all the functionality of the leo_to_html plugin.

See the docstring for the leo_to_html module for details.

announce(msg, prefix=None, color=None, silent=None)[source]

Print a message if flags allow.

announce_end(msg='done', prefix=None, color=None)[source]
announce_fail(msg='failed', prefix=None, color=None)[source]
announce_start(msg='running ...', prefix=None, color=None)[source]

Fit self.xhtml and self.title into an (x)html template.

Plaace the result in self.xhtml.

The template string in self.template should have too %s place holders. The first for the title the second for the body.

doBodyElement(pp, level=None)[source]

Append wrapped body string to output stream.

doHeadline(p, level=None)[source]

Append wrapped headstring to output stream.


” Recursivley proccess an outline node into an xhtml list.

doItemHeadlineTags(p, level=1)[source]

” Recursivley proccess an outline node into an xhtml list.


Convert the tree to xhtml.

Return the result as a string in self.xhtml.

Only the code to represent the tree is generated, not the wraper code to turn it into a file.


Returns a string containing a template for the outline page.

The string should have positions in order, for:
title and body text.

Returns a string containing a template for the outline page.

The string should have positions in order, for:
title and body text.

Load configuration from a .ini file.

main(bullet=None, show=False, node=False)[source]

Generate the html and write the files.

If ‘bullet’ is not recognized then the value of bullet_type from the the properties file will be used.

If ‘show’ is True then the file will be saved to a temp dir and shown in a browser.


Set various parameters.


Convert the outline to xhtml and display the results in a browser.

If browser_command is set, this command will be used to launch the browser. If it is not set, or if the command fails, the default browser will be used. Setting browser_command to a bad command will slow down browser launch.


Return True if subtree should be shown.

subtree should be shown if it is not an @file node or if it is an @file node and flags say it should be shown.

write(name, data, basedir=None, path=None)[source]

Write a single file.

The name can be a file name or a ralative path which will be added to basedir and path to create a full path for the file to be written.

If basedir is None self.basedir will be used and if path is none self.path will be used.


Write all the files


Join the arguments and convert to an absolute file path.

leo.plugins.leo_to_html.createExportMenus(tag, keywords)[source]

Create menu items in File -> Export menu.

Menu’s will not be created if the following appears in an @setting tree:

@bool leo_to_html_no_menus = True

This is so that the user can use @menu to decide which commands will appear in the menu and where.


Return True if the plugin has loaded successfully.

leo.plugins.leo_to_html.onCreate(tag, keys)[source]

Handle ‘after-create-leo-frame’ hooks by creating a plugin controller for the commander issuing the hook.

class leo.plugins.leo_to_html.pluginController(c)[source]

Bases: object

A per commander plugin controller to create and handle minibuffer commands that control the plugins functions.

export_html(event=None, bullet=None, show=False, node=False)[source]

Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.

export_html_node(event=None, bullet=None)[source]

Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.

show_html(event=None, bullet=None)[source]

Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.

show_html_node(event=None, bullet=None)[source]

Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.


Command handler for leo_to_html. See modules docstring for details.[source]

Convert special characters to html entities.

leo_to_rtf Module

Outputs a Leo outline as a numbered list to an RTF file. The RTF file can be loaded into Microsoft Word and formatted as a proper outline.

This plug-in loads installs an “Outline to Microsoft RTF” menu item in your File > Export… menu in Leo.

Settings such as outputting just the headlines (vs. headlines & body text) and whether to include or ignore the contents of @file nodes are stored in the rtf_export.ini file in your Leoplugins folder.

The default export path is also stored in the INI file. By default, it’s set to c:so you may need to modify it depending on your system.

leo.plugins.leo_to_rtf.createExportMenu(tag, keywords)[source]

Return True if the plugin has loaded successfully.

leocursor Module

Creates a LeoCursor object that can walk around a Leo outline and decode attributes from nodes.

Node names can be used through . (dot) notation so cursor.Data.Name._B for example returns the body text of the Name node which is a child of the Data node which is a child of the cursors current location.

See …/plugins/examples/leocursorexample.leo for application.

class leo.plugins.leocursor.AM_CapColon[source]

Bases: leo.plugins.leocursor.AM_Colon

Like AM_Colon, but first letter must be capital.

pattern = '^([A-Z][A-Za-z0-9_]*:)(\\s+(\\S.*))*$'
class leo.plugins.leocursor.AM_Colon[source]

Bases: leo.plugins.leocursor.AttribManager

Attributes are in the body text as:

start-of-line letter letters-or-numbers colon space(s) attribute-value




foo: all this is the value

are attributes (first one is value==’‘), but:


is not (because there’s no space after the colon).


Return the body string without any parts used to store attributes, if this flavor of attribute manager stores attributes in the body. If not, just return the whole body string.

getAttrib(v, what)[source]

Get an attribute value from a vnode

has_key(v, what)[source]

Get list of attribute keys from a vnode

pattern = <_sre.SRE_Pattern object>
class leo.plugins.leocursor.AttribManager[source]

Bases: object

Class responsible for reading / writing attributes from vnodes for LeoCursor

exception NotPresent[source]

Bases: exceptions.Exception


Return the body string without any parts used to store attributes, if this flavor of attribute manager stores attributes in the body. If not, just return the whole body string.

getAttrib(v, what)[source]

Get an attribute value from a vnode


Get list of attribute keys from a vnode

class leo.plugins.leocursor.LeoCursor(v, other=None)[source]

Bases: object

See module docs.

exception NotPresent[source]

Bases: exceptions.Exception

leofeeds Module

Read feeds from rss / atom / whatever sources

Usage: Create node with a headline like:

(or somesuch).

Do alt-x act-on-node on that node to populate the subtree from the feed data. Requires “feedparser” python module

class leo.plugins.leofeeds.MLStripper[source]

Bases: HTMLParser.HTMLParser

leo.plugins.leofeeds.emit(r, h, b)[source]
leo.plugins.leofeeds.emitfeed(url, p)[source]
leo.plugins.leofeeds.feeds_act_on_node(c, p, event)[source]
leo.plugins.leofeeds.onCreate(tag, keys)[source]

leofts Module

leomail Module

Sync local mailbox files over to Leo.

Creates mail-refresh command, which can only be applied to @mbox nodes of the form:

@mbox <path to .mbox file>

The command parses the .mbox file and creates a separate node for each thread.

Replies to the original messages become children of that message.

class leo.plugins.leomail.MLStripper[source]

Bases: HTMLParser.HTMLParser

leo.plugins.leomail.emit_message(c, parent, root, message)[source]

Create all the children of p.


leomylyn Module

Provides an experience like Mylyn: for Leo.

It “scores” the nodes based on how interesting they probably are for you, allowing you to focus on your “working set”.

Scoring is based on how much you edit the nodes.

class leo.plugins.leomylyn.MylynController[source]

Bases: object

add_score(v, points)[source]
children_hnd(tag, kw)[source]
content_hnd(tag, kw)[source]

Return True if the plugin has loaded successfully.

leoremote Module

leoscreen Module

lineNumbers Module

Adds #line directives in perl and perlpod programs.

Over-rides two methods in to write #line directives after node sentinels. This allows compilers to give locations of errors in relation to the node name rather than the filename. Currently supports only perl and perlpod.


Return True if the plugin has loaded successfully.

livecode Module

macros Module

Creates new nodes containing parameterized section reference.

This plugin adds nodes under the currently selected tree that are to act as section references. To do so, go the Outline menu and select the ‘Parameterize Section Reference’ command. This plugin looks for a top level node called ‘Parameterized Nodes’. If it finds a headline that matches the section reference it adds a node/nodes to the current tree.

To see this in action, do the following:

  1. Important: in the examples below, type << instead of < < and type >> instead of > >. Docstrings can not contain section references!

  2. Create a node called ‘Parameterized Nodes’, with a sub-node called < < Meow >>. The body of < < Meow > > should have the text:

    I mmmm sooo happy I could  < < 1$  > >.
    But I don't know if I have all the  < < 2$  > >
    money in the world.
  3. In a node called A, type:

    < < meow( purrrrrr, zzooot )  > >
    (leave the cursor at the end of the line)
  4. In a node called B, type:

     < < meow ( spit or puke, blinkin  )  > >
    (leave the cursor at the end of the line)
  5. Leave the cursor in Node A at the designated point.

  6. Go to Outline and select Parameterize Section Reference.

The plugin searches the outline, goes to level one and finds a Node with the Headline, “Parameterized Nodes”. It looks for nodes under that headline with the the headline << meow >>. It then creates this node structure under Node A:

< < meow ( purrrrrr, zzooot ) > >
    < <2$> >
    < <1$> >
  1. Examine the new subnodes of Node A:

    < < meow ( purrrrrr, zzooot ) > >

    contains the body text of the < < meow > > node.

    < < 1$ > > contains the word purrrrrr. < < 2$ > > contains the word zzooot.

  2. Go to Node B, and leave the cursor at the designated point.

Go to Outline Menu and select Parameterize Section Reference command.

  1. Examine the new subnodes of Node B.

It’s a lot easier to use than to explain!

class leo.plugins.macros.ParamClass(c)[source]

Bases: object


Add a submenu in the outline menu.


Find the parameterized nodes in p’s parents..


Return True if this plugin loaded correctly.

leo.plugins.macros.onCreate(tag, keywords)[source]

Create the per-commander instance of ParamClass.

maximizeNewWindows Module

Maximizes all new windows.


Return True if the plugin has loaded successfully.

leo.plugins.maximizeNewWindows.maximize_window(tag, keywords)[source]

mime Module

Opens files with their default platform program.

The double-click-icon-box command on @mime nodes will attempt to open the named file as if opened from a file manager. @path parent nodes are used to find the full filename path. For example:

@mime foodir/document.pdf

The string setting ‘mime_open_cmd’ allows specifying a program to handle opening files:

    @string mime_open_cmd = see
    .. or ..
    @string mime_open_cmd = see %s

Where ‘%s’ is replaced with the full pathname.

Note: This plugin terminates handling of the ‘icondclick1’ event by returning True. If another plugin using this event (e.g. is also enabled, the order in @enabled-plugins matters. For example: if is enabled before, double-clicking on an @mime node will both open the body text in [g]vim AND call the mime_open_cmd.

Use @url for opening either URLs or Uniform Node Locators in “*.leo” files and use @mime nodes for opening files on the local file system. It also replaces the plugin, where here the headline must start with @mime to activate this plugin.

For other sys.platform’s, add an elif case to the section “guess file association handler” and either define a default _mime_open_cmd string, where “%s” will be replaced with the filename, or define a function taking the filename string as its only argument and set as open_func.


Accept a command string including filename and return a function which executes the command.


Accept a command string and return a function which opens executes the command, replacing %s with the full file path.


Return True if the plugin has loaded successfully.

leo.plugins.mime.open_mimetype(tag, keywords, val=None)[source]

Simulate double-clicking on the filename in a file manager. Order of preference is:

  1. @string mime_open_cmd setting
  2. _mime_open_cmd, defined per sys.platform detection
  3. open_func(fpath), defined per sys.platform detection
  4. mailcap file for mimetype handling

mnplugins Module

mnplugins shows how to : define new Commands “insertOK” + “insertUser” create Usermenu with new Commands

new Commands: insertOK:

insert ‘OK’ in headline and a stamp in the first body line are there child nodes without ‘OK’ verhindern OK in actual node. The right-click-icon command also inserts ‘OK’.
insertUser : Shift-F6
insert a <user/date/time> stamp at the current location in body text
leo.plugins.mnplugins.create_UserMenu(tag, keywords)[source]

Return True if the plugin has loaded successfully.

leo.plugins.mnplugins.insertBodystamp(c, v)[source]
leo.plugins.mnplugins.insertOKcmd(self, event=None)[source]
leo.plugins.mnplugins.insertUser(self, event=None)[source]

Handle the Insert User command.

leo.plugins.mnplugins.onRclick(tag, keywords)[source]

Handle right click in body pane.

leo.plugins.mnplugins.onStart(tag, keywords)[source]
leo.plugins.mnplugins.setHeadOK(c, v)[source]

mod_autosave Module

mod_framesize Module

Sets a hardcoded frame size.

Prevents Leo from setting custom frame size (e.g. from an external .leo document)


Return True if the plugin has loaded successfully.

leo.plugins.mod_framesize.setTopGeometry_mod_framesize(self, *args)[source]

Monkeypatced version of setTopGeometry

mod_http Module

An http plug-in for LEO, based on

Adapted and extended from the Python Cookbook:

This plug-in has three distinct behaviors:

Install this plug-in is as follows:

Start Leo with the plug-in enabled. You will see a purple message that says something like:

"http serving enabled at"


@bool http_active = True
required for plug-in to be active
@string http_ip =
address to bind to, see notes below
@int  http_port = 8130
port to use (1 3 0 ~= L E O)
@bool http_allow_remote_exec = False
must be changed to True for remote code execution
@string rst_http_attributename = 'rst_http_attribute'
link to obsolete rst3 plugin
@data user_bookmark_stylesheet
Additional .css for bookmarks.
@data http_stylesheet
The default .css for this page.
@data user_http_stylesheet
Additional .css for this page.

Note: The html generated by the server contains both stylesheets as inline <style> elements, with the user_http_stylesheet contents last.

@data mod_http script
The body text of this @data setting contains all the javascript used in the page.

Note The html generated by the server handles the <script> elements:

<script src="">
<script>..the contents of @data mod_http_script..

Browsing Leo files

Start a web browser, and enter the following URL: http://localhost:8130/

You will see a a “top” level page containing one link for every open .leo file. Start clicking :-)

You can use the browser’s refresh button to update the top-level view in the browser after you have opened or closed files.

Note: IP address is accessible by all users logged into your local machine. That means while Leo and mod_http is running anyone logged into your machine will be able to browse all your leo outlines and add bookmarks.

Note: If you want all other network accessible machines to have access to your mod_http instance, then use @string http_ip =

Note: the browser_encoding constant (defined in the top node of this file) must match the character encoding used in the browser. If it does not, non-ascii characters will look strange.

Saving bookmarks from browser to Leo

To do this, add a bookmark to the browser with the following URL / Location:

javascript:w=window; d=w.document; ln=[];if(w.location.href.indexOf('one-tab')>-1){el=d.querySelectorAll('a');for (i in el){ln.push({url:el[i].href,txt:el[i].innerHTML});};};'http://localhost:8130/_/add/bkmk/?&name=' + escape(d.title) + '&selection=' + escape(window.getSelection()) + '&ln=' + escape(JSON.stringify(ln)) + '&url=' + escape(w.location.href),"_blank","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=800, height=300, status=no");void(0); # NOQA

and edit the port (8130 in the example above) to match the port you’re using for mod_http.

Bookmarks are created as the first node in the outline which has been opened longest. You can set the @string http_bookmark_unl to specify an alternative location, e.g.:

@string http_bookmark_unl = /home/tbrown/.bookmarks.leo#@bookmarks-->Incoming

to place them in the Incoming node in the @bookmarks node in the .bookmarks.leo outline.

The headline is preceded with @urlunless the bookmarks plug-in is loaded. If the bookmarks plug-in is loaded the bookmark will have to be moved to a @bookmarks tree to be useful.

Note: there is special support for Chrome’s OneTab extension as a mechanism for saving all tabs open. Click the OneTab button to get a list of tabs, then click the “Share all as web page” link to show the list on Bookmark as usual as described above. You can then delete the shared list with the “Delete this shared page” button. The Leo node created will have a child node for each of the listed tabs.

The browser may or may not be able to close the bookmark form window for you, depending on settings - set dom.allow_scripts_to_close_windows to true in about:config in Firefox.

Executing code remotely


Allowing remote code execution is a HUGE SECURITY HOLE, you need to be sure that the url from which you access Leo (typically http://localhost:8130/) is accessible only by people and software you trust.

Remote execution is turned off by default, you need to manually / locally change the @setting @bool http_allow_remote_exec = False to True to enable it.

Commands to be executed are submitted via HTTP GET requests, which can be generated in almost any language and also triggered from shortcuts, links in other documents or applications, etc. etc.

The basic form is:

http://localhost:8130/_/exec/?cmd=<python code for Leo to execute>

The query parameters are:

cmd (required)
A valid python snippet for Leo to execute. Executed by the eval command in the mod_scripting plug-in. Can be specified multiple times, each is executed in order. May contain newlines, see examples.
c (optional)
Which currently loaded outline to use, can be an integer, starting from zero, or the full path+filename, or just the base filename. Defaults to 0 (zero), i.e. the “first” open outline.
enc (optional)
Encoding for response, ‘str’, ‘repr’, or ‘json’. Used to render the returned value.
mime_type (optional)
Defaults to text/plain. Could be useful to use text/html etc.

A special variant url is:


which returns a list of open outlines.


This command:

curl http://localhost:8130/_/exec/?cmd='c.bringToFront()' >/dev/null

will raise the Leo window, or at least make the window manager signal the need to raise it.

curl --get --data-urlencode       cmd='g.handleUrl("file:///home/tbrown/.leo/.contacts.leo#Contacts", c)'       http://localhost:8130/_/exec/ >/dev/null

will cause a running Leo instance to open /some/path/contacts.leo and select the Contacts node. A desktop icon link, browser bookmark, or link in a spread-sheet or other document could be used the same way.

In the bash shell language, this code:

curl --silent --show-error --get --data-urlencode cmd="
    nd = c.rootPosition().insertAfter()
    nd.h = 'TODO: $TEXT'
    import time
    nd.b = '# created %s' % time.asctime()
    'To do item created

could be written in a file called td, and then, assuming that file is executable and on the shell’s path, entering:

td remember to vacuum the cat

on the command line would create a node at the top of the first open outline in Leo with a headline TODO: remember to vacuum the cat and a body text # created Wed Jul 29 16:42:26 2015. The command vs-eval returns the value of the last expression in a block, so the trailing 'To do item created ' gives better feedback than None generated by c.redraw(). c.selectPosition(nd) is important ant to stop Leo getting confused about which node is selected.

class leo.plugins.mod_http.ExecHandler(request_handler)[source]

Bases: object

Quasi-RPC GET based interface


Return the file like ‘f’ that leo_interface.send_head makes

class leo.plugins.mod_http.LeoActions(request_handler)[source]

Bases: object

A place to collect other URL based actions like saving bookmarks from the browser. Conceptually this stuff could go in class leo_interface but putting it here for separation for now.


Return the file like ‘f’ that leo_interface.send_head makes

add_bookmark_selection(node, text)[source]

Insert the selected text into the bookmark node, after any earlier selections but before the users comments.

Tags: tags, are here

Full title of the page

Collected: timestamp

“”” The first saved selection “”“

“”” The second saved selection “”“

Users comments

i.e. just above the “Users comments” line.

get_one_tab(links, nd)[source]

get_one_tab - Add child bookmarks from OneTab chrome extension

  • links: list of {‘txt’:, ‘url’:} dicts
  • nd: node under which to put child nodes

Return the file like ‘f’ that leo_interface.send_head makes

class leo.plugins.mod_http.RequestHandler(conn, addr, server)[source]

Bases: leo.plugins.mod_http.leo_interface, asynchat.async_chat, SimpleHTTPServer.SimpleHTTPRequestHandler


Collects the data arriving on the connexion

copyfile(source, outputfile)[source]

Copy all data between two file objects.

The SOURCE argument is a file object open for reading (or anything with a read() method) and the DESTINATION argument is a file object open for writing (or anything with a write() method).

The only reason for overriding this would be to change the block size or perhaps to replace newlines by CRLF – note however that this the default server uses this to copy binary data as well.


Begins serving a GET request


Begins serving a POST request. The request data must be readable on a file-like object called self.rfile


Reset terminator (required after POST method), then close


Class to override


Called when a POST request body has been read


Over-ride SimpleHTTPRequestHandler.handle_read_event.


Called when the http request line and headers have been received

log_message(format, *args)[source]

Log an arbitrary message.

This is used by all other logging functions. Override it if you have specific logging wishes.

The first argument, FORMAT, is a format string for the message to be logged. If the format string contains any % escapes requiring parameters, they should be specified as subsequent arguments (it’s just like printf!).

The client host and current date/time are prefixed to every message.


Prepare to read the request body


Returns the QUERY dictionary, similar to the result of cgi.parse_qs except that : - if the key ends with [], returns the value (a Python list) - if not, returns a string, empty if the list is empty, or with the first value in the list

class leo.plugins.mod_http.Server(ip, port, handler)[source]

Bases: asyncore.dispatcher

Copied from http_server in medusa

class leo.plugins.mod_http.config[source]

Bases: object

http_active = False
http_ip = ''
http_port = 8130
http_timeout = 0
rst2_http_attributename = 'rst_http_attribute'
class leo.plugins.mod_http.delayedSocketStream(sock)[source]

Bases: asyncore.dispatcher_with_send


Called when the user opens a new file.


Return the given @data node.


read config.


Return True if the plugin has loaded successfully.

class leo.plugins.mod_http.leo_interface[source]

Bases: object

Given a node ‘node’, add links to:
The next sibling, if any. the next node. the parent. The children, if any.
create_href(href, text, f)[source]
create_leo_h_reference(window, node)[source]
create_leo_reference(window, node, text, f)[source]

Create a reference to ‘node’ in ‘window’, displaying ‘text’

given a path of the form:

[<short filename>,<number1>,<number2>…<numbern>] identify the leo node which is in that file, and, from top to bottom, is the <number1> child of the topmost node, the <number2> child of that node, and so on.

Return None if that node can not be identified that way.


Given a position p, return the name of the node.

This is called from leo.core.leoRst.


Common code for GET and HEAD commands.

This sends the response code and MIME headers.

Return value is either a file object (which has to be copied to the outputfile by the caller unless the command was HEAD, and must be closed by the caller under all circumstances), or None, in which case the caller has nothing further to do.


Split self.path.

write_body_pane(f, p)[source]
write_head(f, headString, window)[source]
write_leo_tree(f, window, root)[source]

Wriite the entire html file to f.

write_node_and_subtree(f, p)[source]
write_path(node, f)[source]
leo.plugins.mod_http.loop(timeout=5.0, use_poll=0, map=None)[source]

Override the loop function of asynchore. We poll only until there is not read or write request pending.

exception leo.plugins.mod_http.noLeoNodePath[source]

Bases: exceptions.Exception

Raised if the path can not be converted a filename and a series of numbers. Most likely a reference to a picture.

exception leo.plugins.mod_http.nodeNotFound[source]

Bases: exceptions.Exception


Use by the rst3 plugin.

leo.plugins.mod_http.onFileOpen(tag, keywords)[source]
leo.plugins.mod_http.plugin_wrapper(tag, keywords)[source]
leo.plugins.mod_http.reconstruct_html_from_attrs(attrs, how_much_to_ignore=0)[source]

Given an attribute, reconstruct the html for this node.

leo.plugins.mod_http.set_http_attribute(p, value)[source]

mod_leo2ascd Module

leo.plugins.mod_leo2ascd.CodeChunk(text, width=72)[source]

Split a line of text into a list of chunks not longer than width.

leo.plugins.mod_leo2ascd.CreateAscMenu(tag, keywords)[source]

Create the Outline to AsciiDoc menu item in the Export menu.

leo.plugins.mod_leo2ascd.GetAscFilename(c, p)[source]

Checks a node for a filename directive.

leo.plugins.mod_leo2ascd.SectionUnderline(h, level, v)[source]

Return a section underline string.


Writes @root directive and/or @ascfile directive to log pane.

leo.plugins.mod_leo2ascd.WriteNode(v, startinglevel, ascFile)[source]

Writes the contents of the node v to the ascFile.

leo.plugins.mod_leo2ascd.WriteTreeAsAsc(p, fn)[source]

Writes the tree under p to the file ascFile


Return True if the plugin has loaded successfully.

mod_read_dir_outline Module

Allows Leo to read a complete directory tree into a Leo outline. Converts directories into headlines and puts the list of file names into bodies.

Ce plug-in permet de traduire l’arborescence d’un répertoire en une arborescence Leo : Chaque dossier est converti en noeud dans Leo ; son nom est placé dans l’entête du noeud et chaque nom de fichier qu’il contient est listé dans son contenu.

Feedback on this plugin can be sent to:

Frédéric Momméja
<frederic [point] mommeja [at] laposte [point] net>
class leo.plugins.mod_read_dir_outline.controller(c)[source]

Bases: object

importDir(dir, compteurglobal)[source]

La routine récursive de lecture des fichiers


Return True if the plugin has loaded successfully.

leo.plugins.mod_read_dir_outline.onCreate(tag, keywords)[source]

mod_scripting Module

mod_speedups Module

Experimental speedups

Various optimizations. Use at your own risk.

If stuff breaks, disable this plugin before reporting bugs.


Return True if the plugin has loaded successfully.

leo.plugins.mod_speedups.os_path_expanduser_cached(path, encoding=None)[source]
leo.plugins.mod_speedups.os_path_finalize_cached(path, **keys)[source]
leo.plugins.mod_speedups.os_path_finalize_join_cached(*args, **keys)[source]
leo.plugins.mod_speedups.os_path_join_speedup(*args, **kw)[source]
leo.plugins.mod_speedups.speedup_toUnicodeFileEncoding(s, arg=None)[source]

mod_tempfname Module

mod_timestamp Module

Timestamps all save operations to show when they occur.


Return True if the plugin has loaded successfully.

leo.plugins.mod_timestamp.timestamp(tag=None, keywords=None)[source]

multifile Module

Allows Leo to write a file to multiple locations.

This plugin acts as a post-write mechanism, a file must be written to the file system for it to work. At this point it is not a replacement for @path or an absolute path, it works in tandem with them.

To use, place @multipath at the start of a line in the root node or an ancestor of the node. The format is (On Unix-like systems):

@multipath /machine/unit/:/machine/robot/:/machine/

New in version 0.6 of this plugin: the separator used above is ‘;’ not ‘:’, for example:

@multipath c:\prog\test;c:\prog\unittest

It will places copy of the written file in each of these directories.

There is an additional directive that simplifies common paths, it is called @multiprefix. By typing @multiprefix with a path following it, before a @multipath directive you set the beginning of the paths in the @multipath directive. For example:



#@multipath plugins: fungus : drain

copies a file to /leo/plugins /leo/fungus /leo/drain.

Note: I put # in front of the directives here because I don’t want someone browsing this file to accidentally save multiple copies of this file to their system :)

The @multiprefix stays in effect for the entire tree until reset with another @multiprefix directive. @multipath is cumulative, in that for each @multipath in an ancestor a copy of the file is created. These directives must at the beginning of the line and by themselves.

leo.plugins.multifile.addMenu(tag, keywords)[source]
leo.plugins.multifile.decoratedOpenFileForWriting(self, root, fileName, toString)[source]

Return True if the plugin has loaded successfully.


Return a dictionary whose keys are fileNames and whose values are lists of paths to which the fileName is to be written. New in version 0.6 of this plugin: use ‘;’ to separate paths in @multipath statements.

leo.plugins.multifile.stop(tag, keywords)[source]

nested_splitter Module

niceNosent Module

Ensures that all descendants of @file-nosent nodes end with exactly one newline, replaces all tabs with spaces, and adds a newline before class and functions in the derived file.


Return True if the plugin has loaded successfully.

leo.plugins.niceNosent.onPostSave(tag=None, keywords=None)[source]

After saving an @nosent file, replace all tabs with spaces.

leo.plugins.niceNosent.onPreSave(tag=None, keywords=None)[source]

Before saving an @nosent file, make sure that all nodes have a blank line at the end.

nodeActions Module

Allows the definition of double-click actions.

The double-click-icon-box command causes this plugin checks for a match of the clicked node’s headline text with a list of patterns. If a match occurs, the plugin executes the associated script.

nodeAction nodes may be located anywhere in the outline. Such nodes should contain one or more pattern nodes as children. The headline of each pattern node contains the pattern; the body text contains the script to be executed when the pattern matches the double-clicked node.

For example, the “nodeActions” node containing a “launch URL” pattern node and a “pre-process python code” node could be placed under an “@settings” node:

+- nodeActions
   +- http:\\*
   +- @file *.py


The nodeActions plugin supports the following global configurations using Leo’s support for setting global variables within an @settings node’s sub-nodes in the leoSettings.leo, myLeoSettings.leo, and the project Leo file:

@bool nodeActions_save_atFile_nodes = False

True:The double-click-icon-box command on an @file type node will save the file to disk before executing the script.
False:The double-click-icon-box command on an @file type node will not save the file to disk before executing the script. (default)

@int nodeActions_message_level = 1

Specifies the type of messages to be sent to the log pane. Specifying a higher message level will display that level and all lower levels. The following integer values are supported:

0 no messages
1 Plugin triggered and the patterns that were matched (default)
2 Double-click event passed or not to next plugin
3 Patterns that did not match
4 Code debugging messages


Pattern matching is performed using python’s support for Unix shell-style patterns unless overwritten by the “X” pattern directive. The following pattern elements are supported:

*           matches everything
?           matches any single character
[<seq>]     matches any character in <seq>
[!<seq>]    matches any character **not** in <seq>

Unix shell-style pattern matching is case insensitive and always starts from the beginning of the headline. For example:

Pattern Matches Does not match
.py .py - Test

To enable a script to run on any type of @file node (@thin, @shadow, …), the pattern can start with “@files” to match on any external file type. For example, the pattern “@files *.py” will match a node with the headline “@file”.

The double-click-icon-box command matches the headline of the node against the patterns starting from the first sub-node under the “nodeActions” node to the last sub-node.

Only the script associated with the first matching pattern is invoked unless overwritten by the “V” pattern directive.

Using the “V” pattern directive allows a broad pattern such as “@files *.py” to be invoked, and then, by placing a more restrictive pattern above it, such as “@files *”, a different script can be executed for those files requiring pre-processing:

+- nodeActions
   +- @files *
   +- @files *.py

Note: To prevent Leo from trying to save patterns that begin with a derived file directive (@file, @auto, …) to disk, such as “@file *.py”, place the “@ignore” directive in the body of the “nodeActions” node.

Pattern nodes can be placed at any level under the “nodeActions” node. Only nodes with no child nodes are considered pattern nodes. This allows patterns that are to be used in multiple Leo files to be read from a file. For example, the following structure reads the pattern definition from the “C:\Leo\nodeActions_Patterns.txt” file:

+- nodeActions
+- @files C:\\Leo\\nodeActions_Patterns.txt
    +- http:\\*
    +- @file *.py

Pattern directives

The following pattern specific directives can be appended to the end of a pattern (do not include the ‘:’):


Use python’s regular expression type patterns instead of the Unix shell-style pattern syntax.

For example, the following patterns will match the same headline string:

Unix shell-style pattern:
   @files *.py

Regular Expression pattern:
   ^@files .*\.py$ [X]

Matching the pattern will not block the double-click event from being passed to the remaining patterns. The “V” represents a down arrow that symbolizes the passing of the event to the next pattern below it.

For example, adding the “[V]” directive to the “@files *” in the Patterns section above, changes its script from being ‘an alternate to’ to being ‘a pre-processor for’ the “@files *.py” script:

+- nodeActions
   +- @files * [V]
   +- @files *.py

Matching the pattern will not block the double-click event from being passed to other plugins. The “>” represents a right arrow that symbolizes the passing of the event to the next plugin.

If the headline matched more than one headline, the double-click event will be passed to the next plugin if the directive is associated with any of the matched patterns.

The directive(s) for a pattern must be contained within a single set of brackets, separated from the pattern by a space, with or without a comma separator. For example, the following specifies all three directives:

^@files .*\.py$ [X,V>]


The script for a pattern is located in the body of the pattern’s node. The following global variables are available to the script:

pClicked - node position of the double-clicked node
pScript - node position of the invoked script


The double-click-icon-box command on a node with a “http:\” headline will invoke the script associated with the “http:\*” pattern. The following script in the body of the pattern’s node displays the URL in a browser:

import webbrowser
hClicked = pClicked.h     #Clicked node's Headline text #Invoke browser

The following script can be placed in the body of a pattern’s node to execute a command in the first line of the body of a double-clicked node:

g.os.system('"Start /b ' + pClicked.bodyString() + '"')
leo.plugins.nodeActions.applyNodeAction(pScript, pClicked, c)[source]
leo.plugins.nodeActions.doNodeAction(pClicked, c)[source]

Return True if the plugin has loaded successfully.

leo.plugins.nodeActions.onIconDoubleClickNA(tag, keywords)[source]
leo.plugins.nodeActions.shellScriptInWindowNA(c, script)[source]

nodediff Module

Provides commands to run text diffs on node bodies within Leo.

By Jacob M. Peck

Configuration Settings

This plugin is configured with the following @settings:

@string node-diff-style

One of ‘compare’, ‘ndiff’, or ‘unified_diff’. Chooses which diff output method difflib uses to provide the diff. Defaults to ‘compare’.

The various diff output methods are explained in the difflib documentation.


This plugin defines the following commands:


Runs a diff on the marked nodes. Only works if there are exactly two nodes marked in the current outline.


Runs a diff on the selected nodes. Only works if there are exactly two selected nodes in the current outline.


Runs a diff on the children of the currently selected node. Only works if the selected node has exactly two children.


Runs a diff on the current node and the same node in the .leo file on disk, i.e. changes in the node since last save. This does not work for derived @<files> (@auto, @edit, etc.), only nodes which are part of the Leo outline itself.


Runs a diff on the current node and the same node in the most recent commit of the .leo file to a VCS like git or bzr (currently only git and bzr supported), i.e. changes in the node since last commit. This does not work for derived @<files> (@auto, @edit, etc.), only nodes which are part of the Leo outline itself.

Common Usage

For those who don’t use marked nodes for much else, the ‘diff-marked’ option is probably the best. Mark two nodes and then execute ‘diff-marked’.

The ‘diff-subtree’ option is the second most common option, and makes a lot of sense for those who use clones regularly. Create an organizer node and clone your two nodes to be diffed under that organizer node, then select the organizer node and execute ‘diff-subtree’.

The ‘diff-selected’ option is for those who use the mouse. Using Ctrl+click or Shift+click, select exactly two nodes in the outline pane, and then execute ‘diff-selected’.

Scripting can be used by scripts to run any of the three styles of diff. The following are available to scripts, and all of them take a list of two positions as input:

class leo.plugins.nodediff.NodeDiffController(c)[source]

Bases: object


Runs a diff on the marked nodes. Will only work if exactly 2 marked nodes exist in the outline.


run_diff_on_saved - compare current node content to saved content

  • event: Leo event

Runs a diff on the selected nodes. Will only work if exactly two nodes are selected.


Runs a diff on the children of the currently selected node. Will only work if the node has exactly two children.


run_diff_on_vcs - try and check out the previous version of the Leo file and compare a node with the same gnx in that file with the current node

  • event: Leo event

Return True if the plugin has loaded successfully.

leo.plugins.nodediff.onCreate(tag, keys)[source]

nodetags Module

nodewatch Module

notebook Module

open_shell Module

Creates an ‘Extensions’ menu containing two commands: Open Console Window and Open Explorer.

The Open Console Window command opens xterm on Linux. The Open Explorer command Opens a Windows explorer window.

This allows quick navigation to facilitate testing and navigating large systems with complex directories.

Please submit bugs / feature requests to

Current limitations: - Not tested on Mac OS X … - On Linux, xterm must be in your path.


Return True if the plugin has loaded successfully.

leo.plugins.open_shell.onCreate(tag, keywords)[source]
class leo.plugins.open_shell.pluginController(c)[source]

Bases: object


outline_export Module

Modifies the way exported outlines are written.


Return True if the plugin has loaded successfully.

leo.plugins.outline_export.newMoreHead(self, firstLevel, useVerticalBar=True)[source]
leo.plugins.outline_export.onStart(tag, keywords)[source]

paste_as_headlines Module

Creates new headlines from clipboard text.

If the pasted text would be greater than 50 characters in length, the plugin truncates the headline to 50 characters and pastes the entire line into the body text of that node. Creates a “Paste as Headlines” option the Edit menu directly under the existing Paste option.

leo.plugins.paste_as_headlines.createPasteAsHeadlinesMenu(tag, keywords)[source]

Return True if the plugin has loaded successfully.


pluginsTest Module

plugins_menu Module

Creates a Plugins menu and adds all actives plugins to it.

Selecting these menu items will bring up a short About Plugin dialog with the details of the plugin. In some circumstances a submenu will be created instead and an ‘About’ menu entry will be created in this.

INI files and the Properties Dialog

If a file exists in the plugins directory with the same file name as the plugin but with a .ini extension instead of .py, then a Properties item will be created in a submenu. Selecting this item will pop up a Properties Dialog which will allow the contents of this file to be edited.

The .ini file should be formated for use by the python ConfigParser class.

Special Methods

Certain methods defined at the top level are considered special.

If a method is defined at the module level with a name of the form cmd_XZY then a menu item XZY will be created which will invoke cmd_XZY when it is selected. These menus will appear in a sub menu.


This method, if it exists, will be called when the user clicks on the plugin name in the plugins menu (or the About item in its submenu), but only if the plugin was loaded properly and registered with g.plugin_signon.

Special Variable Names

Some names defined at the top level have special significance.

This will be used to define the name of the plugin and will be used as a label for its menu entry.
Plugins can also attempt to select the order they will appear in the menu by defining a __plugin_prioriy__. The menu will be created with the highest priority items first. This behavior is not guaranteed since other plugins can define any priority. This priority does not affect the order of calling handlers. To change the order select a number outside the range 0-200 since this range is used internally for sorting alphabetically. Properties and INI files.
class leo.plugins.plugins_menu.PlugIn(plgMod, c=None)[source]

Bases: object

A class to hold information about one plugin


Put information about this plugin in a scrolledMessage dialog.


Add items in the main menu for each decorated command in this plugin. The g.command decorator sets func.is_command & func.command_name.


Return a nice version of the plugin name

Historically some plugins had “at_” and “mod_” prefixes to their name which makes the name look a little ugly in the lists. There is no real reason why the majority of users need to know the underlying name so here we create a nice readable version.


Display a modal properties dialog for this plugin


Update the config object from the dialog ‘data’ structure


Write the configuration to a file.

leo.plugins.plugins_menu.addPluginMenuItem(p, c)[source]

@param p: Plugin object for one currently loaded plugin @param c: Leo-editor “commander” for the current .leo file

leo.plugins.plugins_menu.createPluginsMenu(tag, keywords)[source]

Create the plugins menu: calld from create-optional-menus hook.


Return True if the plugin has loaded successfully.

pretty_print Module

Customizes pretty printing.

The plugin creates a do-nothing subclass of Leo’s tokenizing pretty printer. To customize, simply override in this file the methods of the base prettyPrinter class in You would typically want to override putNormalToken or its allies. Templates for these methods have been provided. You may, however, override any methods you like. You could even define your own class entirely, provided you implement the prettyPrintNode method.

class leo.plugins.pretty_print.MyPrettyPrinter(c)[source]

Bases: leo.core.leoBeautify.PythonTokenBeautifier

An example subclass of Leo’s PrettyPrinter class.

Not all the base class methods are shown here: just the ones you are likely to want to override.


Return True if the plugin has loaded successfully.

projectwizard Module

python_terminal Module

qtGui Module

qt gui plugin.

qt_main Module

class leo.plugins.qt_main.Ui_MainWindow[source]

Bases: object


qt_quicksearch Module

qtframecommands Module

quickMove Module

quicksearch Module

quit_leo Module

Shows how to force Leo to quit.


Return True if the plugin has loaded successfully.

read_only_nodes Module

redirect_to_log Module

Sends all output to the log pane.


Return True if the plugin has loaded successfully.

leo.plugins.redirect_to_log.onStart(tag, keywords)[source]

rss Module

Adds primitive RSS reader functionality to Leo.

By Jacob M. Peck.

RSS feeds

This plugin requires the python module ‘feedparser’ to be installed.

This plugin operates on RSS feed definitions, which are defined as nodes with headlines that start with @feed, and with bodies that contain a valid @url directive.

For example, the following is a valid feed definition:

@feed  Hack a Day

    Hack a Day's feed.  Awesome tech stuff.

Each @feed node also stores a viewed history of previous stories, so that the next time the feed is parsed, you will only see new stories. This history can be reset with the rss-clear-etc commands below.

Important Note

This plugin currently doesn’t have any undo capability - any changes performed by the following commands are not undoable.

Configuration Settings

This plugin is configured with the following @settings:

@string rss-date-format

Format string to provide datetime.time.strftime, to format entry dates. Defaults to ‘%Y-%m-%d %I:%M %p’ if not provided.

@bool rss-sort-newest-first

If True, newest entries are placed before older entries. If False, older entries are placed before newer entries.

@string rss-headline-format

The format of an entry headline, specified with various tokens. Defaults to ‘[<date>] <title>’ if not provided.

Valid tokens are:

<date> - the date, formatted according to @string rss-date-format
<title> - the entry title
<link> - the entry link (not recommended in headline)
<summary> - the entry summary (extremely not recommeded in headline)

Anything that isn’t a valid token is retained untouched, such as the square brackets in the default setting.

@data rss-body-format

The body of this node will provide the structure of the body of parsed entry nodes. Empty lines should be denoted with ‘n’ on a line by itself. It defaults to the following, if not provided:

@url <link>



Valid tokens are the same as for @string rss-headline-format. Any instance of ‘ ‘ on a line by itself is replaced with an empty line. All other strings that are not valid tokens are retained untouched, such as the @url directive in the default.


This plugin uses commands to operate on these @feed definitions. The following commands are available:


Parses the selected @feed node, creating entries for each story as children of the @feed node. Can be SLOW for large feeds.


Parses all @feed nodes in the current outline, creating entries for each story as children of the appropriate @feed nodes. Not recommended, as it can make Leo appear to be locked up while running.


Deletes all the children of the selected @feed node.


Deletes all children of all @feed nodes in the current outline.


Clears the selected @feed node’s viewed stories history.


Clears the viewed stories history of every @feed node in the current outline.

class leo.plugins.rss.RSSController(c)[source]

Bases: object

add_entry_to_history(feed, entry)[source]

Clears the viewed stories history of every @feed node in the current outline.


Clears the selected @feed node’s viewed stories history.


Deletes all children of all @feed nodes in the current outline.


Deletes all the children of the selected @feed node.

entry_in_history(feed, entry)[source]

Parses all @feed nodes in the current outline, creating entries for each story as children of the appropriate @feed nodes. Not recommended, as it can make Leo appear to be locked up while running.


Parses the selected @feed node, creating entries for each story as children of the @feed node. Can be SLOW for large feeds.

set_history(feed, history)[source]

Return True if the plugin has loaded successfully.

leo.plugins.rss.onCreate(tag, keys)[source]

rst3 Module

run_nodes Module

Runs a program and interface Leo through its input/output/error streams.

The double-click-icon-box command on a node whose headlines is @run ‘cmd args’ will execute the command. There are several other features, including @arg and @input nodes.

The plugin introduce two new nodes that transform leo into a terminal. It was mostly intended to run compilers and debuggers while having the possibility to send messages to the program.

The double-click-icon-box command on a node whose headline is @run <command> <args> will launch <command> with the given arguments. It will also mark the node. # Terminates the argument list. @run # <comment> is also valid.

@in nodes are used to send input to the running process. Double clicking on the icon of an @in <message> node will append a “n” to <message> and write it to the program, no matter where the node is placed. If no @run node is active, nothing happens.

The body text of every child, in which the headlines do not begin with @run’ or @in’, will be appended to <command>, allowing you to add an unlimited number of arguments to <command>.

The output of the program is written in the log pane (Error output in red). When the program exit the node is set unmarked and the return value is displayed… When the enter key is pressed in the body pane of an active @run node the content of it body pane is written to the program and then emptied ready for another line of input. If the node have @run nodes in its descendants, they will be launched successively. (Unless one returned an exit code other than 0, then it will stop there)

By Alexis Gendron Paquette. Please send comments to the Leo forums.

leo.plugins.run_nodes.OnBodyKey(tag, keywords)[source]
leo.plugins.run_nodes.OnIconDoubleClick(tag, keywords)[source]
leo.plugins.run_nodes.OnIdle(tag, keywords)[source]
leo.plugins.run_nodes.OnQuit(tag, keywords=None)[source]
leo.plugins.run_nodes.UpdateText(t, wcolor='black')[source]

Return True if the plugin has loaded successfully.

class leo.plugins.run_nodes.readingThread(group=None, target=None, name=None, args=(), kwargs=None, verbose=None)[source]

Bases: threading.Thread

File = None
Text = ''
TextLock = <thread.lock object>

Called automatically when the thread is created.

screen_capture Module

screencast Module

screenshots Module

script_io_to_body Module

Sends output from the Execute Script command to the end of the body pane.


Return True if the plugin has loaded successfully.

leo.plugins.script_io_to_body.newExecuteScript(self, event=None, p=None, script=None, useSelectedText=True, define_g=True, define_name='__main__', silent=False)[source]
leo.plugins.script_io_to_body.newPut(self, s, *args, **keys)[source]
leo.plugins.script_io_to_body.newPutNl(self, s, *args, **keys)[source]
leo.plugins.script_io_to_body.onCreate(tag, keys)[source]

scripts_menu Module

Creates a Scripts menu for LeoPy.leo.

leo.plugins.scripts_menu.createScriptsMenu(tag, keywords)[source]

Return True if the plugin has loaded successfully.

setHomeDirectory Module

Sets to a hard-coded path.


Return True if the plugin has loaded successfully.

sftp Module

slideshow Module

Supports slideshows in Leo outlines.

This plugin defines four new commands:

  • next-slide-show: move to the start of the next slide show, or the first slide show if no slide show has been seen yet.
  • prev-slide-show: move to the start of the previous slide show, or the first slide show if no slide show has been seen yet.
  • next-slide: move to the next slide of a present slide show.
  • prev-slide: move to the previous slide of the present slide show.

Slides shows consist of a root @slideshow node with descendant @slide nodes. @slide nodes may be organized via non-@slide nodes that do not appear in the slideshow.

All these commands ignore @ignore trees.


Return True if the plugin has loaded successfully.

leo.plugins.slideshow.onCreate(tag, keys)[source]
class leo.plugins.slideshow.slideshowController(c)[source]

Bases: object


Make p the present slide, and set self.slide and maybe self.slideShowRoot.

spydershell Module

startfile Module

Launches (starts) a file given by a headline when executing the double-click-icon-box

This plugin ignores headlines starting with an ‘@’. Uses the @folder path if the headline is under an @folder headline. Otherwise the path is relative to the Leo file.

This does not work on Linux, because os.startfile does not exist.


Return True if the plugin has loaded successfully.

leo.plugins.startfile.onIconDoubleClick(tag, keywords)[source]
leo.plugins.startfile.start_file(c, p)[source]

stickynotes Module

stickynotes_plus Module

swing_gui Module

systray Module

testRegisterCommand Module

A plugin to test k.registerCommand.


Return True if the plugin has loaded successfully.

leo.plugins.testRegisterCommand.onCreate(tag, keys)[source]

textnode Module

Supports @text nodes for reading and writing external files.

This plugin has been superceded by @edit nodes.

The @text node is for embedding text files in a leo node that won’t be saved with the leo file, and won’t contain any sentinel leo comments. Children of @text nodes are not saved with the derived file, though they will stay in the outline. When a outline is first loaded any @text nodes are filled with the contents of the text files on disk. To refresh the contents of an @text node, execute the double-click-icon-box command on the node.

leo.plugins.textnode.getPath(c, p)[source]

Return True if the plugin has loaded successfully.

leo.plugins.textnode.on_icondclick(tag, keywords)[source]
leo.plugins.textnode.on_open(tag, keywords)[source]
leo.plugins.textnode.on_save(tag, keywords)[source]
leo.plugins.textnode.readtextnode(c, p)[source]
leo.plugins.textnode.savetextnode(c, p)[source]

threadutil Module

timestamp Module

If this plugin is enabled, the following node attributes will be managed: - str_ctime: creation time - str_mtime: time node was last modified - str_atime: time node contents were last viewed

leo.plugins.timestamp.create_node_hook(tag, keywords)[source]

Hooked to <create-node> = set all 3 timestamps to now


Use standard Unix timestamps


Return True if the plugin has loaded successfully.

leo.plugins.timestamp.new_hook(tag, keywords)[source]

Hooked to <new> event, fired when a Leo file is created, which the create_node_hook doesn’t handle.

leo.plugins.timestamp.select1_hook(tag, keywords)[source]

Hooked to select1, which fires when focus changes Always sets str_atime to now, sets str_mtime if node body has changed

tkGui Module

todo Module

tomboy_import Module

Allows imports of notes created in Tomboy / gnote.


  • Create a node with the headline ‘tomboy’
  • Select the node, and do alt+x act-on-node
  • The notes will appear as children of ‘tomboy’ node
  • The next time you do act-on-node, existing notes will be updated (they don’t need to be under ‘tomboy’ node anymore) and new notes added.
class leo.plugins.tomboy_import.MLStripper[source]

Bases: HTMLParser.HTMLParser

leo.plugins.tomboy_import.capturenotes(c, pos)[source]

Return True if the plugin has loaded successfully.

leo.plugins.tomboy_import.onCreate(tag, keys)[source]
leo.plugins.tomboy_import.pos_for_gnx(c, gnx)[source]
leo.plugins.tomboy_import.tomboy_act_on_node(c, p, event)[source]

trace_gc_plugin Module

Traces changes to Leo’s objects at idle time.


Return True if the plugin has loaded successfully.

leo.plugins.trace_gc_plugin.printIdleGC(tag, keywords)[source]
leo.plugins.trace_gc_plugin.printIdleRefs(tag, keywords)[source]

trace_keys Module

Traces keystrokes in the outline and body panes.


Return True if the plugin has loaded successfully.

leo.plugins.trace_keys.onKey(tag, keywords)[source]

trace_tags Module

Trace most common hooks, but not key, drag or idle hooks.


Return True if the plugin has loaded successfully.

leo.plugins.trace_tags.trace_tags(tag, keywords)[source]

valuespace Module

Supports Leo scripting using per-Leo-outline namespaces.


This plugin supports the following commands:


Creates a tree whose root node is named ‘valuespace’ containing one child node for every entry in the namespace. The headline of each child is @@r <key>, where <key> is one of the keys of the namespace. The body text of the child node is the value for <key>.


Prints key/value pairs of the namespace.


Clears the namespace.


Scans the entire Leo outline twice, processing @=, @a and @r nodes.

Pass 1

Pass 1 evaluates all @= and @a nodes in the outline as follows:

@= (assignment) nodes should have headlines of the the form:

@= <var>

Pass 1 evaluates the body text and assigns the result to <var>.

@a (anchor) nodes should have headlines of one of two forms:

@a <var>

The first form evaluates the script in the parent node of the @a node. Such bare @a nodes serve as markers that the parent contains code to be executed.

The second form evaluates the body of the parent of the @a node and assigns the result to <var>.

Important: Both forms of @a nodes support the following @x convention when evaluating the parent’s body text. Before evaluating the body text, pass1 scans the body text looking for @x lines. Such lines have two forms:

  1. @x <python statement>

Pass 1 executes <python statement>.

  1. The second form spans multiple lines of the body text:

    @x {
    python statements
    @x }

Pass 1 executes all the python statements between the @x { and the @x }

  1. Assign block of text to variable:

    @x =<var> {
    @x }

Pass 1 assigns the block of text to <var>. The type of value is SList, a special subclass of standard ‘list’ that makes operating with string lists convenient. Notably, you can do <var>.n to get the content as plain string.

A special case of this is the “list append” notation:

@x =<var>+ {
@x }

This assumes that <var> is a list, and appends the content as SList to this list. You will typically do ‘@x var = []’ earlier in the document to make this construct work.

<var> in all constructs above can be arbitrary expression that can be on left hand side of assignment. E.g. you can use, foo[‘bar’], foo().bar etc.

Pass 2

Pass 2 “renders” all @r nodes in the outline into body text. @r nodes should have the form:

@r <expression>

Pass 2 evaluates <expression> and places the result in the body pane.

TODO: discuss SList expressions.

Evaluating expressions

All expression are evaluated in a context that predefines Leo’s c, g and p vars. In addition, g.vs is a dictionary whose keys are c.hash() and whose values are the namespaces for each commander. This allows communication between different namespaces, while keeping namespaces generally separate.

class leo.plugins.valuespace.ValueSpaceController(c=None, ns=None)[source]

Bases: object

A class supporting per-commander evaluation spaces containing @a, @r and @= nodes.


The vs-create-tree command.


Add ‘builtin’ methods to namespace

let(var, val)[source]

Enter var into self.d with the given value. Both var and val must be strings.

let_body(var, val)[source]
let_cl(var, body)[source]

handle @cl node


Update p’s tree (or the entire tree) as follows:

  • Evaluate all @= nodes and assign them to variables
  • Evaluate the body of the parent nodes for all @a nodes.
  • Read in @vsi nodes and assign to variables
render_value(p, value)[source]

Put the rendered value in p’s body pane.


The vs-reset command.


reconfigure vsc for new c

Needed by ipython integration


The vs-update command.


Evaluate @r <expr> nodes, puting the result in their body text. Output @vso nodes, based on file extension

leo.plugins.valuespace.colorize_headlines_visitor(c, p, item)[source]

Changes @thin, @auto, @shadow to bold


deal with singleton “ipython” controller


Return True if the plugin has loaded successfully.

leo.plugins.valuespace.onCreate(tag, key)[source]

Create tree from all variables.


Dump the valuespace for this commander.


viewrendered Module

viewrendered2 Module

vim Module

#@@language rest

Enables two-way communication with gVim (recommended) or Vim.


Opens the nearest ancestor @file or @clean node in vim. Leo will update the file in the outline when you save the file in vim.
Opens the selected node in vim. Leo will update the node in the outline when you save the file in vim.


Set the vim_cmd and vim_exe settings as shown below.

Alternatively, you can put gvim.exe is on your PATH.


@string vim_cmd

The command to execute to start gvim. Something like:

<path-to-gvim>/gvim --servername LEO
@string vim_exe
The path to the gvim executable.
True: Leo will put the node or file in a Vim tab card.
class leo.plugins.vim.VimCommander(c, entire_file)[source]

Bases: object

A class implementing the vim plugin.


Return True of basic checks pass.


Report an error.


Search the open-files list for a file corresponding to p.


Return the nearest ancestor @auto or @clean node.


Stop handling the path: - Remove the path from the list of open-with files. - Send a command to vim telling it to close the path.


Compute the cursor argument for vim.


Load the contextmenu plugin.


Open the the file in vim using c.openWith.


Open p in vim, or the entire enclosing file if entire_file is True.

should_open_old_file(path, root)[source]

Return True if we should open the old temp file.


Return the concatenation of all bodies in p’s tree.


Return True if the plugin has loaded successfully.

leo.plugins.vim.vim_open_file_command(event)[source] Open the entire file in (g)vim.

leo.plugins.vim.vim_open_node_command(event)[source] open the selected node in (g)vim.

word_count Module

Counts characters, words, lines, and paragraphs in the body pane.

It adds a “Word Count…” option to the bottom of the Edit menu that will activate the command.

leo.plugins.word_count.createWordCountMenu(tag, keywords)[source]

Return True if the plugin has loaded successfully.


wikiview Module

word_export Module

Adds the Plugins:Word Export:Export menu item to format and export the selected outline to a Word document, starting Word if necessary.


Export the current node to Word

leo.plugins.word_export.doPara(word, text, style=None)[source]

Write a paragraph to word


Called when the user presses the “Apply” button on the Properties form


Get a connection to Word


Return True if the plugin has loaded successfully.

leo.plugins.word_export.writeNodeAndTree(c, word, header_style, level, maxlevel=3, usesections=1, sectionhead='', vnode=None)[source]

Write a node and its children to Word

wxGui Module

xemacs Module

Allows you to edit nodes in emacs/xemacs.

Provides the emacs-open-node command which passes the body text of the node to emacs.

You may edit the node in the emacs buffer and changes will appear in Leo.


Return True if the plugin has loaded successfully.

leo.plugins.xemacs.open_in_emacs(tag, keywords)[source]

Open current node in (x)emacs

Provied by plugin

leo.plugins.xemacs.open_in_emacs_helper(c, p)[source]

xml_edit Module

Provides commands (Alt-x) for importing and exporting XML from a Leo outline. These commands are to XML what @auto-rst is to reStructuredText.

xml2leo imports an .xml file into the node following the currently selected node. leo2xml exports the current subtree to an .xml file the user selects.

xml_validate, if executed on the top node in the Leo xml tree, reports any errors in XML generation or DTD validation, based on the DTD referenced from the XML itself. If there’s no DTD it reports that as an error.

leo2xml2leo takes the selected Leo subtree representing an XML file, converts it to XML internally, and then creates a new Leo subtree from that XML after the original, with ‘NEW ‘ at the start of the top node’s name. This updates all the headlines, so that the convenience only previews (see below) are updated. The original can be deleted if the new subtree seems correct.


This is a valid XML file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dml SYSTEM "dml.dtd">
<?xml-stylesheet href="common.css"?>
<dml xmlns='' xmlns:other=''/>
  <block type='example'>Here's <other:b>some</other:b> text</block>
<!-- This is the last line -->

Note the processing instruction (xml-stylesheet), the DTD (DOCTYPE), the trailing comment (after the closing tag), and the pernicious mixed content (three separate pieces of text in the <block/> element). These commands attempt to deal with all of this.

  • A top level Leo node is created to hold these top level parts. Its headline is the basename of the file.

  • The xml declaration is placed in the body of this top level Leo node

  • Below that, in the same body text, appears a simple namespace map:

    i.e. the default namespace first, and then any prefixed name spaces.

  • Below that, in the same body text, appears the DOCTYPE declaration

  • Children are added to this top level Leo node to represent the top level elements in the xml file. Headlines have the following meanings:

    • ? pi-target some="other" __CHK - i.e. questionmark, space, name of processing instruction target, start of processing instruction content. Only the questionmark, which indicates the processing instruction, and the first word, which indicates the processing instruction target, matter. The remainder is just a convenience preview of the processing instruction content, which is the Leo node’s body text.
    • # This is *really* imp - i.e. hash, space, start of comment content. Only the hash, which indicates the comment, matters. The remainder is just a convenience preview of the comment content, which is the Leo node’s body text.
    • tagname name_attribute start of element text - i.e. the name of an element followed by a convenience preview of the element’s text content. If the element has a name attribute that’s included at the start of the text preview. Only the first word matters, it’s the name of the element.
  • Element’s text is placed in the Leo node’s body. If the element has tailing text (the " text" tailing the <other:b/> element in the above example), that occurs in the Leo node’s body separated by the tailing text sentinel:

  • Element’s attributes are stored in a dict p.v.u['_XML']['_edit'] on the Leo node. '_XML' is the uA prefix for these commands, and '_edit' is used by the attrib_edit plugin to identify attributes it should present to the user for editing. The attrib_edit plugin should be enabled and its v.u mode activated (through its submenu on the Plugins menu). The attribute edit panel initially appears as a tab in the log pane, although it can be moved around by right clicking on the pane dividers if the viewrendered and free_layout plugins are enabled.

leo.plugins.xml_edit.append_element(xml_node, to_leo_node)[source]

handle appending xml_node which may be Element, Comment, or ProcessingInstruction. Recurses for Element.

leo.plugins.xml_edit.cd_here(c, p)[source]

attempt to cd to the directory in effect at p according to Leo’s @path concept


recursively read from leo nodes and write into an Element tree

leo.plugins.xml_edit.get_tag(xml_node, attrib=None)[source]

replace {}element with fns:element


Return True if the plugin has loaded successfully.


wrapper to write xml for current node


wrapper to cycle leo->xml->leo, mostly to clean up headers


replace fns:element with {}element

leo.plugins.xml_edit.xml2leo(event, from_string=None)[source]

handle import of an .xml file, places new subtree after c.p


get the xml for the subtree at nd


Perform DTD validation on the xml and return error output or an empty string if there is none

xsltWithNodes Module

Adds the Outline:XSLT menu containing XSLT-related commands.

This menu contains the following items:

  • Set StyleSheet Node:
    • Selects the current node as the xsl stylesheet the plugin will use.
  • Process Node with Stylesheet Node:
    • Processes the current node as an xml document, resolving section references and Leo directives.
    • Creates a sibling containing the results.

Requires 4Suite 1.0a3 or better, downloadable from

leo.plugins.xsltWithNodes.addMenu(tag, keywords)[source]
leo.plugins.xsltWithNodes.addXSLTElement(c, element)[source]

adds some xslt to the text node


creates a node and inserts some xslt boilerplate


This method cleans a string up for the processor. It currently just removes leading and trailing whitespace


This def performs a simple test on a node. Can the data be successfully parsed by minidom or not? Results are output to the log.


This def turns a node into a string using Leo’s file-nosent write logic.


Return True if the plugin has loaded successfully.


Simple method that jumps us to the current XSLT node


this executes the stylesheet node against the current node


this command sets what the current style node is


Determines if a XSLT Style node has not been selected

zenity_file_dialogs Module

Replaces the tk file dialogs on Linux with external calls to the zenity gtk dialog package.

This plugin is more a proof of concept demo than a useful tool. The dialogs presented do not take filters and starting folders can not be specified.

Despite this, some Linux users might prefer it to the tk dialogs.

leo.plugins.zenity_file_dialogs.callZenity(title, multiple=False, save=False, test=False)[source]

Return True if the plugin has loaded successfully.

leo.plugins.zenity_file_dialogs.onStart2(tag, keywords)[source]

Replace tkfile open/save method with external calls to zenity.

leo.plugins.zenity_file_dialogs.runOpenFileDialog(title=None, filetypes=None, defaultextension=None, multiple=False)[source]

Call zenity’s open file(s) dialog.

leo.plugins.zenity_file_dialogs.runSaveFileDialog(initialfile=None, title=None, filetypes=None, defaultextension=None)[source]

Call zenity’s save file dialog.