<?xml version="1.0" encoding="utf-8"?>
<!-- Created by Leo: http://leoeditor.com/leo_toc.html -->
<leo_file xmlns:leo="http://leoeditor.com/namespaces/leo-python-editor/1.1" >
<leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/>
<globals body_outline_ratio="0.5" body_secondary_ratio="0.5">
	<global_window_position top="50" left="50" height="500" width="700"/>
	<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
<preferences/>
<find_panel_settings/>
<vnodes>
<v t="ekr.20050315084904"><vh>Startup</vh>
<v t="ekr.20141117135127.2"><vh>@settings</vh>
<v t="ekr.20141117135127.3"><vh>@bool wikiview-active = False</vh></v>
</v>
<v t="ekr.20070325123540"><vh>@chapters</vh></v>
<v t="ekr.20101025095431.1517"><vh>Installer/Distribution bugs &amp; to-do</vh>
<v t="ekr.20101025095431.1518"><vh>Fixed Bug 514656 Uninstall operation does not work as expected</vh>
<v t="ekr.20090901092556.1576"><vh>genUninstallData &amp; helpers</vh>
<v t="ekr.20090901121423.1568"><vh>getDeleteDirectories</vh></v>
<v t="ekr.20090901121423.1569"><vh>getDeleteFiles</vh></v>
<v t="ekr.20090901121423.1567"><vh>getUninstallVariableData</vh></v>
</v>
</v>
<v t="ekr.20101026142031.1516"><vh>Registry Keys</vh></v>
</v>
</v>
<v t="EKR.20040519091259"><vh>Announcements</vh>
<v t="EKR.20040519091259.1"><vh>Download statistics</vh></v>
<v t="ekr.20160315105606.1"><vh>Previous announcements</vh>
<v t="ekr.20160314155303.1"><vh>Leo 4.x</vh>
<v t="ekr.20101115090518.1494"><vh>Leo 4.8 final</vh></v>
<v t="ekr.20110603112852.1505"><vh>Leo 4.9 final</vh></v>
<v t="ekr.20120328150744.1791"><vh>Leo 4.10 final</vh></v>
<v t="ekr.20131105110107.16636"><vh>Leo 4.11 final</vh></v>
</v>
<v t="ekr.20141105082156.2"><vh>Leo 5.0 final</vh></v>
<v t="ekr.20150415145711.1"><vh>Leo 5.1 final</vh></v>
<v t="ekr.20160314155002.1"><vh>Leo 5.2-final</vh>
<v t="ekr.20160314155002.2"><vh> Highlights</vh></v>
<v t="ekr.20160314155002.3"><vh>Bugs</vh>
<v t="ekr.20160314155002.4"><vh>Fixed #131: Insert time in headline now inserts time in body</vh></v>
<v t="ekr.20160314155002.5"><vh>Fixed #136: Viewrendered2 chokes on displaying @html nodes</vh></v>
<v t="ekr.20160314155002.6"><vh>Fixed #150: Importing file to @clean produces section references...</vh></v>
<v t="ekr.20160314155002.7"><vh>Fixed #162: Valid language list in Docs not up to date</vh></v>
<v t="ekr.20160314155002.8"><vh>Fixed #169: import-file does not preserve gnx of root @file node</vh></v>
<v t="ekr.20160314155002.9"><vh>Fixed #181: Focus remains in previous file</vh></v>
<v t="ekr.20160314155002.10"><vh>Fixed #182: Long filenames do not wrap in notification dialogues</vh></v>
<v t="ekr.20160314155002.11"><vh>Fixed #193: goto-global-line doesn't work properly in @clean files</vh></v>
<v t="ekr.20160314155002.12"><vh>Fixed #195: fcol when using @first directive is inaccurate</vh></v>
<v t="ekr.20160314155002.13"><vh>Fixed #196: Traceback using graphcanvas.py</vh></v>
<v t="ekr.20160314155002.14"><vh>Fixed #198: Find tab 'ignore case' tick box has no effect</vh></v>
<v t="ekr.20160314155002.15"><vh>Fixed #199: The "already open" logic hard crashes Leo</vh></v>
<v t="ekr.20160314155002.16"><vh>Fixed #200: goto-global-line logic is too complex and buggy</vh></v>
<v t="ekr.20160314155002.17"><vh>Fixed #211: Saving untitled document on window close not working on Qt GUI</vh></v>
<v t="ekr.20160314155002.18"><vh>Fixed #213: leo --ipython fails to connect with python3.5 and jupyter</vh></v>
<v t="ekr.20160314155002.19"><vh>Fixed #215: insert-file-name doesn't process ~</vh></v>
<v t="ekr.20160314155002.20"><vh>Fixed #217: vim plugin does not work as described</vh></v>
<v t="ekr.20160314155002.21"><vh>Fixed #218: Select Text and Clipboard</vh></v>
<v t="ekr.20160314155002.22"><vh>Fixed #220: @spot bug</vh></v>
<v t="ekr.20160314155002.23"><vh>Fixed #224: TypeError: unorderable types...</vh></v>
<v t="ekr.20160314155002.24"><vh>Fixed #234: hard crash on UnicodeDecodeError</vh></v>
<v t="ekr.20160314155002.25"><vh>Fixed #239: cfa fails to find many occurrences...</vh></v>
<v t="ekr.20160314155002.26"><vh>Fixed @tabwidth bug</vh></v>
<v t="ekr.20160314155002.27"><vh>Fixed a bug in p.__eq__</vh></v>
<v t="ekr.20160314155002.28"><vh>Fixed abbreviation bugs and improved abbreviations</vh></v>
<v t="ekr.20160314155002.29"><vh>Fixed cut/paste from menus</vh></v>
<v t="ekr.20160314155002.30"><vh>Fixed Find crash</vh></v>
<v t="ekr.20160314155002.31"><vh>Fixed Python 3k problem with @lineending</vh></v>
<v t="ekr.20160314155002.32"><vh>Fixed remove-blank-lines command</vh></v>
<v t="ekr.20160314155002.33"><vh>Improved Ctrl-LtArrow</vh></v>
<v t="ekr.20160314155002.34"><vh>Investigated #153: Leo acts on some operator input when the Leo window is NOT the top window</vh></v>
<v t="ekr.20160314155002.35"><vh>Investigated #188: Find/Replace All Suboutline only same as Node only</vh></v>
<v t="ekr.20160314155002.36"><vh>Investigated #188: Find/Replace All Suboutline only same as Node only</vh></v>
<v t="ekr.20160314155002.37"><vh>Investigated #232: print-plugins-info fails</vh></v>
<v t="ekr.20160314155002.38"><vh>Recover from orphan bit in leoPyBad.leo</vh></v>
</v>
<v t="ekr.20160314155002.39"><vh>Code</vh>
<v t="ekr.20160314155002.40"><vh>Added new position predicates for limiting search</vh></v>
<v t="ekr.20160314155002.41"><vh>c.backup</vh></v>
<v t="ekr.20160314155002.42"><vh>c.cloneFindByPredicate</vh></v>
<v t="ekr.20160314155002.43"><vh>Changed handling of orphan bits</vh></v>
<v t="ekr.20160314155002.44"><vh>Decorators simplify Leo's command dispatching</vh></v>
<v t="ekr.20160314155002.45"><vh>Removed g.isChar</vh></v>
<v t="ekr.20160314155002.46"><vh>Reorganized Leo's commands files</vh></v>
<v t="ekr.20160314155002.47"><vh>Replace all has_key by "in"</vh></v>
<v t="ekr.20160314155002.48"><vh>Verified that c.p.copy() is always redundant</vh></v>
</v>
<v t="ekr.20160314155002.49"><vh>Commands</vh>
<v t="ekr.20160314155002.50"><vh>Alt-N (goto-next-clone) falls backs to find-next-clone</vh></v>
<v t="ekr.20160314155002.51"><vh>cfa and cff</vh></v>
<v t="ekr.20160314155002.52"><vh>cffm and cfam</vh></v>
<v t="ekr.20160314155002.53"><vh>clear-log</vh></v>
<v t="ekr.20160314155002.54"><vh>clone-to-at-spot</vh></v>
<v t="ekr.20160314155002.55"><vh>cut/copy</vh></v>
<v t="ekr.20160314155002.56"><vh>find-all now writes to the body of a new top-level node</vh></v>
<v t="ekr.20160314155002.57"><vh>find-def &amp; find-var</vh></v>
<v t="ekr.20160314155002.58"><vh>flatten-outline-to-node</vh></v>
<v t="ekr.20160314155002.59"><vh>help-for-keystroke</vh></v>
<v t="ekr.20160314155002.60"><vh>kill</vh></v>
<v t="ekr.20160314155002.61"><vh>show-invisibles uses Qt characters</vh></v>
<v t="ekr.20160314155002.62"><vh>vim-open-file command</vh></v>
</v>
<v t="ekr.20160314155002.63"><vh>Directives</vh>
<v t="ekr.20160314155002.64"><vh>@beautify and @nobeautify</vh></v>
<v t="ekr.20160314155002.65"><vh>@wrap now honored immediately</vh></v>
</v>
<v t="ekr.20160314155002.66"><vh>Features</vh>
<v t="ekr.20160314155002.67"><vh>Decluttered headlines</vh></v>
<v t="ekr.20160314155002.68"><vh>Abbreviations now support auto-close quotes</vh></v>
<v t="ekr.20160314155002.69"><vh>Added new Themes machinery</vh></v>
<v t="ekr.20160314155002.70"><vh>Allow wildcard expansion of filenames on the command-line</vh></v>
<v t="ekr.20160314155002.71"><vh>Ctrl-G now resets status line</vh></v>
<v t="ekr.20160314155002.72"><vh>Find commands now show status</vh></v>
<v t="ekr.20160314155002.73"><vh>Optional line numbers</vh></v>
<v t="ekr.20160314155002.74"><vh>Use Qt code to show invisibles</vh></v>
</v>
<v t="ekr.20160314155002.75"><vh>Menus</vh>
<v t="ekr.20160314155002.76"><vh>Settings: Edit Settings menu</vh></v>
<v t="ekr.20160314155002.77"><vh>File:Print menu</vh></v>
</v>
<v t="ekr.20160314155002.78"><vh>Plugins</vh>
<v t="ekr.20160314155002.79"><vh>leoOPML.py</vh></v>
<v t="ekr.20160314155002.80"><vh>mod_http.py: controlling Leo remotely</vh></v>
</v>
<v t="ekr.20160314155002.81"><vh>Scripts</vh>
<v t="ekr.20160314155002.82"><vh>make_stub_files.py</vh></v>
<v t="ekr.20160314155002.83"><vh>python_to_coffescript.py</vh></v>
</v>
<v t="ekr.20160314155002.84"><vh>Settings</vh>
<v t="ekr.20160314155002.85"><vh>@bool find-ignore-duplicates</vh></v>
<v t="ekr.20160314155002.86"><vh>@bool preload-find-pattern</vh></v>
<v t="ekr.20160314155002.87"><vh>@bool syntax-error-popup</vh></v>
<v t="ekr.20160314155002.88"><vh>@bool use_find_dialog</vh></v>
<v t="ekr.20160314155002.89"><vh>@color find-*</vh></v>
<v t="ekr.20160314155002.90"><vh>@data abbreviations-subst-env now allows Leo directives</vh></v>
<v t="ekr.20160314155002.91"><vh>@data history-list</vh></v>
<v t="ekr.20160314155002.92"><vh>@data qt-gui-user-style-sheet</vh></v>
<v t="ekr.20160314155002.93"><vh>@ifenv, improved @ifplatform &amp; @ifhostname</vh></v>
<v t="ekr.20160314155002.94"><vh>@language coffeescript</vh></v>
<v t="ekr.20160314155002.95"><vh>Settings for gutter numbers</vh></v>
</v>
</v>
</v>
<v t="ekr.20160428153901.1"><vh>Leo 5.3-final</vh></v>
<v t="EKR.20040519091259.2"><vh>Quotes of the month</vh>
<v t="ekr.20080901114425.2"><vh>Sept 2008</vh></v>
<v t="ekr.20070425092712"><vh>April 2007</vh></v>
<v t="ekr.20070101093904"><vh>January 2007</vh></v>
<v t="ekr.20060823090437"><vh>August 2006</vh></v>
<v t="ekr.20060213160806"><vh>February 2005</vh></v>
<v t="ekr.20040828084148"><vh>August 2004</vh></v>
<v t="ekr.20040630210818"><vh>July 2004</vh></v>
<v t="EKR.20040519091259.3"><vh>November 2003</vh></v>
<v t="EKR.20040519091259.4"><vh>October 2003</vh></v>
</v>
</v>
<v t="ekr.20150326055410.1"><vh>Update versions</vh></v>
<v t="ekr.20150416081546.1"><vh>Distribution check scripts</vh>
<v t="ekr.20150416081546.2"><vh>Catch mixed newlines in distribution files</vh>
<v t="ekr.20150416081546.3"><vh>check</vh></v>
</v>
<v t="ekr.20150416081546.4"><vh>Catch mixed tab &amp; space in derived files</vh>
<v t="ekr.20150416081546.5"><vh>check</vh></v>
</v>
<v t="ekr.20150416081546.6"><vh>Check all colorizer files for problem regex's</vh></v>
<v t="ekr.20150416081546.7"><vh>Clean ekr-spellpyx.txt</vh></v>
<v t="ekr.20150416081546.8"><vh>Linux install script</vh></v>
<v t="ekr.20150416081546.9"><vh>Warn if leoProjects.txt or leoToDo.txt contain clones</vh></v>
</v>
<v t="EKR.20040519090846"><vh>Distribution files</vh>
<v t="ekr.20141016105045.2119"><vh>@asis ../../.gitattributes</vh></v>
<v t="ekr.20130809141000.1990"><vh>@asis ../../INSTALL.TXT</vh>
<v t="ekr.20130809141000.1991"><vh>System requirements</vh></v>
<v t="ekr.20130809141000.1992"><vh>Leo's HOME directory</vh></v>
<v t="ekr.20130809141000.1993"><vh>Linux installation</vh></v>
<v t="ekr.20130809141000.1994"><vh>Windows installation</vh></v>
<v t="ekr.20130809141000.1995"><vh>Running Leo</vh></v>
<v t="ekr.20130809141000.1996"><vh>Creating file associations</vh></v>
<v t="ekr.20130809141000.1997"><vh>Adding Leo to your path</vh></v>
<v t="ekr.20130809141000.1998"><vh>Running Leo for the first time</vh></v>
</v>
<v t="EKR.20040519090846.1"><vh>@asis ../../LICENSE.TXT</vh></v>
<v t="EKR.20040519090846.8"><vh>@asis ../../PKG-INFO.TXT</vh></v>
<v t="EKR.20040519090846.9"><vh>@asis ../../README.MD</vh></v>
<v t="ekr.20151227063335.1"><vh>@asis ../../About leo.exe.TXT</vh></v>
<v t="ekr.20150425135153.1"><vh>homebrew istall script</vh>
<v t="ekr.20150425135153.2"><vh>brew install formula</vh></v>
</v>
</v>
<v t="ekr.20141118074110.4"><vh>Discussions</vh>
<v t="ekr.20141118074110.2"><vh>Matt's workflow for updating pypi</vh></v>
<v t="ekr.20141118074110.3"><vh>Installing Leo on Linux</vh></v>
</v>
<v t="ekr.20100202061222.1494"><vh>Distribution checklist</vh></v>
<v t="ekr.20101027131034.1490"><vh>NSIS source files</vh>
<v t="ekr.20101027160251.1500"><vh>Notes</vh>
<v t="ekr.20101027135430.1492"><vh>@url nsi new ui readme</vh></v>
<v t="ekr.20101027135430.1493"><vh>@url about pages</vh></v>
<v t="ekr.20101027160251.1497"><vh>@url nsDialogs</vh></v>
</v>
<v t="ekr.20101027054254.1590"><vh>@edit ../../leo.nsi</vh></v>
<v t="ekr.20101027115225.1494"><vh>@file nsi-boilerplate.txt</vh></v>
</v>
<v t="ekr.20101027070126.1639"><vh>@button make leo</vh>
<v t="ekr.20090905082405.1487"><vh>&lt;&lt; includes &gt;&gt;</vh></v>
<v t="ekr.20110614062644.1379"><vh>&lt;&lt; define global paths and file names &gt;&gt;</vh></v>
<v t="ekr.20101027070126.1643"><vh>class LeoMaker</vh>
<v t="ekr.20101027070126.1662"><vh>run &amp; helpers</vh>
<v t="ekr.20101105103524.1494"><vh>clean_manifest</vh></v>
<v t="ekr.20110603171959.1506"><vh>clean_spellpyx</vh></v>
<v t="ekr.20141016123713.2120"><vh>copy_nsi_files</vh></v>
<v t="ekr.20110614062644.1378"><vh>copy_ref_files (not used)</vh></v>
<v t="ekr.20101027070126.1675"><vh>create_install_files</vh></v>
<v t="ekr.20101027070126.1676"><vh>create_uninstall_files</vh></v>
<v t="ekr.20101027070126.1663"><vh>directoryList</vh></v>
<v t="ekr.20101027070126.1664"><vh>filterLines &amp; helpers</vh>
<v t="ekr.20101027070126.1665"><vh>delete...</vh></v>
</v>
<v t="ekr.20101105103524.1491"><vh>make_manifest</vh></v>
<v t="ekr.20101105103524.1493"><vh>make_zip</vh></v>
<v t="ekr.20101027070126.1666"><vh>makeDicts</vh></v>
<v t="ekr.20101027070126.1667"><vh>printMissing</vh></v>
</v>
<v t="ekr.20101027070126.1680"><vh>utils...</vh>
<v t="ekr.20101027070126.1679"><vh>openFile</vh></v>
<v t="ekr.20101027070126.1678"><vh>put</vh></v>
<v t="ekr.20090905082405.1490"><vh>unlink</vh></v>
</v>
</v>
</v>
</vnodes>
<tnodes>
<t tx="EKR.20040519090846">@language rest
</t>
<t tx="EKR.20040519090846.1">Leo is Open Software and is distributed under the terms of the MIT
License. The gist of the license is that Leo is absolutely free, even
for commercial use (including resale). There is no GNU-like "copyleft"
restriction. The Open Source Initiative board has voted to certify the
MIT license as Open Source. This license is compatible with the GPL.

Copyright (c) 1997-2016 by Edward K. Ream. All Rights Reserved.

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Leo or Edward K. Ream
not be used in advertising or publicity pertaining to distribution of
the software without specific, written prior permission.

DISCLAIMER OF WARRANTIES

EDWARD K. REAM (REAM) SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESSED
OR IMPLIED, WITH RESPECT TO THIS COMPUTER SOFTWARE, INCLUDING BUT NOT
LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. IN NO EVENT SHALL REAM BE LIABLE FOR ANY LOSS OF
PROFIT OR ANY COMMERCIAL DAMAGE, INCLUDING BUT NOT LIMITED TO SPECIAL,
INCIDENTAL, CONSEQUENTIAL OR OTHER DAMAGES.
</t>
<t tx="EKR.20040519090846.8">Metadata-Version: 1.0
Name: leo
Version: 5.3
Summary: Leo: Leonine Editor with Outlines
Home-page: http://leoeditor.com/
Author: Edward K. Ream
Author-email: edreamleo@gmail.com
License: MIT
Download URL: http://sourceforge.net/projects/leo/files/
Keywords: Outliner, IDE, PIM
Platform: Windows, Linux, MaxOS

Classifiers: Development Status :: 6 - Mature
             License :: OSI Approved :: MIT License
             Operating System :: MacOS
             Operating System :: Microsoft :: Windows
             Operating System :: POSIX :: Linux
             Programming Language :: Python
             Topic :: Software Development
             Topic :: Text Processing

Description: Leo is:
             - An outliner. Everything in Leo is an outline.
             - A Personal Information Manager.
             - A browser with a memory.
             - A powerful scripting environment.
             - A tool for studying other people's code.
             - A fully-featured IDE, with emacs-like commands.
             - Extensible via a simple plugin architecture.
             - A tool that plays well with  IPython, vim and xemacs.
             - Written in 100% pure Python
             - Compatible with Python 2.6 and above or Python 3.0 and above.
             - A tool with an inspiring and active community.
             **Leo's unique features**
             - Always-present, persistent, outline structure.
             - Leo's underlying data is a Directed Acyclic Graph.
             - Clones create multiple views of an outline.
             - A simple, powerful, outline-oriented Python API.
             - Scripts and programs can be composed from outlines.
             - Importers convert flat text into outlines.
             - Scripts have full access to all of Leo's sources.
             - Commands that act on outline structure.
               Example: the rst3 command converts outlines to reStructuredText.
             - @test and @suite scripts create unit tests automatically.
             - @button scripts apply scripts to outline data.
             - Outline-oriented directives.
             Simulating these features in vim or Emacs is possible, just as
             it is possible to simulate Python in assembly language...
             **Links**
             - Leo's home page:  http://leoeditor.com
             - Documentation:    http://leoeditor.com/leo_toc.html
             - Tutorials:        http://leoeditor.com/tutorial.html
             - Video tutorials:  http://leoeditor.com/screencasts.html
             - Forum:            http://groups.google.com/group/leo-editor
             - Download:         http://sourceforge.net/projects/leo/files/
             - Github sources:   https://github.com/leo-editor/leo-editor
             - What people are saying about Leo:     http://leoeditor.com/testimonials.html
             - A web page that displays .leo files:  http://leoeditor.com/load-leo.html
             - More links:       http://leoeditor.com/leoLinks.html
</t>
<t tx="EKR.20040519090846.9">Leo 5.3-final May 2, 2016

[Leo](http://leoeditor.com/) 5.3-final is now available on [SourceForge](http://sourceforge.net/projects/leo/files/Leo/). Leo is a PIM, an IDE and an outliner.

**The highlights of Leo 5.3**

- Leo now supports Jupyter Notebook (.ipynb) files.
- @chapter is now allowed anywhere. No need for @chapters.
- Faster spell checking.
- The rst3 command supports @rst-table.
- The show-invisibles command now uses native Qt characters.
- Dozens of other improvements and bug fixes.

**Leo is**:

- An outliner. Everything in Leo is an outline.
- A Personal Information Manager.
- A browser with a memory.
- A powerful scripting environment.
- A tool for studying other people's code.
- A fully-featured IDE, with emacs-like commands.
- Extensible via a simple plugin architecture.
- A tool that plays well with  IPython, vim and xemacs.
- Written in 100% pure Python
- Compatible with Python 2.6 and above or Python 3.0 and above.

**Leo's unique features**:
    
- Always-present, persistent, outline structure.
- Leo's underlying data is a Directed Acyclic Graph.
- Clones create multiple views of an outline.
- A simple, powerful, outline-oriented Python API.
- Scripts and programs can be composed from outlines.
- Importers convert flat text into outlines.
- Scripts have full access to all of Leo's sources.
- Commands that act on outline structure.
  Example: the rst3 command converts outlines to reStructuredText.
- @test and @suite scripts create unit tests automatically.
- @button scripts apply scripts to outline data.
- Outline-oriented directives.

Simulating these features in vim or Emacs is possible, just as
it is possible to simulate Python in assembly language...

**Links**

- [Leo's home page](http://leoeditor.com)
- [Documentation](http://leoeditor.com/leo_toc.html)
- [Tutorials](http://leoeditor.com/tutorial.html)
- [Video tutorials](http://leoeditor.com/screencasts.html)
- [Forum](http://groups.google.com/group/leo-editor)
- [Download](http://sourceforge.net/projects/leo/files/)
- [Leo on Github](https://github.com/leo-editor/leo-editor)
- [What people are saying about Leo](http://leoeditor.com/testimonials.html)
- [A web page that displays .leo files](http://leoeditor.com/load-leo.html)
- [More links](http://leoeditor.com/leoLinks.html)
</t>
<t tx="EKR.20040519091259">@pagewidth 70
@language rest
@wrap

Markdown is all that is needed:

1. SourceForge (and github) accepts markdown and generates html.
2. Create leo-editor &amp; google groups announcements by
   copy/paste from resulting SourceForge announcement.
3. Get actual html using the HTML tab in my blog.
</t>
<t tx="EKR.20040519091259.1">5.1:        setup: 1,114    zip: 2,912
5.0:        setup: 552      zip: 1,617
4.4.5       setup: 547   zip: 379  2007-12-11
4.4.4       setup: 856  zip: 539  2007-11-02
4.4.3.1     setup: 1092 zip: 743  2007-7-03
4.4.3       setup: 363  zip: 282  2007-6-26
4.4.2.1     setup: 2847 zip: 2044 2006-10-19
4.4.1.1     setup: 1041 zip: 813  2006-9-3
4.4         setup: 1318 zip: 1075 2006-5-11
3.3.3       setup: 1503 zip: 1145 2005-9-19
4.3.2 final setup: 409  zip: 222
4.3.1 final setup: 2168 zip: 1781
4.3 final   setup: 942  zip: 686
4.2.1 final setup: 413  zip: 490
4.2-final   setup: 1828 zip: 1508
4.2b3       setup: 563, zip: 338
4.1rc3      setup: 870  zip: 630
4.1 b5      setup: 195, zip: 128
4.0.4       setup: 340, zip: 385
4.0                     zip: 382
3.12        setup: 953  zip: 592
3.11                    zip: 102
3.10                    zip: 1193</t>
<t tx="EKR.20040519091259.2"></t>
<t tx="EKR.20040519091259.3">I like Leo more the more I use it...It's an unexpected pleasure to
see my (linearly written) code outlined in Leo. I can't wait to use
Leo to start a new project, going from outline to code...Thanks again
for providing the computing community with such a fine piece of
software. -- Jim Shapiro, Ph.D.

If you think you have used all possible programmer's editors, but
have not yet tried Leo, you are wrong...I rate Leo as a "must have"
for Python programmers. The code makes for a good read.
-- John Tobler  http://weblogs.asp.net/Jtobler/
</t>
<t tx="EKR.20040519091259.4">I've written documentation in WordPerfert, Ventura, Word, PageMaker, and
FrameMaker and even though they create wonderfully looking and useful
documents, they've never been able to do what I've been looking for. HTML,
compiled help files, and later PDF came closer, but still not there. I think
I've found it in LEO, a way to make a "living" document. A document built out
of discrete parts that can be re-organized on the fly to meet the needs of a
varying audience...Being a convert for less than a day I've still got a lot to
learn, but just the possibility of keeping system maintenance scripts in the IT
manual is mind boggling.  -- David Nichols dnichols@amci.com</t>
<t tx="ekr.20040630210818">HTML Editing in Leo is soooo much easier then with NoNodeEditors. Ive
had a blast working on a web page. Usually I had to look at a bunch of
gunk all at once. Now I can look at little pieces of gunk! :) 

-Anon (for now)

Before leo, I try to avoid or refactor long functions. With leo, I am
very tempted not to. Being able to view and slice my code at a higher
level in pretty much anyway I want, I feel like a commanding master in
my own mess...Leo lets me be lazy and get away with it. ;)

Mark Ng

[Quote] I have just finished a little embedded system for someone, written in
C using leo as the editor. I told the customer he _had_ to use leo for
ongoing maintenance, after I looked at one of the main state machines:
600 lines in the derived file, but trivialy easy to get your head
around in Leo...

The good news is that having been forced to meet leo he thinks it'll
solve many other problems that his company has with code maintenance.
Another step to world domination!

Leo allows you to do things that you'd never consider with another editor. 

BTW: in a real-time embedded system like I was working on, not having
the overhead of a function call (which you'd have had if you'd split
the case statement as you would with a normal editor) saves time, and
makes the system more flexible...
[End Quote]</t>
<t tx="ekr.20040828084148">Leo is the best IDE that I have had the pleasure to use. I have been using it
now for about 2 -- 3 months. It has totally changed not only the way that I
program, but also the way that I store and organise all of the information that
I need for the job that I do. -- Ian Mulvany</t>
<t tx="ekr.20050315084904"></t>
<t tx="ekr.20060213160806">"Thanks for a wonderful program – everybody should be using it! It blows the
socks off that Java Mind mapping software that won project of the month a while
back on sourceforge!" -- Derick van Niekerk.
</t>
<t tx="ekr.20060823090437">Thanks for creating the most useful and amazing application that
I've come across in years. I use Leo every day.</t>
<t tx="ekr.20070101093904">Leo is THE BEST THING to ever had happened to me. I've done in two
weeks what would have taken me years (not exaggerating!). Thanks Ed
for a terrific tool!!!!
 
Julian S. Fecteau 
</t>
<t tx="ekr.20070325123540"></t>
<t tx="ekr.20070425092712">Leo--especially with its feature of user-controllable outlining and
overview __has for the last 4-5 years had the greatest positive effect
on my overall programming quality of life than anything else out there
in the software world (apart maybe from the Python language itself,
and those who contribute Python modules to the world). -- David McNab
</t>
<t tx="ekr.20080901114425.2">For me Squeak and Leo have been two of the most significant technologies to
redefine my personal computer experience and the ideas behind computing.</t>
<t tx="ekr.20090901092556.1576">def genUninstallData(self,dirs,dirDict,filesDict):

    '''Generate the manifest-specific uninstall data.'''

    trace = True

    s = r'''
Section Uninstall

    DeleteRegKey HKEY_LOCAL_MACHINE "${hkey_local_machine}"

    ; Delete files &amp; directories only if we own them!
    ReadRegStr $$1 HKCR "${ext}" ""
    StrCmp $$1 "${name}File" 0 FinishUninstall

    ; Delete files &amp; directories only if there is no backup_val key.
    ReadRegStr $$1 HKCR "${ext}" "backup_val"
    StrCmp $$1 "" 0 DeleteLeoKeysAndFiles
      DeleteRegKey HKCR "${ext}"
    Goto FinishUninstall

DeleteLeoKeysAndFiles:
    WriteRegStr HKCR "${ext}" "" $$1
    DeleteRegValue HKCR "${ext}" "backup_val"

    ; ---- Start of manifest-related data...
'''

    self.put(s,substitute=True)

    # Does all the hard work.
    s = self.getUninstallVariableData(dirs,dirDict,filesDict)
    if trace: g.trace('\n',s)
    self.put(s,adjust = False)

    s = r'''
    ; ---- End of manifest related data.

FinishUninstall:
    ; MessageBox MB_YESNO|MB_ICONQUESTION \
    ;    "Delete all files in ${INSTDIR}?" IDNO NoDelete
; NoDelete:

  Delete "${SMPROGRAMS}\${name}\Uninstall.lnk"
  RMDir "${SMPROGRAMS}\${name}-${version}"
  Delete "${DESKTOP}\${name}.lnk"

  DeleteRegKey ${uninst_root_key} "${uninst_key}"
  SetAutoClose false

; end Uninstall section
SectionEnd
'''

    self.put(s,substitute=True)
</t>
<t tx="ekr.20090901121423.1567">def getUninstallVariableData(self,dirs,dirDict,filesDict):

    s1 = self.getDeleteFiles(dirs,dirDict,filesDict)
    s2 = self.getDeleteDirectories(dirs,dirDict)
    return '%s\n%s' % (s1,s2)
</t>
<t tx="ekr.20090901121423.1568">def getDeleteDirectories (self,dirs,dirDict):

    reverseDirs = dirs[:]
    reverseDirs.reverse()

    result = []

    if 1:
        result.append('; Recursively delete the leo directory and everything in it.\n')
        result.append('RMDir /r "$INSTDIR\\leo"\n\n')
    else:
        result.append('; Uninstall directories in reverse order\n')
        for theDir in reverseDirs:
            # Delete the directory even if it has files.
            if theDir and theDir != '**top':
                if not theDir.startswith('.bzr'):
                    result.append('RMDir "$INSTDIR\\%s"\n' % (
                        theDir.replace('/','\\')))

    # top-level folder.
    result.append('; Delete the top-level directory.\n')
    result.append('RMDir "$INSTDIR"\n')

    result = [self.indent(z) for z in result]
    return ''.join(result)
</t>
<t tx="ekr.20090901121423.1569">def getDeleteFiles (self,dirs,dirDict,filesDict):

    result = []
    result.append('\n')
    result.append('; Uninstall files...\n\n')

    # top-level files.
    result.append('; Delete top-level files...\n')
    aList = dirDict.get('**top',[])
    # Add *.py, *.pyo, *.pyc and *.leo, the most common added files.
    if 0: # This seems way too drastic, and not needed.
        for fn in ('*.py','*.pyo','*.pyc','*.leo',):
            aList.append(fn)
    # special case.
    aList.append('uninst.exe')
    # Warning: **never** delete all files in the top-level directory.
    for fn in aList:
        result.append('Delete "$INSTDIR\\%s"\n' % fn)

    if 0:
        wildcard_delete = True
        if wildcard_delete:
            result.append('\n')
        # Use the \r option to recursively delete everything in the leo directory.

        for theDir in dirs:
            if theDir:
                dir2 = theDir.replace('/','\\')
                if wildcard_delete:
                    result.append('Delete "$INSTDIR\\%s\\*.*"\n' % (dir2))
                else:
                    aList = dirDict.get(theDir,[])
                    if aList:
                        result.append('\n')
                        result.append('Delete "$INSTDIR\\%s\\*.pyc"\n' % (dir2))
                        result.append('Delete "$INSTDIR\\%s\\*.pyo"\n' % (dir2))
                    for fn in aList:
                        result.append('Delete "$INSTDIR\\%s\\%s"\n' % (
                            dir2,fn))

    result = [self.indent(z) for z in result]
    return ''.join(result)
</t>
<t tx="ekr.20090905082405.1487">import os
import shutil
import string
import struct
import subprocess
import sys
import time</t>
<t tx="ekr.20090905082405.1490">def unlink (self,fn):

    # print('command: unlink: %s' % fn)
    os.remove(fn)
</t>
<t tx="ekr.20100202061222.1494">@language rest

Pre-testing:
- Make sure no distributed .leo file contains xml-stylesheet elements.
- Make sure Leo looks good without myLeoSettings.leo.
- Run the "check-bindings" button in leoSettings.leo.
- Run all unit tests with *both* Python 2 and 3.
- Run pylint -a.

Update release notes and web documentation:
- Make sure copyright dates are correct.
- Update version numbers in html/conf.py
- Update the release notes.
- Remove @language rest where possible in new notes.
- Create new "what's new" section.
- Copy release notes to leoDist.leo.
- Update version number and modification date on Leo's home page.
  (The sphinx date is updated automatically.)
- Regenerate all .html files.
- Copy files to web, including leo/doc/html/index.html

LeoReleaseNotes.leo:
- Update release notes from LeoDocs.leo

LeoDocs.leo:
- Remove top-level clones.
- Spell check entire file.
- Select the readme node.

leoVersion.py:
- Update version constant.

LeoPyRef.leo and LeoPluginsRef.leo:
- Regenerate from corresponding local file.
- Remove top-level clones.

Post-testing:
- Run all unit tests.

LeoDist.leo:
- Make sure copyright dates are correct.
- Update version numbers: search leoDist.leo for ##version.
- Update readme.txt.
- Check readme.txt spelling.
- Check 'PKG-INFO.TXT'

Run pyinstaller:
- Delete leo-editor/dist and leo-editor/build folders first.
- Run pyinstaller2 launchLeo-unified.spec.
- Test it, then rerun it (so .pyo files are not part of the package)
- Compress the folder:
    - Windows: Leo_&lt;version&gt;_Win.zip.
    - Linux:   Leo_&lt;version&gt;_Linux_64_bit.tar.gz.

Run make-leo.
- Commit all files before running make-leo.
- Run make-leo button in leoDist.leo.
- Commit any changed files.

Create the executable installer:
- Double-click leo.nsi. (Run with makeNSIS.exe)

Test files in installed folder:
- Run all unit tests in the installed folder, with the installed Leo.
- Make sure the following open without errors:
    - leoPlugins.leo
    - leoPy.leo
    - LeoDocs.leo

Create a git tag **last**:
- Create a full (annotated) tag: git tag -a Leo_5.2 -m "commit message"
    - Do *not* use -f option!

Scan all folders &amp; files before uploading.

Create Release on SourceForge: http://sourceforge.net/projects/leo/

Announcements
- Update version number on Leo's wikipedia site:
  http://en.wikipedia.org/wiki/Leo_%28editor%29
  Edit with the 'Edit this page' *tab* (not a link)
- Update version number on web site.

1. Announce to SourceForge:  http://sourceforge.net/projects/leo/
   **Markdown accepted, so paste release notes in LeoDocs.leo.**.
   **Paste SourceForge announcement to leo-editor announcement &amp; blog post**.
2. Announce to leo-editor.
   **Paste source-forge announcement**.
3. Announce to Python-announce-list using email:
   mailto:python-announce-list@python.org
   **Paste source-forge or leo-editor announcement**.
  - Check it by visiting the archive:
  https://mail.python.org/pipermail/python-announce-list/
- Register Leo at http://www.python.org/pypi?:action=submit_form
- My blog: http://edreamleo.blogspot.com/
  **Paste source-forge or leo-editor announcement**.
  **To get HTML, just use html tab**.
- Twitter (point to my blog)
</t>
<t tx="ekr.20101025095431.1517">@language rest</t>
<t tx="ekr.20101025095431.1518">https://bugs.launchpad.net/leo-editor/+bug/514656
</t>
<t tx="ekr.20101026142031.1516">@nocolor-node

HKEY_CURRENT_USER\Software\Classes\Applications\python.exe
HKEY_CURRENT_USER\Software\Classes\Applications\python.exe\shell\open\command
    val = c:\Python26\python.exe %1
HKCU
HKEY_CURRENT_USER\Software\Classes\Applications\pythonw.exe
HKEY_CURRENT_USER\Software\Classes\Applications\pythonw.exe\shell\open\command
    val = c:\Python26\pythonw.exe %1

HKEY_CURRENT_USER\Software\Classes\Applications\py_auto_file\shell\open\command
    val = c:\Python26\python.exe %1
    
HKEY_CURRENT_USER\Software\Classes\Installer\Products\nnnnnn

HKLM
HKEY_LOCAL_MACHINE\SOFTWARE\Python
HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore
HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.7\InstallPath
    val = c:\python27\
HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonPath
    val = c:\Python27\Lib;\Python27\DLLs;C:\Python27\Lib\lib-tk
</t>
<t tx="ekr.20101027070126.1639"># Commit all files before running this script.

'''
Make all variable Leo distribution files::

    git-manifest.txt
    leo\dist\nsi-install-files.txt
    leo\dist\nsi-uninstall-files.txt
    leo.zip.

Copy these files from the leo\dist folder to the top-level folder::

    nsi-install-files.txt
    nsi-uninstall-files.txt
    nsi-boilerplate.txt
'''

version = '5.3-final' ##version
&lt;&lt; includes &gt;&gt;
&lt;&lt; define global paths and file names &gt;&gt;

@others

LeoMaker().run()
g.es_print('done') # '@button make-leo done')
</t>
<t tx="ekr.20101027070126.1643">class LeoMaker:

    '''A class to make Leo distribution files:

    git-manifest.txt.
    leo\dist\nsi-install-files.txt
    leo\dist\nsi-uninstall-files.txt
    leo.zip
    '''

    @others
</t>
<t tx="ekr.20101027070126.1662">def run (self):
    '''The top-level logic.'''
    g.cls()
    self.clean_spellpyx()
    self.make_manifest()
    files = self.clean_manifest()
    dirs = self.directoryList(rootDir)
        # Compute the list of all the directories.
    dirDict,filesDict = self.makeDicts(dirs,files)
        # Compute dictionaries of directories and files.
    errors = self.printMissing(files,dirDict,filesDict)
        # Print manifest lines not in either dict.
        # This is a crucial check.
    if not errors:
        self.create_install_files(dirs,dirDict,filesDict)
        self.create_uninstall_files(dirs,dirDict,filesDict)
        self.make_zip()
        self.copy_nsi_files()
</t>
<t tx="ekr.20101027070126.1663">def directoryList (self,rootDir):
    '''
    Compute a top-down list of all directories.
    These directories start at the top-level directory.
    '''
    trace = False
    ignoreDirs = ('.bzr','.git',)
    # Important: this adds all directories on EKR's machine,
    # regardless of whether they appear in the manifest!
    result = [] ; n = len(rootDir)
    for z in os.walk(rootDir): # top-down traversal.
        dirpath, dirnames, filenames = z
        assert dirpath.startswith(rootDir),z
        if len(dirpath) &gt; n:
            path = dirpath[n+1:].replace('\\','/')
            result.append(path)
    for z2 in ignoreDirs:
        result = [ z for z in result if not z.startswith(z2)]
    if trace:
        g.trace('-' * 40)
        g.trace(g.listToString(result))
    return result
</t>
<t tx="ekr.20101027070126.1664">def filterLines (self,lines):
    '''Filter lines from the input manifest file.'''
    trace = False
    # Remove blank lines, comments, and .pyc and .pyo files.
    lines = self.deleteBlankLines(lines)
    lines = self.deleteComments(lines)
    lines = self.deleteTempFiles(lines)
    lines = self.deleteExt(lines,'.pyc')
    lines = self.deleteExt(lines,'.pyo')
    lines = self.deleteExt(lines,'.zip') # Don't include the zip file.
    lines = self.deleteExt(lines,'.exe') # Don't include the installer.
    # Remove specific files.
    deleteList = (
        '.bzrignore',
        '.gitignore',
        # 'bzr-manifest.txt',
        'git-manifest.txt',
        # 'bzr-small-manifest.txt',
        # 'setup.py',
        'stand_alone_globals.leo',
        'leoStandAloneGlobals',
        'leo/test/unittest/.leo_shadow/',
        'nsi.log.txt', # Can't write log while we are creating it.
        'leo/core/leoPy.leo',
        'leo/core/ekrLeoPy.leo',
    )
    lines = self.deleteFiles(lines,deleteList)
    if trace:
        g.trace('=' * 40)
        g.trace(g.listToString(lines))
    return lines
</t>
<t tx="ekr.20101027070126.1665">def deleteBlankLines (self,lines):

    return [z.strip() for z in lines if z.strip()]

def deleteComments (self,lines):

    return [z for z in lines if not z.startswith('#')]

def deleteExt (self,lines,ext):

    return [z for z in lines if not z.endswith(ext)]

def deleteFiles (self,lines,deleteList):

    return [z for z in lines if not z in deleteList]

def deleteTempFiles (self,lines):

    for i in range(1,10):
        lines = [z for z in lines if not z.endswith('~%s~' % i)]
    return lines
</t>
<t tx="ekr.20101027070126.1666">def makeDicts (self,dirs,lines):

    trace = False ; verbose = True
    # Create the dirDict.
    # Keys are directories.
    # Values are files contained in each directory.
    dirDict = {}
    dirDict['**top'] = [] # Create an entry for the root directory.
    for z in dirs:
        dirDict[z] = []
    # Assign files to dirDict.
    for line in lines:
        line = line.strip().replace('\\','/')
        if line in dirDict.keys():
            path,fn = None,None
        elif line.startswith('leo/'):
            path,fn = g.os_path_split(line)
        else:
            path,fn = '**top',line.strip()
        # Don't include top-level leo directory,
        # Do include leo/scripts/leo file.
        if fn and (path != '**top**' or fn != 'leo'):
            aList = dirDict.get(path,[])
            assert line not in aList,repr(line)
            aList.append(fn)
            dirDict[path]=aList
    for theDir in sorted(dirDict):
        aList = dirDict.get(theDir)
        if aList and trace:
            if verbose:
                print() ; print(theDir)
                print(g.listToString(aList))
            else:
                print(theDir)
    # Create the inverse dict.
    filesDict = {}
    for theDir in sorted(dirDict):
        aList = dirDict.get(theDir)
        for fn in aList:
            path = g.choose(theDir=='**top',
                fn,'%s/%s' % (theDir,fn))
            filesDict[path] = theDir
            # if fn == 'wikiview.py': g.trace(fn,path)
    return dirDict,filesDict
</t>
<t tx="ekr.20101027070126.1667">def printMissing (self,files,dirDict,filesDict):
    '''A crucial check.'''
    errors = 0
    for fn in files:
        fn = fn.rstrip('/')
        if fn and fn not in dirDict and fn not in filesDict:
            g.es_print('missing',fn,color='red')
            errors += 1
    if errors:
        g.es_print('%s errors' % (errors),color='red')
    return errors
</t>
<t tx="ekr.20101027070126.1675">def create_install_files(self,dirs,dirDict,filesDict):
    '''Create leo/dist/nsi-install-files.txt'''
    global install_fn,rootDir
    put = self.put
    self.f = self.openFile(install_fn)
    if not self.f: return
    # Top level
    theDir = '**top'
    put('\n')
    put('; top-level\n')
    put('SetOutPath "$INSTDIR"\n')
    put('SetOverwrite ifnewer\n')
    aList = dirDict.get(theDir,[])
    for fn in aList:
        put('File "%s"\n' % fn)
    for theDir in dirs:
        if theDir != '**top':
            aList = dirDict.get(theDir,[])
            if aList:
                theDir2 = theDir.replace('/','\\').rstrip('\\')
                put('\n')
                put('SetOutPath $INSTDIR\\%s\n' % theDir2)
                for fn in aList:
                    # Fix bug 425369: quote file names.
                    put('File "%s\\%s\\%s"\n' % (
                        rootDir,theDir2,fn))
    self.f.close()
</t>
<t tx="ekr.20101027070126.1676">def create_uninstall_files(self,dirs,dirDict,filesDict):
    '''Create leo/dist/nsi-uninstall-files.txt'''
    def clean(s):
        return s.replace('/','\\')
    put = self.put
    self.f = self.openFile(uninstall_fn)
    if not self.f: return
    # Part 1: Delete top-level files.
    put('\n')
    put('; Uninstall files...\n\n')
    put('SetOutPath $Temp\n')
    # Get the list of top-level files.
    aList = dirDict.get('**top',[])
    # Add some special cases:
    for fn in ('*.pyo','*.pyc',
        'uninst.exe',
        # 'setup.py',
            # setup.py is now allowed at the top level.
        'git-manifest.txt'
    ):
        if fn not in aList:
            aList.append(fn)
    for fn in aList:
        # Always delete individual files.
        put('Delete "$INSTDIR\\%s"\n' % fn)
    if 1:
        # Just delete the leo folder with /r option.
        # This should be completely safe.
        put('RMDir /r "$INSTDIR\\leo"\n')
    else:
        # Part 2: Delete files in lower directories.
        for theDir in dirs:
            if theDir:
                dir2 = clean(theDir)
                aList = dirDict.get(theDir,[])
                if aList:
                    put('\n')
                    put('Delete "$INSTDIR\\%s\\*.pyc"\n' % (dir2))
                    put('Delete "$INSTDIR\\%s\\*.pyo"\n' % (dir2))
                    # Delete all files in any __pycache__ subdirectory.
                    put('Delete "$INSTDIR\\%s\\__pycache__\\*.pyc"\n' % (dir2))
                for fn in aList:
                    put('Delete "$INSTDIR\\%s\\%s"\n' % (dir2,fn))
        # Part 3: Delete directories.
        reverseDirs = dirs[:]
        reverseDirs.reverse()
        put('\n')
        put('; Uninstall directories in reverse order\n')
        for theDir in reverseDirs:
            # Delete the directory even if it has files.
            if theDir and theDir != '**top':
                if not theDir.startswith('.bzr'):
                    put('RMDir "$INSTDIR\\%s\\__pycache__"\n' % (clean(theDir)))
                    put('RMDir "$INSTDIR\\%s"\n' % (clean(theDir)))
    # Delete the op-level folder.
    put('\n')
    put('; Delete the top-level directory.\n')
    put('RMDir "$INSTDIR"\n')
        # Important: the /r option is not safe here!
    self.f.close()
</t>
<t tx="ekr.20101027070126.1678">def put (self,s):

    # g.trace(s.rstrip())
    self.f.write(s)
</t>
<t tx="ekr.20101027070126.1679">def openFile (self,fn,mode='w'):

    try:
        f = open(fn,mode)
        return f
    except IOError:
        g.error('can not open',fn)
        return None
</t>
<t tx="ekr.20101027070126.1680"></t>
<t tx="ekr.20101027131034.1490">@color</t>
<t tx="ekr.20101027135430.1492">http://nsis.sourceforge.net/Docs/Modern%20UI%202/Readme.html</t>
<t tx="ekr.20101027135430.1493">http://nsis.sourceforge.net/Docs/Chapter4.html#4.5</t>
<t tx="ekr.20101027160251.1497">http://nsis.sourceforge.net/Docs/nsDialogs/Readme.html</t>
<t tx="ekr.20101027160251.1500"></t>
<t tx="ekr.20101105103524.1491">def make_manifest(self):
    '''Create git-manifest.txt.'''
    os.chdir(rootDir) # Can't be done below.
    commands = (
        r'del git-manifest.txt',
        r'c:\apps\Git\bin\git.exe ls-files &gt; git-manifest.txt',
        # r'&amp;ed git-manifest.txt',
    )
    g.execute_shell_commands(commands,trace=True)
</t>
<t tx="ekr.20101105103524.1493">def make_zip(self):
    '''
    Create the zip file.
    
    The archive will not contain the .git directory, but will contain
    .gitignore, .gitattributes, etc. To suppress these files, use the
    export-ignore attribute in a .gitattributes file. Commit this before
    doing git archive.
    '''
    for z in (zipFile,zipFile2):
        if exists(z): self.unlink(z)
    os.chdir(rootDir) # Required.
    commands = (
        # This commit ensures the proper files are included in the distribution.
        # r'git commit -m "commit doc files during make"',
        ##version
        r'%s archive --format zip --output "%s" --prefix=Leo-5.3-final/ master' % (
            r'c:\apps\Git\bin\git.exe',zipFile),
    )
    g.execute_shell_commands(commands,trace=True)
    if not g.os_path_exists(zipFile):
        print('does not exist: %s' % zipFile)
    # Remove the temporary zip file.
    if exists(zipFile2):
        self.unlink(zipFile2)</t>
<t tx="ekr.20101105103524.1494">def clean_manifest(self):
    '''Create and filter the list of files from the manifest.'''
    f = open(manifest_fn)
    s = f.read()
    f.close()
    lines = g.splitLines(s)
    lines = self.filterLines(lines)
    # Write the file back.
    f = open(manifest_fn,'w')
    f.write('\n'.join(lines))
    f.close()
    return lines
</t>
<t tx="ekr.20101115090518.1494">Leo 4.8 final                               November 26, 2010

Leo 4.8 final is now available at:
http://sourceforge.net/projects/leo/files/

Leo is a text editor, data organizer, project manager and much more. See:
http://leoeditor.com/

The highlights of Leo 4.8:
--------------------------

- Leo now uses the simplest possible sentinel lines in external files.
  External files with sentinels now look like Emacs org-mode files.
- Leo Qt gui now supports Drag and Drop.
  This was one of the most frequently requested features.
- Improved abbreviation commands.
  You now define abbreviations in Leo settings nodes, not external files.
- @url nodes may contain url's in body text.
  This allows headlines to contain summaries: very useful.
- Leo now uses PyEnchant to check spelling.
- Leo can now open multiple files from the command line.
- Leo's ancient Tangle and Untangle commands are now deprecated.
  This will help newbies how to learn Leo.
- Leo now shows "Resurrected" and "Recovered" nodes.
  These protect data and show how data have changed.
  These fix several long-standing data-related problems.
- A new "screenshots" plugin for creating slide shows with Leo.
  I used this plugin to create Leo's introductory slide shows.
- Improved autocompletion: Ctrl-space starts a one-time completion.
- A better installer.
- Many bug fixes.

Links:
------
Leo:      http://leoeditor.com/
Forum:    http://groups.google.com/group/leo-editor
Download: http://sourceforge.net/project/showfiles.php?group_id=3458
Bzr:      http://code.launchpad.net/leo-editor/
Quotes:   http://leoeditor.com/testimonials.html
</t>
<t tx="ekr.20110603112852.1505">Leo 4.9 final              June 21, 2011

Leo 4.9 final is now available at:
http://sourceforge.net/projects/leo/files/

Leo is a text editor, data organizer, project manager and much more.
See: http://leoeditor.com/

The highlights of Leo 4.9:
--------------------------

- The Qt gui completely replaces the Tk gui--Qt gui now has all essential
  features of Tk, including plugins.

- Completed Leo's autocompleter.

- The rendering pane can now display movies, html, svg images, etc.

- The scrolledmessage plugin can now use the rendering pane.

- Nodes may contain multiple @language directives.

- Leo highlights URL's everywhere. Ctrl-click URL's opens them in your web
  browser. 

- Leo uses an @file node's extension by default if there is no @language
  directive in effect.
  
- Unified extract and import commands.

- Leo can now colorize multiple @language directives in a single node.

- Plain up/down arrow keys in headline-editing mode select a new node.

- New commands to insert, delete, change or print uA's.

- Added namespace directive to .leo files.

- Fixed many bugs, some important, most quite minor.

Links:
------
Leo:      http://leoeditor.com/
Forum:    http://groups.google.com/group/leo-editor
Download: http://sourceforge.net/projects/leo/files/
Bzr:      http://code.launchpad.net/leo-editor/
Quotes:   http://leoeditor.com/testimonials.html
</t>
<t tx="ekr.20110603171959.1506">def clean_spellpyx (self):
    '''Clean ekr-spellpyx.txt.'''
    fn = g.os_path_finalize_join(pluginsDir,'ekr-spellpyx.txt')
    if not g.os_path_exists(fn):
        return
    f = self.openFile(fn,mode='rb')
    s = f.read()
    f.close()
    s2 = s.replace(b'\r',b'')
    if s != s2:
        g.es_print('cleaning',fn)
        f = self.openFile(fn,mode='wb')
        f.write(s2)
        f.close()
</t>
<t tx="ekr.20110614062644.1378">def copy_ref_files (self):
    '''Copy reference copies of .leo files.'''
    if 0:
        # There seems to be no need for this.
        # Furthermore, this changes the ref files.
        table = (
            (pluginsDir,'leoGuiPlugins.leo','leoGuiPluginsRef.leo'),
            (pluginsDir,'leoPlugins.leo','leoPluginsRef.leo'),
            (coreDir,'leoPy.leo','leoPyRef.leo'),
        )
        for d,src,dst in table:
            src_path = join(d,src)
            dst_path = join(d,dst)
            if not exists(src_path):
                g.error('does not exist',src_path)
            if not exists(dst_path):
                g.error('does not exist',dst_path)
            if exists(src_path) and exists(dst_path):
                shutil.copyfile(src_path,dst_path)
</t>
<t tx="ekr.20110614062644.1379"># Globals...
abspath,exists,join = g.os_path_abspath,g.os_path_exists,g.os_path_join

# First.
# bzrRoot     = join('Lib','site-packages','Leo-%s' % (version))

    # Don't use abspath!
distDir     = abspath(join(g.app.loadDir,'..','dist'))
rootDir     = abspath(join(g.app.loadDir,'..','..')) # Same as top.
pluginsDir  = abspath(join(g.app.loadDir,'..','plugins'))

# Next.
coreDir =       abspath(join(g.app.loadDir,'..','core'))
docDir =        abspath(join(g.app.loadDir,'..','doc'))
manifest_fn =   abspath(join(rootDir,'git-manifest.txt'))
install_fn =    abspath(join(distDir,'nsi-install-files.txt')) # was distDir.
uninstall_fn =  abspath(join(distDir,'nsi-uninstall-files.txt')) # was distDir.
zipFile =       abspath(join(rootDir,'Leo-%s.zip' % (version)))
zipFile2 =      abspath(join(rootDir,'Leo-%s-temp.zip' % (version)))

# assert g.os_path_exists(manifest)</t>
<t tx="ekr.20120328150744.1791">Leo 4.10 final                                         March 29, 2012

Leo 4.10 final is now available at: http://sourceforge.net/projects/leo/files/

Leo is a text editor, data organizer, project manager and much more.
http://leoeditor.com/

Leo 4.10 contains 9 months of intense work on Leo. Several very important
features are subtle; you could almost call them Easter Eggs, so please read
the following notes carefully.

The highlights of Leo 4.10:
--------------------------

* Dozens of new and improved features and commands, including...
  - Tab completion now shows all @command &amp; @button nodes.
  - Leo tabs may be detached from the main window.
  - The Open With menu now works.
  - The leoInspect module answers questions about Python code.
  - Leo can highlight the pane containing the focus.
  - The bigdash plugin searches across multiple files.
  - Improved abbreviation capabilities.
  - Improved handling of URL's.
  - Improved editing of non-Leo files.
  - Improvements create "weightless" unit testing.
  - Improved Leo's home page.
* Easier installation on MacOS.
* Fixed almost 70 bugs.

The Easter Eggs
---------------

1. Tab completion now shows all @command &amp; @button nodes.

Put all your common scripts in @command nodes in myLeoSettings.leo.
Typing &lt;Alt-X&gt;@c&lt;Tab&gt; will remind you of the names of these scripts.
You can execute the scripts by name without the "@command-" prefix.

2. Improved abbreviation capabilities.

Virtually any kind of abbreviation is possible. For example, ~a to ã.

3. Improved handling of URL's.

URL's can be used as links to other Leo outlines.

4 Weightless unit testing.

The mantra is edit, alt-4 (run-marked-unit-tests-externally), edit,
alt-4,... Several seemingly innocuous changes made this work without
"friction". The result is a remarkable increase in productivity.

Links:
------
Leo:      http://leoeditor.com/
Forum:    http://groups.google.com/group/leo-editor
Download: http://sourceforge.net/projects/leo/files/
Bzr:      http://code.launchpad.net/leo-editor/
Quotes:   http://leoeditor.com/testimonials.html
</t>
<t tx="ekr.20130809141000.1990">@language rest
</t>
<t tx="ekr.20130809141000.1991">System requirements
-------------------

Leo requires the `Python`_ and `PyQt_` package.
The `PyEnchant`_ package is optional. 

**Python**: Leo will work on any platform that supports Python 2.6 or
above, including Python 3.0 and above. To install Python, see
http://python.org.

**PyQt**: PyQt provides Leo's widgets. To install PyQt, get the binary
package from: http://www.riverbankcomputing.co.uk/software/pyqt/download
The PyQt version must match your installed Python version. Remember that
Leo requires Python 2.6 or later, or Python 3.0 or later. Now run the
binary PyQt installer.

**PyEnchant**: You must install the PyEnchant package if you want to use
Leo's Spell tab. Download and install the PyEnchant package from
http://pythonhosted.org/pyenchant/download.html There is an executable
installer for Windows users.

</t>
<t tx="ekr.20130809141000.1992">
Leo's HOME directory
--------------------

Python's HOME environment variable specifies Leo's HOME directory.
See http://docs.python.org/lib/os-procinfo.html for details.

Leo puts several files in your HOME/.leo directory:
.leoID.txt, .leoRecentFiles.txt, and myLeoSettings.leo.
There are various fallback directories if there is no home directory.
</t>
<t tx="ekr.20130809141000.1993">
Installing Leo on Linux
-----------------------

You may download Leo's sources in one of three ways, as described at:
http://leoeditor.com/download.html If the sources are zipped, unzip them
into a folder in your home directory, say ~/leo-5.2 (or /usr/bin, etc.)

To gain access to Leo, you have two choices:

A. Add  ~/leo-5.2 to your path.
B. Create alias for Leo.

I prefer using aliases because they allow me to start Leo using Python 2 or 3,
or other distributions, like Anaconda 2 or 3.

See `Running Leo`_ for how to run Leo after installing it.
</t>
<t tx="ekr.20130809141000.1994">
Installing Leo on Windows
--------------------------

Install Python and Qt, as described above.

Now you have a choice.  You can use Leo's binary (single-click) installer
or download Leo's sources directly.

1. Using the single-click installer

Leo has a binary installer for Windows, available at
http://sourceforge.net/projects/leo/files/Leo/ The binary installer
installs Leo and sets Windows file associations.

2. Installing from sources

You may download Leo's sources in one of three ways, as described at:
http://leoeditor.com/download.html If the sources are zipped, unpack them
into a temp folder. You may place the sources anywhere you like, including
Python's *site-packages* folder, for example,
C:\Python26\Lib\site-packages.

</t>
<t tx="ekr.20130809141000.1995">
Running Leo
-----------

You can run Leo from a Python interpreter as follows::

    import leo
    leo.run() # runs Leo, opening a new outline or,
    leo.run(fileName=aFileName) # runs Leo, opening the given file name.

Another way to run Leo is as follows::

    cd &lt;path-to-launchLeo.py&gt;
    python launchLeo.py
</t>
<t tx="ekr.20130809141000.1996">
Creating File Associations
--------------------------

**Linux**

The following shell script will allow you to open foo.leo files by typing leo foo::

    #!/bin/sh 
    python &lt;leopath&gt;launchLeo.py $1

where &lt;leopath&gt; is the path to the directory *containing* the leo directory. 

**Windows**

*Important*: Leo's binary Windows installer sets file associations
automatically, so this section is needed only if you are installing Leo
from a .zip file or other sources.

There are two ways of associating .leo files with Leo. The first uses the
Windows control panel, the second, the Windows console.

**Method 1: Using the Windows Control Panel**

The goal is that you want to associate .leo files with the following command::

    "&lt;path to python&gt;\python.exe" "&lt;path to launchLeo.py&gt;\launchLeo.py" "%1"
    
Before Windows 7, you do this with using the Folder Options control panel.
In Windows 7, you do this with the Default Programs control panel.

*Note*: "%1" passes just the file being clicked on, quoted for spaces etc.
The quotation marks are needed to handle file paths containing spaces.

*Warning:* In a batch file, %1 passes just the first command line parameter.
It is logical to expect %* to work for file associations just as in batch
files. Alas, it does not.

**Method 2: Using the Windows Console**

Open a Windows console with administrator privileges, then type::

    ftype LeoFile="&lt;path to python&gt;\pythonw.exe" "&lt;path to launchLeo.py&gt;\launchLeo.py" "%1" %*
    assoc .leo=LeoFile

And put this leo.bat in %PATH%::

    @start /b "Leo" "&lt;path to python&gt;\python.exe" "&lt;path to launchLeo.py&gt;\launchLeo.py" %*
    
You may omit the /b option if you want to create a separate console window for Leo.
</t>
<t tx="ekr.20130809141000.1997">
Adding Leo to Your Path
-----------------------

After you have installed Leo, you should add the location of your leo/core folder to your python path.
One way to do this is adding something like the following to python/Lib/sitecustomize.py:

    import sys
    sys.path.append(r'&lt;path-to-leo&gt;leo\core')

Another way is to append &lt;path-to-leo&gt; to the Windows PYTHONPATH environment variable.
</t>
<t tx="ekr.20130809141000.1998">
Running Leo for the first time
------------------------------

The first time you start Leo, a dialog will ask you for a unique identifier. If
you are using cvs, use your cvs login name. Otherwise your initials will do. Leo
stores this identifier in the file ``.leoID.txt``. Leo attempts to create
``leoID.txt`` in the .leo sub-directory of your home directory, then in Leo's config directory, and
finally in Leo's core directory. You can change this identifier at any time by
editing ``.leoID.txt``.
</t>
<t tx="ekr.20131105110107.16636">Leo 4.11 final released: Python scripting IDE

Leo 4.11 final is now available at: http://sourceforge.net/projects/leo/files/Leo/
Leo 4.11 contains over a year's work on Leo.

Leo is a PIM, an IDE and an outliner for programmers, authors and web
designers. Leo's unique features organize data in a revolutionary way.
Python scripts can easily access all parts of Leo outlines.
See http://leoeditor.com/tutorial.html

The highlights of Leo 4.11:
---------------------------

- Leo's tutorials have been rewritten and simplified.
- Greatly improved abbreviations, including templates.
- Clones are now valid anywhere in @file nodes.
- Leo now warns if a .leo file is open elsewhere.
- Leo's IPython bridge now works with IPython 1.x.
- Added support for @testsetup and @testclass.
- Added support for sessions.
- Added colorizing themes.
- A colored border highlights the pane with focus.
- Added support for the clojure, markdown and TypeScript languages.
- Added importers for .ipynb, .otl and vimoutliner files.
- Many new and improved commands, plugins and scripts.
- Dozens of bug fixes and code-level improvements.

Links:
------
Leo:       http://leoeditor.com
Docs:      http://leoeditor.com/leo_toc.html
Tutorials: http://leoeditor.com/tutorial.html
Forum:     http://groups.google.com/group/leo-editor
Download:  http://sourceforge.net/projects/leo/files/
Bzr:       http://code.launchpad.net/leo-editor/
Quotes:    http://leoeditor.com/testimonials.html
</t>
<t tx="ekr.20141016105045.2119"># .gitattributes file for Leo distribution

# Commit this file after changing it!

.gitattributes                  export-ignore
.gitignore                      export-ignore
nsi.log.txt                     export-ignore

git-manifest.txt                export-ignore
MakeFile                        export-ignore
MANIFEST.in                     export-ignore

leoStandAloneGlobals.py         export-ignore
stand_alone_globals.leo         export-ignore
# setup.cfg                     export-ignore
# setup.py                      export-ignore

leo/core/leoPy.leo              export-ignore
leo/core/ekrLeoPy.leo           export-ignore
leo/test/unittest/.leo_shadow/  export-ignore
</t>
<t tx="ekr.20141016123713.2120">def copy_nsi_files(self):
    '''
    Copy these files from the leo\dist folder to the leo-editor folder::

        nsi-install-files.txt
        nsi-uninstall-files.txt
        nsi-boilerplate.txt
    '''
    names = (
        'nsi-install-files.txt',
        'nsi-uninstall-files.txt',
        'nsi-boilerplate.txt',
    )
    for fn in names:
        src = g.os_path_join(distDir,fn)
        dst = g.os_path_join(rootDir,fn)
        assert g.os_path_exists(src),src
        shutil.copyfile(src,dst)
</t>
<t tx="ekr.20141105082156.2">Leo 5.0 final                       November 24, 2014

Leo 5.0-final is now available at:
http://sourceforge.net/projects/leo/files/Leo/

This release fixes several installation issues
and updates installation instructions for Linux/Ubuntu.

Leo is a PIM, an IDE and an outliner.
Video tutorials: http://leoeditor.com/screencasts.html
Text tutorials: http://leoeditor.com/tutorial.html

The highlights of Leo 5.0
--------------------------

* Better compatibility with vim, Emacs, pylint and PyQt:
    - Optional native emulation of vim commands.
    - Full support for Emacs org-mode outlines.
    - Full support for Vim .otl outlines.
    - Better support for pylint.
    - Support for both PyQt4 and PyQt5.
* Smoother installation:
    - Support for brew install leo on MacOS.
    - 'python setup.py install' now works.
    - pip install leo now works.
    - Leo is now a debian package.
* Better handling of nodes containing large text:
    - Idle time syntax coloring eliminates delay.
    - Optional delayed loading of large text.
* Power features:
    - Command history for minibuffer commands.
    - Leo available via github repository.
    - File name completion.
    - Cloned nodes expand and contract independently.
    - @data nodes can be composed from descendant nodes.
    - No need to change Leo's main style sheet:
      it can be customized with @color and @font settings.
    - @persistence nodes save data in @auto trees.
    - A pluggable architecture for @auto nodes.
    - The style-reload command changes Leo's appearance instantly.
* Important new plugins for tagging, display and node evaluation.
* For beginners:
    - Leo's default workbook files contains Leo's quickstart guide.
* Hundreds of new/improved features and bug fixes.

Links:
------
Leo:       http://leoeditor.com
Docs:      http://leoeditor.com/leo_toc.html
Tutorials: http://leoeditor.com/tutorial.html
Videos:    http://leoeditor.com/screencasts.html
Forum:     http://groups.google.com/group/leo-editor
Download:  http://sourceforge.net/projects/leo/files/
Github:    https://github.com/leo-editor/leo-editor
Quotes:    http://leoeditor.com/testimonials.html
</t>
<t tx="ekr.20141117135127.2"></t>
<t tx="ekr.20141117135127.3"></t>
<t tx="ekr.20141118074110.2">@language rest

https://groups.google.com/d/msg/leo-editor/Mm0hFBIR81Q/0v217II0kPIJ

Here's my workflow (written here as a script, but really done in fits and
starts):

:: checkout tagged release &amp; build package
pushd b:\apps\leo-editor
git checkout tags/Leo-5.0-final
python setup.py sdist
popd

:: install from built package
pip uninstall leo
pip install  b:\apps\dist\leo-5.0-final.zip

:: verify Leo works as expected
D:\&gt;which leoc
B:\o4w\apps\Python27\Scripts\leoc.EXE

D:\&gt;leoc --version
Leo 5.0-final, build 20141117141110, Mon Nov 17 14:11:10 CST 2014

D:\&gt;leoc

** isPython3: False
Leo 5.0-final, build 20141117141110, Mon Nov 17 14:11:10 CST 2014
Not running from a git repo
Python 2.7.4, PyQt version 4.7.1
Windows 7 AMD64 (build 6.1.7601) SP1
leoID=maphew (in C:\Users\mhwilkie\dropbox\.leo)
reading settings in B:\o4w\apps\Python27\lib\site-packages\leo\config\leoSettings.leo
reading settings in C:\Users\mhwilkie\dropbox\.leo\myLeoSettings.leo
reading settings in C:\Users\mhwilkie\dropbox\.leo\workbook.leo
...snip...
wrote recent file: C:\Users\mhwilkie\dropbox\.leo\.leoRecentFiles.txt

:: rebuild package and upload
pushd b:\apps\leo-editor
python setup.py sdist upload
popd

:: inspect public page for problems
start https://pypi.python.org/pypi/leo

:: verbosely install from pypi.org
pip uninstall leo
pip -v install -pre leo

:: repeat verify run leo works.

https://groups.google.com/d/msg/leo-editor/Mm0hFBIR81Q/67p7y-x1zLAJ

&gt; python setup.py sdist upload

This is the tricky part, there's a bunch of prep-work that's hidden,
involving getting a properly formatted ~/.pypirc. It looks very
straightforward, according to docs, but in practice I've found devilishly
difficult. There are bugs lurking in distutils/setuptools/something. I've
had my .pypirc mangled by "register" and had to rebuild manually. Anyway:

Step 1:
python setup.py register

and answer wizard steps, you'll need your pypi user and pass handy.
DO save at end.

Step 2: manually edit %HOME%\.pypirc and make sure it resembles below.
**Do not** use https.

Step 3: the commands in previous message (`python setup.py sdist upload`)

Here's my .pypirc:

[distutils]
index-servers =
    pypi
    testpypi

[pypi]
repository: http://pypi.python.org/pypi
username: {{omitted}}
password: {{omitted}}

[testpypi]
repository: http://testpypi.python.org/pypi
username: {{omitted}}
password: {{omitted}}

It really is a horrible system. The user and pass are sent in clear text. I
don't know what's taking them so long to use SSH keys or OpenID or..., but
frankly it's to Python's detriment. I hope they get it sorted out sooner
than later.


</t>
<t tx="ekr.20141118074110.3">https://groups.google.com/forum/#!topic/leo-editor/VvnDYjV4aIk</t>
<t tx="ekr.20141118074110.4"></t>
<t tx="ekr.20150326055410.1">@language rest

1. Search for ##version

    **Note**: The final version in PKG-INFO.TXT must be called 5.x, not 5.x-final.
    See Pep 440: https://www.python.org/dev/peps/pep-0440/

2. Search for copyright

    Latest copyright date: 2016.

    Note: install.txt file embeds a copyright message in the nsi installer.</t>
<t tx="ekr.20150415145711.1">April 16, 2015

[Leo](http://leoeditor.com/) 5.1 final is now available [at SourceForge.](http://sourceforge.net/projects/leo/files/Leo/) Leo is a PIM, an IDE and an outliner.

Leo 5.1-final is recommended for anyone using Leo 5.1 b1 or Leo 5.0-final.

**The highlights of Leo 5.1**

This release features **@clean** trees, one of the most important developments in Leo's history.

@clean nodes create external files without sentinel comments, yet Leo can update @clean trees from changes made to the corresponding external files, something long thought impossible. @clean trees preserve clone links and user attributes (uA's). Reading @clean trees is faster than reading @auto or @shadow trees. Steve Zatz [explains why @clean changes everything.](http://leoeditor.com/testimonials.html#steve-zatz-explains-why-clean-changes-everything)

**More highlights**
 
* A new [web page](http://leoeditor.com/load-leo.html) displays .leo files in the browser.
  
* Added **command history** to Leo's minibuffer.

* A new IdleTime class greatly simplifies idle-time handling.

* Leo now honors @language inside @doc parts

* @data nodes can be composed of their descendant nodes.

* @shadow is now deprecated. @clean is superior to @shadow in all respects. 

**Links**

The [Mulder/Ream algorithm](http://leoeditor.com/appendices.html#the-mulder-ream-update-algorithm) updates @clean trees from changes made in the corresponding external files. 

[Leo's home page](http://leoeditor.com)
[Documentation](http://leoeditor.com/leo_toc.html)
[Tutorials](http://leoeditor.com/tutorial.html)
[Video tutorials](http://leoeditor.com/screencasts.html)
[Forum](http://groups.google.com/group/leo-editor)
[Download](http://sourceforge.net/projects/leo/files/)
[Leo on Github](https://github.com/leo-editor/leo-editor)
[What people are saying about Leo](http://leoeditor.com/testimonials.html)
[A web page that displays .leo files](http://leoeditor.com/load-leo.html)
[More links](http://leoeditor.com/leoLinks.html)
</t>
<t tx="ekr.20150416081546.1"></t>
<t tx="ekr.20150416081546.2">import glob

@others

verbose = False

# extraFiles = ('..\\install','..\\uninstall','test\\unittest\\perfectImport\\formatter.py',)
extraFiles = () # 'test\\test-line-ending.py',)

baseDir = g.os_path_abspath(g.os_path_join(g.app.loadDir,'..'))
n = 0
dirs = ('','src','scripts','plugins',)
# dirs = ('src',)

if 1:
    for dir2 in dirs:
        theDir = g.os_path_abspath(g.os_path_join(baseDir,dir2))
        print theDir
        files1 = glob.glob('%s\*.py' % theDir)
        files2 = glob.glob('%s\*.leo' % theDir)
        files = files1
        files.extend(files2)
        for name in files:
            f = file(name)
            lines = f.readlines()
            # print '%5d %s' % (len(lines),name)
            f.close()
            check(name,lines)
            n += 1

for z in extraFiles:
    name = g.os_path_abspath(g.os_path_join(baseDir,z))
    f = file(name)
    lines = f.readlines()
    # print '%5d %s' % (len(lines),name)
    f.close()
    check(name,lines)
    n += 1

print 'done.  checked %d files' % (n)
</t>
<t tx="ekr.20150416081546.3">def check(name,lines):

    cr = 0 ; nl = 0

    for s in lines:
       for ch in s:
        if ch == '\r': cr += 1
        if ch == '\n': nl += 1

    if verbose or cr &gt; 0:
        print "%55s %s cr's %4s nl's" % (name,cr,nl)
</t>
<t tx="ekr.20150416081546.4">import glob

@others

baseDir = g.os_path_abspath(g.os_path_join(g.app.loadDir,'..'))
n = 0
for dir2 in ('','src','scripts','plugins',):

    theDir = g.os_path_abspath(g.os_path_join(baseDir,dir2))
    print theDir
    files = glob.glob('%s\*.py' % theDir)
    for name in files:
        f = file(name)
        lines = f.readlines()
        # print '%5d %s' % (len(lines),name)
        f.close()
        check(name,lines)
        n += 1

print 'done.  checked %d files' % (n)
</t>
<t tx="ekr.20150416081546.5">def check(name,lines):

    n = 0
    for line in lines:
        n += 1
        i = g.skip_ws(line,0)
        lws = line[0:i]
        if lws:
            if lws.find(' ') &gt; -1 and lws.find('\t') &gt; -1:
                print '%20s %5d %s' % (name,n,repr(line))
</t>
<t tx="ekr.20150416081546.6">import glob
pattern = g.os_path_finalize_join(g.app.loadDir,'..','modes','*.py')
for fn in glob.glob(pattern):
    sfn = g.shortFileName(fn)
    f = open(fn)
    s = f.read()
    f.close()
    if s.find(r'regexp="\\') &gt; -1:
        g.es(sfn)

@ found: Rules indicated are dubious or broken

md.py:
    [ \t]   leadins: 8,20,24,25(?),50,51
    space   leadins: 23,46,49
    [=-]    leadins: 21,47
    [\\_]   leadins: 54,55
    #       leadins: 22
    other   leadins: 7,12,19,53

moin.py:
    [ \t]           rule 3.
    single-quote    rule 6.

erlang.py:  no obvious problem.
lilypond.py:no obvious problem.
perl.py:    no obvious problem.
pl1.py:     no obvious problm.
rest.py:    no obvious problem.
rtf.py:     no obvious problem.
scala.py:   no obvious problem.
yaml.py:    fixed</t>
<t tx="ekr.20150416081546.7">'''
Regularize newlines in ekr-spellpyx.txt.

Replaces sorts the file, removes duplicate lines and ensuring a trailing newline.
'''
fn = g.os_path_finalize_join(g.app.loadDir,'..','..','ekr-spellpyx.txt')
with open(fn) as f:
    s = ''.join(sorted(set(g.splitLines(f.read().strip()+'\n'))))
with open(fn,'w') as f:
    f.write(s)
</t>
<t tx="ekr.20150416081546.8">@first

"""
A simple script to install Leo on Linux.

Contributed by David McNab &lt;david@rebirthing.co.nz&gt;
"""

import commands,os,sys # commands module is for Unix only.

# We must be root to use this script.
if os.getuid() != 0:
    print "You need to run this install script as root"
    sys.exit(1)

# Create /usr/lib/leo and copy all files there.
print "***** Installing Leo to /usr/lib/leo..."
commands.getoutput("mkdir -p /usr/lib/leo")
commands.getoutput("cp -rp * /usr/lib/leo")

# Create user's 'leo' command script into /usr/bin/leo
print "***** Creating Leo startup script -&gt; /usr/bin/leo"
fd = open("/usr/bin/leo", "w")
fd.write("""#!/usr/bin/python
import commands,sys
files = " ".join(sys.argv[1:])
print commands.getoutput("python /usr/lib/leo/leo.py %s" % files)
""")
fd.close()
commands.getoutput("chmod 755 /usr/bin/leo")
print "***** Leo installed successfully - type 'leo filename.leo' to use it."
</t>
<t tx="ekr.20150416081546.9">@language python

# This script must be run from leoPy.leo.

'''Warn if leoProjects.txt or leoToDo.txt contain any clones.'''

clones,nodes,seen = 0,0,set()
table = (
  '@file ../doc/leoProjects.txt',
  '@file ../doc/leoToDo.txt',
)

def check_clone(c,p0,root):
    '''Warn if p appears in any @&lt;file&gt; node outside of root's tree.'''
    global nodes,seen
    v = p0.v
    for p in c.all_positions():
        nodes += 1
        if p.v == v:
            # Check *all* ancestors, not just the nearest one.
            for parent in p.self_and_parents():
                nodes += 1
                if parent.isAnyAtFileNode() and parent.v != root.v:
                    if parent.v not in seen:
                        seen.add(parent.v)
                        g.es_print('%s and %s contain clone: %s' % (
                            root.h,parent.h,p0.h))

for h in table:
    root = g.findNodeAnywhere(c,h)
    if root:
        for p in root.self_and_subtree():
            nodes += 1
            if p.isCloned():
                clones += 1
                check_clone(c,p,root)
    else:
        g.es_print('not found',h,color='red')
print('done: %s nodes, %s clones' % (nodes,clones))
</t>
<t tx="ekr.20150425135153.1">@language ruby
@tabwidth -2
</t>
<t tx="ekr.20150425135153.2">class Leo &lt; Formula

  homepage "http://leoeditor.com/"
  url "http://sourceforge.net/projects/leo/files/Leo/5.0-final/Leo-5.0-final.zip"
  sha256 "2d742f9825959ba5c7624d1179b9f3065e14e055c90272fbce199f91770de826"
  head "https://github.com/leo-editor/leo-editor", :using =&gt; :git

  depends_on "pyqt"
  depends_on "enchant" =&gt; :recommended
  depends_on :python if MacOS.version &lt;= :snow_leopard

  def install
    (lib+"python2.7/site-packages").install "leo"
    bin.install "launchLeo.py" =&gt; "leo" 
  end

  test do
    system bin/"python", "-c", "import leo"
  end
end
</t>
<t tx="ekr.20151227063335.1">leo.exe contains everything you need to run Leo on Windows without
installing *anything* else. It contains all needed libraries, including
Python itself, PyQt, pylint and other packages. It also contains many data
files, including Leo's source code and various .leo files.

Notes:

1. leo.exe was created by PyInstaller: http://pythonhosted.org/PyInstaller

2. Before Leo starts, PyInstaller unpacks all libraries and data files to a
   temp folder: ~\AppData\Local\Temp\_MEInnn. As a result, starting leo.exe
   is slower than usual.

3. *Warning*: You can open Leo files from the "Files:Open Leo File" menu,
   but these files will be in the temp folder. They will be *destroyed*
   when you exit leo.exe. If you want to do real work with Leo you must
   create .leo files in a permanent folder on your machine.
</t>
<t tx="ekr.20160314155002.1">Leo 5.2-final, March 18, 2016

[Leo](http://leoeditor.com/) 5.2-final is now available on [SourceForge](http://sourceforge.net/projects/leo/files/Leo/). Leo is a PIM, an IDE and an outliner.

**The highlights of Leo 5.2**

- Easy install with PyInstaller packaging
- c.cloneFindByPredicate
- clone-find-marked commands
- decorators create all Leo commands
- find-def and find-var
- help-for-keystroke
- The --ipyhon command-line option works with latest IPython versions
- Optional line numbers in the body pane
- show-invisibles uses Qt characters
- Themes
- Wildcard file names on Leo's command line

**Links**

[Leo's home page](http://leoeditor.com)
[Documentation](http://leoeditor.com/leo_toc.html)
[Tutorials](http://leoeditor.com/tutorial.html)
[Video tutorials](http://leoeditor.com/screencasts.html)
[Forum](http://groups.google.com/group/leo-editor)
[Download](http://sourceforge.net/projects/leo/files/)
[Leo on Github](https://github.com/leo-editor/leo-editor)
[What people are saying about Leo](http://leoeditor.com/testimonials.html)
[A web page that displays .leo files](http://leoeditor.com/load-leo.html)
[More links](http://leoeditor.com/leoLinks.html)
</t>
<t tx="ekr.20160314155002.10">https://github.com/leo-editor/leo-editor/issues/182

Added g.splitLongFileName and called it from several file dialogs.
</t>
<t tx="ekr.20160314155002.11">https://github.com/leo-editor/leo-editor/issues/193

The fix was in GoToLineNumber.go: it must test for p.isAtCleanNode()
</t>
<t tx="ekr.20160314155002.12">https://github.com/leo-editor/leo-editor/issues/195

1. p.textOffset returns None if no @&lt;file&gt; node is an ancestor.
2. p.textOffset never caches its result.
    In any case, it was quite wrong to cache results in positions.
3. Rewrote p.textOffset to simplify it.
4. QtStatusLineClass.update prints '' for fcol if p.textOffset returns None.
5. Changed unit tests accordingly.
</t>
<t tx="ekr.20160314155002.13">https://github.com/leo-editor/leo-editor/issues/196

The fix was to use setBackground instead of setBackgroundColor.
No real testing was done.
</t>
<t tx="ekr.20160314155002.14">https://github.com/leo-editor/leo-editor/issues/198
</t>
<t tx="ekr.20160314155002.15">https://github.com/leo-editor/leo-editor/issues/199

Leo now warns in the log pane and raises a summary dialog about possibly already-open files.  However, all files are opened as usual, leaving it to the user to determine what to do.

A (new?) bug *won't* be fixed.  Closing a file removes the file's entry from g.app.db, so reopening the file *again* won't give another warning.  This is a very minor matter.

What I did: (See app.Detecting already-open files)

- Added g.app.already_open_files list.
- Added calls to new runAlreadyOpenDialog method in c.open and LM.doPostPluginsInit.
- Rewrote app.checkForOpenFile.
</t>
<t tx="ekr.20160314155002.16">https://github.com/leo-editor/leo-editor/issues/200

- Added leo.commands.gotoCommands module.
- Removed almost all old code.
- Added goto.get_external_file_with_sentinels.
  This returns the external file *with* sentinels, even if
  it normally does not have sentinels.
- Added goto.scan_nonsentinel_lines &amp; goto.scan_sentinel_lines.
  These contain the essential algorithms.
- Added code to force any particular write to use sentinels.
</t>
<t tx="ekr.20160314155002.17">https://github.com/leo-editor/leo-editor/issues/211
</t>
<t tx="ekr.20160314155002.18">https://github.com/leo-editor/leo-editor/issues/213

The fix was so simple: just use default arguments to connect_qtconsole.

The preliminaries were at least as important as the fix itself:

1. Modernized the imports, removing support for legacy imports. Imo, it would be unwise to support ancient code now.

2. Added logging methods. This makes it possible to understand and debug the code in leoIPython.py. Furthermore...

3. Leo's --debug option enables more verbose IPython logging. This is a feature that reveals the workings of the Jupyter kernel.
</t>
<t tx="ekr.20160314155002.19">https://github.com/leo-editor/leo-editor/issues/215
</t>
<t tx="ekr.20160314155002.2">- c.cloneFindByPredicate
- clone-find-marked commands:
  cfam (clone-find-all-marked)
  cffm (clone-find-all-flattened-marked)
- decorators create all Leo commands
- declutter headlines: icons replace @file, @clean, etc.
- find-def and find-var
- help-for-keystroke
- Optional line numbers in the left gutter
- show-invisibles uses Qt characters
- The --ipyhon command-line option works with latest IPython versions
- Themes
- Wildcard file names on Leo's command line
</t>
<t tx="ekr.20160314155002.20">https://github.com/leo-editor/leo-editor/issues/217
</t>
<t tx="ekr.20160314155002.21">https://github.com/leo-editor/leo-editor/issues/218

Here's a shell script you can run in a console

https://gist.github.com/tbnorth/4b781ba2b8f59c83dd5e

to show the content of the primary and secondary selections, and the
clip-board.  You'll probably need to install xclip

When the mouse is released after drag-selecting text in Leo, the
primary selection updates as expected.  This doesn't happen with
shift-arrow selection.

It looks like keyboard shift-arrow selection should call
QClipboard::setText(const QString &amp; text, Mode mode = QClipboard::Selection)
</t>
<t tx="ekr.20160314155002.22">https://github.com/leo-editor/leo-editor/issues/220

Executing clone-to-at-spot with an @spot node selected causes Leo to become
unresponsive and python process slowly eats up all system memory.
</t>
<t tx="ekr.20160314155002.23">https://github.com/leo-editor/leo-editor/issues/224

The fix was in c.checkGnxs
</t>
<t tx="ekr.20160314155002.24">https://github.com/leo-editor/leo-editor/issues/234
</t>
<t tx="ekr.20160314155002.25">https://github.com/leo-editor/leo-editor/issues/239
</t>
<t tx="ekr.20160314155002.26">Using c.tab_width is wrong: it is the *default* tab width.

Created c.getTabWidth()
</t>
<t tx="ekr.20160314155002.27">Rev 645b4ec2f9. Here is the checkin log:

Fixed a bug in p.__eq__, introduced at rev d0dd25b7b (2015-11-14 18:37:06).

p.__eq__ must *not* return NotImplemented when p2 is None.
</t>
<t tx="ekr.20160314155002.28">The fixes were in abbrev.expandAbbrev and helpers.

Rev 585d2f4 improves abbreviations as follows:

- Match longest prefix first: e;; no longer interferes with date;;
- Predefine 'x' as the empty string before executing abbreviation scripts.
- Split @data abbreviations-subst-env into separate nodes.
- Defined do() and insert() functions in @data abbreviations-subst-env as follows::

**Note**:  Because of a glitch in how abbreviations scripts are created, this won't work::

    do(['command1','command2'])

even though c.k.simulateCommand allows list arguments.  Instead, do this::

    do('command1');do('command2');

The following abbreviations insert matching characters (no need to do x='' in them)::

    (={|{insert('()');do('back-char')}|}
    [={|{insert('[]');do('back-char')}|}
    {={|{insert('{}');do('back-char')}|}

This is an implementation of auto-close-quotes, done entirely with abbreviations! For example, typing '(' inserts '()' and puts the cursor between the parens.

I personally dislike these abbreviations.  I find it harder to skip past the ')' than to type it later.  ymmv.
</t>
<t tx="ekr.20160314155002.29"></t>
<t tx="ekr.20160314155002.3"></t>
<t tx="ekr.20160314155002.30">https://groups.google.com/d/msg/leo-editor/tA5Q2YrEu-w/9mzqFAHMcX4J

The fix was in find.changeSelection.
</t>
<t tx="ekr.20160314155002.31">Rev a7e2e86 fixes atFile.create.
</t>
<t tx="ekr.20160314155002.32">It now works when there is no text selection.
</t>
<t tx="ekr.20160314155002.33">Ctrl-LtArrow and Ctrl-RtArrow leave the cursor at the start of a word.
This is the way most editors work.

The fix was in moveWordHelper.
</t>
<t tx="ekr.20160314155002.34">Leo acts on some operator input when the Leo window is NOT the top window
https://github.com/leo-editor/leo-editor/issues/153

This problem is discussed in the Leo-Editor forum thread:
https://groups.google.com/forum/?fromgroups#!topic/leo-editor/3PPObn4JRik

I can't reliably reproduce this problem, so I can't give you a test case that demonstrates it.

The symptom that I first noticed was unexpected, unpredictable changes in what the tree pane showed when I switched back to Leo-Editor after switching away from Leo-Editor by executing open-url.

Sometimes the node selected was unchanged, but it had been scrolled up in the tree pane; and sometimes it had been scrolled all the way out of the tree pane.

Sometimes the node selected had been changed to a sibling node after the node that was selected when I switched away from Leo-Editor.

In all cases, the body pane correctly showed the contents of the currently selected node.

Sometimes an Alt-F4 when a non-Leo-Editor window is the only window showing, causes Leo-Editor to exit or display its "Save changes before exit?" query.

Edward K. Ream currently believes: "The culprit is likely a delayed action (on the order of 0.5 sec) that Leo takes on focus-in events. If the user responds to a focus-in event before that time there will be problems."

My test system:

Xubuntu32 12.04
Python 2.7.3, PyQt version 4.8.1

The problem has been observed on Leo-Editor commit f6cdb2b. It seems to occur slightly more frequently on more recent commits such as 42a5207.
</t>
<t tx="ekr.20160314155002.35">https://github.com/leo-editor/leo-editor/issues/188

This bug appears to be invalid.
</t>
<t tx="ekr.20160314155002.36">https://github.com/leo-editor/leo-editor/issues/188

Rev e8b134:

Improved reporting of find options.  The report now shows suboutline-only and node-only.
- Just after Ctrl-F the status line contains:

    Find (wixbhacf[esn]): &lt;list of options&gt;

- When the command completes, the status line contains:

    found/not found (&lt;list of options&gt;): &lt;find pattern&gt;

This makes it much easier to see what is going on.

I suspect that #188 is invalid.  These changes will reduce confusion.
</t>
<t tx="ekr.20160314155002.37">https://github.com/leo-editor/leo-editor/issues/232

Appears invalid: only happens on 5.1 final.
</t>
<t tx="ekr.20160314155002.38">The orphan bit was set in @file leoGlobals.py. This prevented the file from
being updated.

Changed:
- at.read.
- at.readAll
- fc.putVnode no longer writes orphan bits.
- Removed warning in at.read about orphan bits.
</t>
<t tx="ekr.20160314155002.39"></t>
<t tx="ekr.20160314155002.4">https://github.com/leo-editor/leo-editor/issues/131

The fix was to replace:

    w = self.editWidget()

by:

    w = c.frame.tree.edit_widget(p)

in editCommands.insertHeadlineTime.
</t>
<t tx="ekr.20160314155002.40">​Recent revs add the following new position methods:

- p.is_at_all():  True if p is an @&lt;file&gt; node containing an @all directive.
- p.in_at_all(): True if p is in an @&lt;file&gt; tree whose root contains @all.
- p.is_at_ignore(): True if p is an @ignore node
- p.in_at_ignore_tree(): True if p is in an @ignore tree.

These predicates make it easy to create other predicates that skip @ignore trees or @&lt;file&gt; trees containing @all.  cffm and cfam do not skip such trees, on the theory that one would typically unmark nodes first before marking nodes to be cloned.

So here is how to gather only those marked nodes that lie outside any @ignore tree:

    def isMarked(p):
        return p.isMarked() and not p.in_at_ignore_tree()

    self.cloneFindByPredicate(
        generator = self.all_unique_positions,
        predicate = isMarked,
        flatten = flatten,
        undoType = 'gather-marked')
</t>
<t tx="ekr.20160314155002.41">Useful for per-file backups.
</t>
<t tx="ekr.20160314155002.42">Traverses the tree given using the generator, cloning all positions for which predicate(p) is True. Undoably moves all clones to a new node, created as the last top-level node.
</t>
<t tx="ekr.20160314155002.43">April 15, 2015

Rev 419a82d changes several aspects of how Leo handles the so-called orphan bit in vnodes.  These are major changes, but I believe they will be for the best.

The orphan bit indicates that there was a problem writing an @&lt;file&gt; node.  It will be set, for example, when an @file node contains children but has no @others directive.  Leo simply cannot write the external file in that case.

However, Leo went overboard with the error logic. Here are the recent changes:

1. Leo no longer writes the orphan bit ('O' bit in vnode attr) in .leo files. This kind of persistent error bit seems unwise.

2. Leo clears the bit and issues a warning when reading a vnode with the 'O' attr.

Previously, Leo would refuse to update the outline from the external file if the orphan bit was set! 

This change could have unforeseen consequences, but I suspect nobody will ever notice.  The foreseen consequence is that Leo will keep the outline and external files in sync more often.
</t>
<t tx="ekr.20160314155002.44">- Defined all commands in leoPlugins.leo with @g.command.

- Eliminate the "cmd_" convention. The g.command decorator now sets func.is_command and func.command_name. Plugin.create_menu is now much simpler.
  
- All decorated commands now use the "event" arg:

    @g.command('command-name')
    def my_command(event=None):
        ...

    @cmd('command-name')
    def my_command(self,event=None):
        ...
</t>
<t tx="ekr.20160314155002.45">This function was a bad idea and was never used.

</t>
<t tx="ekr.20160314155002.46">The leo/commands directory contains the new code.
</t>
<t tx="ekr.20160314155002.47"></t>
<t tx="ekr.20160314155002.48">Examined c.p and c.currentPosition.
</t>
<t tx="ekr.20160314155002.49"></t>
<t tx="ekr.20160314155002.5">Revised some of the code, but probably more work is needed.
</t>
<t tx="ekr.20160314155002.50"></t>
<t tx="ekr.20160314155002.51">Rev 38db98ff improves Leo's existing clone-find commands:

- cff (clone-find-flattened)
- cfa (clone-find-all)

in the following important ways:

1. These commands search the entire outline, regardless of the presently selected node. This is a *huge* improvement--you can start searches anywhere. These commands do honor suboutline-only searches.

2. These commands ignore @ignore trees and any @&lt;file&gt; tree whose root nodes contains an @all directive. No more false matches about nodes in the attic.

3. These commands are significantly faster than before because they search body text in one step.

4. The new command names are short enough that they don't need either key bindings or pre-loaded entries in command history.


These commands are so convenient that they become *temporary*. No need to keep them around. I usually start searches with them instead of Ctrl-F. After I create the clone-find node, I then use Ctrl-F (with the existing find pattern) to search the clone-find results.

This is the pattern I have been looking for. I'm not looking for anything better. Notice, it no longer matters how many clones there are.
</t>
<t tx="ekr.20160314155002.52">Two commands that revolutionize my workflow:

- cffm, aka clone-find-flattened-marked
- cfam, aka clone-find-all-marked

These commands create a "target" node as the last top-level node, and clone all marked nodes under the target node.  cffm makes each marked node a child of the target. cfam does not create a child for marked nodes that are descendants of a marked node.

This makes gathering nodes a snap. Just go through the outline, marking the desired nodes, then execute cfam or cffm.  I prefer cffm because all found nodes appear as direct children of the target. These two commands are much better than auto-moving clones as they are made, as I had intended to do yesterday.

Leo's clone-find and clone-find-marked commands allow me to quickly gather desired nodes without duplicates, *regardless* of how many clones there are in an outline. These commands are the magic bullets for searching that I have wanted for decades.

Please try these commands. They are extremely useful.
</t>
<t tx="ekr.20160314155002.53"></t>
<t tx="ekr.20160314155002.54">This command does the following:

1. Clones the selected node.
2. Moves the clone to the last child of the last @spot node in the outline.
3. Collapses all nodes in the outline.
4. Selects the newly-cloned node, thereby making it visible.


</t>
<t tx="ekr.20160314155002.55">Ctrl-x &amp; Ctrl-C cut/copy the entire line if no text is selected
</t>
<t tx="ekr.20160314155002.56">Pretty much like clone-find-all.
</t>
<t tx="ekr.20160314155002.57">Leo now supports find-def and find-var commands.  They find the definitions of classes, defs or vars. These commands work as follows:

- Select the word at the cursor, if text is not already selected.
- Save the find settings in effect before the command started.
- find-def sets the search pattern to "class word" or "def word"
  depending on whether word is capitalized.
- find-var sets the search pattern to "word =".
- Set word-find to True
- Start the search at the root position of the outline.

This finds the first definition of the word.  Thereafter, you can use F3 (find-next) to find additional definitions.

When the search fails, Leo restores the Find settings to what they were previously.

The new @bool find-ignore-duplicates setting (default False), controls whether any search command ignores duplicate matches.  Ctrl-F restarts searches, clearing a list of vnodes that have already been seen.  Any failed search also clears the list of vnodes.
</t>
<t tx="ekr.20160314155002.58"></t>
<t tx="ekr.20160314155002.59">Tells the command name or names associated with any keystroke.

Prompts for a single character: shows corresponding command.
</t>
<t tx="ekr.20160314155002.6">https://github.com/leo-editor/leo-editor/issues/150

The bug was a typo in plugins/importers/basescanner.py.

Also improved reporting in the RecursiveImportController class.
</t>
<t tx="ekr.20160314155002.60">All kill commands except the kill-paragraph and backward-kill-paragraph commands cuts selected *text* if it exists.
</t>
<t tx="ekr.20160314155002.61">The result is much better looking than before.</t>
<t tx="ekr.20160314155002.62">https://github.com/leo-editor/leo-editor/issues/165
All the changes were to the ExternalFilesController class.
</t>
<t tx="ekr.20160314155002.63"></t>
<t tx="ekr.20160314155002.64">These directives are inherited as usual.
</t>
<t tx="ekr.20160314155002.65">Leo now immediately wraps the body pane when @wrap is in effect.
Previously, the user had to reselect the node when typing "@wrap". This
fixes an annoying hangnail.

- Added match_at_wrap to jEdit colorizers.
- Added force keyword option to all setWrap methods.
  This is needed because text can be colorized before c.p.b stabilizes.
</t>
<t tx="ekr.20160314155002.66"></t>
<t tx="ekr.20160314155002.67">To enable, add the following to myLeoSettings.leo:

    @bool tree-declutter = True

    @data tree-declutter-patterns
    
LeoSettings.leo contains an example @data tree-declutter-patterns.
This node contains documentation about how to use the patterns.
</t>
<t tx="ekr.20160314155002.68">https://groups.google.com/d/msg/leo-editor/yJLz-p3I4mY/Pqa1phYN_10J
</t>
<t tx="ekr.20160314155002.69">leoSettings.leo now contains a new top-level node::

    @ignore Themes: copy to last top-level setting in myLeoSettings.leo

The body text tells what to do with it, namely:

To enable a theme:

1. Copy this entire tree to myLeoSettings.leo.
2. Move the tree so it is the last top-level node under @settings.
3. Remove the @ignore from the copy of this node.
4. Enable one of the three themes below by removing @ignore for its node.
5. Test by opening another Leo outline.

Important Notes

1. The "Themes" node does not define @data qt-gui-plugin-style-sheet.

Instead the new themes machinery uses the so-called "fully parameterized" stylesheet that we have all been using for at least several months now.  This stylesheet is defined as a descendant of the "Appearance" node.

2. The only functional theme is a new ekr_dark theme.  It illustrates how to use the new themes machinery.

- This theme uses a small, custom @data qt-gui-user-style-sheet that adjust colors around outline indicators.

- There is a tree call "Common to all themes" which contains settings that probably can be shared by most themes.  Naturally, setting in that tree can be overridden as you desire.

3. The new themes machinery is supposed to be completely self contained.  That is, there should be no need to use a script to generate a theme.

Yes, the user must fill in all appearance-related settings.  But most users will already have done this, so adjusting the settings for a theme should be straightforward.

4. The "Common to all themes" node contains an "Outline indicators" node that specifies a relative path to outline indicator icons (arrow icons or plus/minus) icons.  The path can be relative to either the users home directory or (as shown in leoSettings.leo) relative to the leo/Icons directory. 
</t>
<t tx="ekr.20160314155002.7">https://github.com/leo-editor/leo-editor/issues/162

cm.isValidLanguage accepts any language x for which leo/modes/X.py exists.

Added a script in LeoDocs.leo that will generate all valid languages.
</t>
<t tx="ekr.20160314155002.70">Like leo leo\test\*.leo.
Previously, Leo crashed!
</t>
<t tx="ekr.20160314155002.71">Useful after a failed Ctrl-F
</t>
<t tx="ekr.20160314155002.72">https://github.com/leo-editor/leo-editor/issues/177

After a find command completes (successfully or not), the status areas shows:

- Whether the find command completed successfully.
- The find options in effect for the search.

Previously, the status line was only updated for unsuccessful searches, and it did not contain the find options in effect.  The new status line is much more helpful than the old.

By default, Leo reports successful searches with white text on a blue background and failed searches with white text on a red background. These colors work pretty well even for dark themes.

You can choose these colors using the following settings:

     @color find-found-bg = blue
     @color find-found-fg = white
     @color find-not-found-bg = red
     @color find-not-found-fg = white
</t>
<t tx="ekr.20160314155002.73">https://github.com/leo-editor/leo-editor/issues/186

Controlled by the following new settings in leoSettings.leo, with defaults as shown::

    @bool use_gutter = True
    @color gutter-bg = @LightSteelBlue1
    @color gutter-fg = black
    @int gutter-w-adjust = 12
    @int gutter-y-adjust = 10
    @string gutter-font-family = @font-family
    @string gutter-font-size = @small-font-size
    @string gutter-font-style = @font-style
    @string gutter-font-weight = @font-weight
</t>
<t tx="ekr.20160314155002.74">Better looking than the old way.
</t>
<t tx="ekr.20160314155002.75"></t>
<t tx="ekr.20160314155002.76">https://groups.google.com/d/msg/leo-editor/pM8aVJ1D6ao/Z8lq43t7FAAJ

There's now an "Edit settings" menu under the main Settings menu, containing many submenus.  Each menu item finds the appropriate setting and copies it to
the appropriate outline for you, so knowing what to look for and how to
manage it is handled.

Sometimes you'll see this dialog:

    The relevant setting, '@bookmarks_base_color', is using the value of
    a more general setting, '@text-foreground'.  Would you like to edit
    the more specific setting, '@bookmarks_base_color', or the more
    general setting, '@text-foreground'?  The more general setting may
    alter appearance / behavior in more places, which may or may not be
    what you prefer.

                            Edit specific   Edit general   Cancel

Wordy, but easy enough to follow.  I guess everything after the
last comma could be deleted :-)

If the setting is in leoSettings.leo, you see:

    The setting '@body-font-family' is in the Leo global configuration
    file 'leoSettings.leo' and should probably be copied to
    'myLeoSettings.leo' before editing.
    It may make more sense to copy a group or category of settings.

    Please enter 1, 2, 3, or 4:
    1. copy the one setting, '@body-font-family'
    2. copy the setting group, 'Body font' (Recommended)
    3. copy the setting whole category, 'Fonts'
    4. edit the setting in 'leoSettings.leo' anyway

Again, wordy, but I think easy enough to understand.

(Having to enter a number to pick an option is clunky, a
 gui-independent 'pick item from list widget' can be added to Leo, I
 just didn't want to mix that task into the current task.)

Note "Reload settings" isn't working as effectively as I think it
should, that may need to be addressed as well.  Unrelated to the new
code.

So, this isn't a silver bullet for the newbie setting editing woes, but
it does eliminate a lot of the Leo specific knowledge required (apart
from "edit a headline").  Also this new approach can be developed
further based on feedback, just wanted to get what I had so far into
the main branch for testing etc.
</t>
<t tx="ekr.20160314155002.77"></t>
<t tx="ekr.20160314155002.78"></t>
<t tx="ekr.20160314155002.79"></t>
<t tx="ekr.20160314155002.8">https://github.com/leo-editor/leo-editor/issues/169

The fix was a special case in at.readStartNode.
</t>
<t tx="ekr.20160314155002.80">https://groups.google.com/d/msg/leo-editor/wWWUgfDhPi4/VmRRRa_xDAAJ

Terry Brown: I've added remote code execution abilities to mod_http.py  Relevant part of the doc.s pasted below.

This is a plus for a couple of reasons - previously you had to use the leoremote plug-in which used sockets and was really python only, this new approach just uses HTTP GET requests which can be generated by almost anything (language, link in a doc., browser bookmark, etc.). Also leoremote doesn't work in Python 3.x.

This code to load a file into Leo from the command line:
https://github.com/leo-editor/snippets/blob/master/utils/led.py

Can be replaced with this version:
https://github.com/leo-editor/snippets/blob/master/utils/led.sh

Executing code remotely
-----------------------

.. warning::

    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=&lt;python code for Leo to execute&gt;

The query parameters are:

``cmd`` (required)
    A valid python snippet for Leo to execute.  Executed by the ``vs-eval`` command in the ``valuespace`` 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::

    http://localhost:8130/_/exec/commanders/

which returns a list of open outlines.

Examples
========

This command::

    curl http://localhost:8130/_/exec/?cmd='c.bringToFront()' &gt;/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/ &gt;/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::

    TEXT="$@"
    curl --silent --show-error --get --data-urlencode cmd="
        nd = c.rootPosition().insertAfter()
        nd.h = 'TODO: $TEXT'
        import time
        nd.b = '# created %s' % time.asctime()
        c.selectPosition(nd)
        c.redraw()
        'To do item created\n'
    " http://localhost:8130/_/exec/

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\n'`` 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.
</t>
<t tx="ekr.20160314155002.81"></t>
<t tx="ekr.20160314155002.82">The make_stub_files script eliminates much of the drudgery of creating python stub (.pyi) files https://www.python.org/dev/peps/pep-0484/#stub-files from python source files.

The script does no type inference. Instead, it creates function annotations using user-supplied **patterns**, pairs of strings of the form "name: type-annotation".

Full code and documentation here: https://github.com/edreamleo/make-stub-files
</t>
<t tx="ekr.20160314155002.83">This script helps Python programmers convert Python code to coffeescript. It converts python syntax to the roughly equivalent coffeescript syntax.

This script makes a coffeescript (.coffee) file in the output directory for each source file listed on the command line (wildcard file names are supported).

Full code and documentation here: https://github.com/edreamleo/python-to-coffeescript

Note: This script resulted in the TokenSync class, now in leoAst.py.</t>
<t tx="ekr.20160314155002.84"></t>
<t tx="ekr.20160314155002.85">This setting controls whether any search command ignores duplicate matches.  Ctrl-F restarts searches, clearing a list of vnodes that have already been seen.  Any failed search also clears the list of vnodes.
</t>
<t tx="ekr.20160314155002.86">When True, find commands get their find pattern from the word under the cursor.
</t>
<t tx="ekr.20160314155002.87">True: syntax errors raise impossible-to-miss popup dialog.
</t>
<t tx="ekr.20160314155002.88">Enable with: @bool use_find_dialog = True
Related setting: @bool close-find-dialog-after-search = False

Defaults are as shown above.
</t>
<t tx="ekr.20160314155002.89">The following settings set the colors in the status line after a search completes:

    @color find-found-bg = blue
    @color find-found-fg = white
    @color find-not-found-bg = red
    @color find-not-found-fg = white
</t>
<t tx="ekr.20160314155002.9">https://github.com/leo-editor/leo-editor/issues/181

LM.finishOpen now calls c.outerUpdate.
</t>
<t tx="ekr.20160314155002.90">The fix was to create a dummy root position in abbrev.init_env.
</t>
<t tx="ekr.20160314155002.91">If you aren't using the @data history-list setting chances are that you missing a big chance to simplify your workflow. At one time I thought the history list was a minor feature.  I could not have been more wrong.

The body of the @data history-list node should contain a list of command names, one per line.  This list can include commands created by @command/@button nodes.

You execute items in the history list by doing Alt-X followed by an up arrow to get the first item in the list, or one or more down arrows to get later items in the list.  The last item you execute from this list goes to the head of the list.  Once you have executed an item, Ctrl-P (repeat complex command) will re-execute it.

The history list works well for commands that aren't quite worth a separate key binding, but that nevertheless you find you using quite often.

Even better, the history list is a perfect complement to @button and @command nodes that are tailored for a particular outline. For example, there is a button called cfa-code in leoPy.leo that executes the clone-find-all-flattened command starting at the top-level "Code" node.
</t>
<t tx="ekr.20160314155002.92">https://github.com/leo-editor/leo-editor/issues/183

Added @ignore @data qt-gui-user-style-sheet to leoSettings.leo.
This contains  alternative active pane highlighting.

This completes enhancement #183: improve focus-border handling in qt stylesheet
https://github.com/leo-editor/leo-editor/issues/183

It would be tricky, and not terribly useful, to fold this user stylesheet into
the main @data qt-gui-plugin-style-sheet, especially considering that
themes may want to use qt-gui-user-style-sheet.

Also, the default settings aren't bad, but I prefer to change qt-gui-user-style-sheet directly.
</t>
<t tx="ekr.20160314155002.93">Here are the details:

@ifenv name, one-or-more-comma-separated values

Includes descendant settings if os.getenv(name) matches any of the values.

- Case is significant in the *name* of the environment variable.
- Case is ignored in the *values*.

Examples:

@ifenv HOSTNAME,bob
    Enables descendant settings if os.environ('HOSTNAME') is 'Bob' or 'bob'

@ifenv EDITOR,leo,lion
    Enables descendant settings if os.environ('Editor') is 'Leo' or 'Lion', etc.

@ifplatform name,  one-or-more-comma-separated values.

Includes descendant settings if sys.platform matches any of the values, ignoring case.

Examples:

@ifplatform darwin,linux2
    Enables descendant settings for MacOS and Linux.

@ifplatform win32
    Enables descendant settings for Windows

@ifhostname name

Includes descendant settings if os.environ('HOSTNAME') == name

@ifhostname !name

Includes descendant settings if os.environ('HOSTNAME') != name
</t>
<t tx="ekr.20160314155002.94"></t>
<t tx="ekr.20160314155002.95">@bool use_gutter = True
@color gutter-bg = @LightSteelBlue1
@color gutter-fg = black
@int gutter-w-adjust = 12
@int gutter-y-adjust = 10
@string gutter-font-family = @font-family
@string gutter-font-size = @small-font-size
@string gutter-font-style = @font-style
@string gutter-font-weight = @font-weight
</t>
<t tx="ekr.20160314155303.1"></t>
<t tx="ekr.20160315105606.1"></t>
<t tx="ekr.20160428153901.1">Leo 5.3-final May 2, 2016

[Leo](http://leoeditor.com/) 5.3-final is now available on [SourceForge](http://sourceforge.net/projects/leo/files/Leo/). Leo is a PIM, an IDE and an outliner.

**The highlights of Leo 5.3**

- Leo now supports Jupyter Notebook (.ipynb) files.
- @chapter is now allowed anywhere. No need for @chapters.
- Faster spell checking.
- The rst3 command supports @rst-table.
- The show-invisibles command now uses native Qt characters.
- Dozens of other improvements and bug fixes.

**Leo is**:

- An outliner. Everything in Leo is an outline.
- A Personal Information Manager.
- A browser with a memory.
- A powerful scripting environment.
- A tool for studying other people's code.
- A fully-featured IDE, with emacs-like commands.
- Extensible via a simple plugin architecture.
- A tool that plays well with  IPython, vim and xemacs.
- Written in 100% pure Python
- Compatible with Python 2.6 and above or Python 3.0 and above.
- A tool with an inspiring and active community.

**Leo's unique features**:
    
- Always-present, persistent, outline structure.
- Leo's underlying data is a Directed Acyclic Graph.
- Clones create multiple views of an outline.
- A simple, powerful, outline-oriented Python API.
- Scripts and programs can be composed from outlines.
- Importers convert flat text into outlines.
- Scripts have full access to all of Leo's sources.
- Commands that act on outline structure.
  Example: the rst3 command converts outlines to reStructuredText.
- @test and @suite scripts create unit tests automatically.
- @button scripts apply scripts to outline data.
- Outline-oriented directives.

Simulating these features in vim or Emacs is possible, just as
it is possible to simulate Python in assembly language...

**Links**

- [Leo's home page](http://leoeditor.com)
- [Documentation](http://leoeditor.com/leo_toc.html)
- [Tutorials](http://leoeditor.com/tutorial.html)
- [Video tutorials](http://leoeditor.com/screencasts.html)
- [Forum](http://groups.google.com/group/leo-editor)
- [Download](http://sourceforge.net/projects/leo/files/)
- [Leo on Github](https://github.com/leo-editor/leo-editor)
- [What people are saying about Leo](http://leoeditor.com/testimonials.html)
- [A web page that displays .leo files](http://leoeditor.com/load-leo.html)
- [More links](http://leoeditor.com/leoLinks.html)
</t>
</tnodes>
</leo_file>
