Feature: Allow @path in body text#
Removed unnecessary check in g.get_directives_dict.
Leo https://leo-editor.github.io/leo-editor/ 6.8.10 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [outline-oriented text editor](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.10
Add authentication & secure websockets to leoserver.py.
Add the show-node-files command.
Add the clone-diff-pr command.
Add the c.p setter.
Update most theme files.
Add vv-dark.leo theme.
Add a Leo launcher generator for MacOS.
Remove the todo.py plugin.
Breaking changes to Leo’s API: See the What’s New section for details.
The usual bug fixes.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.10 Issues](leo-editor/leo-editor#issues)
[6.8.10 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.9 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [outline-oriented text editor](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.9
Add Find/Change history. How did we ever live without this?
Replace the ,, Easter Egg with Leo’s Find commands.
Add support for @language pug.
Enhanced security for Leo’s server.
Significant code-level improvements and performance optimizations.
Deprecate support for –gui=console.
The usual bug fixes.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.9 Issues](leo-editor/leo-editor#issues)
[6.8.9 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.8 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [outline-oriented text editor](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.8
Replace Leo’s legacy beautifier commands by full support for [ruff format](https://docs.astral.sh/ruff/formatter/).
Make the add-comments command compatible with ruff format.
Add the @bool raise-file-update-dialogs setting.
Add the dump-last-colorizer-trace command.
Remove support for leoflexx and –gui=browser.
Add check_leo.py script.
Add gdc.summary_diff_two_revs script helper.
Fix several minor bugs.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.8 Issues](leo-editor/leo-editor#issues)
[6.8.8 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.7 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.7
PR #4403: Add support for Python 3.14. Require Python 3.10 or above.
PR #4423: All of Leo’s importers now import @clean files perfectly.
PR #4412: Greatly improve Leo’s parse-body command.
PR #4418: Fix bugs involving the _mod_time attribute in .leo files.
PR #4456: Added leo_to_html_outline_viewer.py plugin.
PR #4456: Add check_leo script.
Fix several other minor bugs. See the What’s new section for details.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.7 Issues](leo-editor/leo-editor#issues)
[6.8.7 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.6.1 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.6 and Leo 6.8.6.1
Leo 6.8.6.1 fixes a bug introduced in Leo 6.8.6 that could corrupt @clean nodes.
Read only unchanged @clean nodes: a huge performance boost!
Support @leo <path>; nodes. See https://leo-editor.github.io/leo-editor/directives.html#leo-directives - The open-at-leo-file command opens the given outline. - The c.makeLinkLeoFiles method helps scripts create a top-level
outline containing links to sub-outlines.
Support for virtual python environments: a long-awaited update for LeoInteg!
Add a theme file for SwotMoknokai.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.6 Issues](leo-editor/leo-editor#issues)
[6.8.6.1 Issues](leo-editor/leo-editor#issues)
[6.8.6 Pull Requests](leo-editor/leo-editor)
[6.8.6.1 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.5 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.5
This release contains minor bug fixes and code cleanups.
The signatures of the`k.registerCommand` and k.registerCommandShortcut methods have changed.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.5 Issues](leo-editor/leo-editor#issues)
[6.8.5 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.4 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.4
Improve the Rust importer.
Allow rest comments to be colored differently from @language rest.
Support @language typst.
Several other improvements to syntax coloring.
Add the show-buttons-and-at-commands command.
Add the find-source-for-command command.
Add the beautify-script command.
The execute-script command beautifies c.p’s tree if @bool beautify-python-code-on-write = True.
Remove the join-leo-irc command.
Scripts (including @command and @button scripts) may now return a value.
Replace c.scanAllDirectives with 7 seven new Commands getters.
Deprecate c.scanAllDirectives and 17 other directives-related functions.
Call g.deprecated in all deprecated functions to issue a deprecation warning.
Several significant code cleanups.
The usual minor bug fixes.
Breaking change
Syntax coloring for @language rest may require a new setting in myLeoSettings.leo. See the What’s new in Leo 6.8.4 for details.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.4 Issues](leo-editor/leo-editor#issues)
[6.8.4 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.3 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.3
Five PRs improve and generalize Leo’s colorizer.
PR #4140: Improve @language jupytext.
PR #4178: Add @language openscad.
PR #4198: Add @language glsl
PR #4203: Add @language vue
PRs #4207 and #4209: Upgrade Leo’s website.
The usual assortment of small bug fixes and code cleanups.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.3 Issues](leo-editor/leo-editor#issues)
[6.8.3 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.8.0 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.8.0
This release contains several breaking changes to Leo’s API. See the What’s new in Leo 6.8.0 section for details.
Significant changes
PR #3828: Leo now requires PyQt6.
PR #3911: Leo’s core no longer uses the free_layout or nested_splitter plugins.
PR #3872: Improve how Leo searches for definitions. Add @bool prefer-nav-pane.
PR #3922: Improved the restart-leo command.
New and improved
PR #3870: Leo’s beautifier works faster.
PR #3841: Add g.traceUnique and g.traceUniqueClass functions.
PR #3893: Add vr-fully-expand, vr-toggle-visibility and vr-keep-open commands.
PR #3902: Add the toggle-unl-view command.
PR #3921: Add the show-qt-widgets command.
The usual minor improvements and bug fixes.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.8.0 Issues](leo-editor/leo-editor#issues)
[6.8.0 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.7.8 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.8
This release simplifies Leo’s install process. See https://leo-editor.github.io/leo-editor/getting-started.html
PR #3757: (leoTokens.py) Make Leo’s beautifier 3x faster.
PR #3771: Revert colorizing of f-strings.
PR #3786: Support Nim.
PR #3790: Add “get-unl” command to Leo’s server.
PR #3805: Fix problems with auto-completion and calltips.
PR #3806: Fix problems with Leo’s go-back and go-forward commands.
PR #3807: Improve Leo’s Python importer.
PR #3817: Allow relative paths in gnx-based UNLs.
The usual minor improvements and bug fixes.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.8 Issues](leo-editor/leo-editor#issues)
[6.7.8 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Leo https://leo-editor.github.io/leo-editor/ 6.7.7 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.7
PR #3761: Improve leoserver.py to support LeoInteg.
Assorted minor improvements.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.7 Issues](leo-editor/leo-editor#issues)
[6.7.7 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.7.6 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.6
Support for Python 3.12:
PR #3693: update leoAst.py for Python 3.12.
PR #3701: Colorize PEP 701 f-strings.
Other significant improvements:
Retire the –load-type command-line option.
PR #3575: Add the indented_languages plugin.
PR #3642: Add the clean-all-lines command.
PR #3659: Add python-to-rust command.
PR #3673: Add summarize command.
scripts.leo contains @button scripts by Thomas Passin.
The usual assortment of minor bug fixes and code-level improvements.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.6 Issues](leo-editor/leo-editor#issues)
[6.7.6 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.7.5 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.5
PR #3568: Improve word-oriented finds and improve Leo’s spell checker.
PRs #3515 and #3517: Significantly improve python importer.
PRs #3509 and #3511: Improve rust importer.
Other improvements
PR #3560: Retire the g.SherlockTracer class.
PR #3552: Clear dirty bits when writing sqLite DBs.
PR #3541: Use c.doCommandByName instead of c.k.simulateCommand.
PR #3538: Make file-diff-files undoable.
PR #3533: Reload outlines rather than restarting Leo.
PR #3531: Add move-outline-to-first-child & move-outline-to-last-child commands.
PR #3528: Improve copy-gnx command.
PR #3525: Add promote-section-references command.
PR #3521: Improve what-line command.
PR #3519: Make the mark-node-and-parents and unmark-node-and-parents commands undoable.
PR #3503: Fix bug involving back slashes in search patterns.
PR #3499: Retire the read-outline-only command.
PR #3607: Add scheme importer
Fix several other minor bugs.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.5 Issues](leo-editor/leo-editor#issues)
[6.7.5 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.7.4 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.4
Warning: breaking changes to Leo’s api
p.get_UNL returns gnx-based unls. Previously it returned path-based gnxs. See the first comment of PR #3424 for full details.
gnx-based unls
PR #3215 and #3424: gnx-based unls (clickable links). These links will break only if the original node is deleted.
New settings
@string unl-status-kind = gnx
@bool full-unl-paths = True
@data unl-path-prefixes
Other improvements
PR #3330: Improve importers for C, C++, and cython.
PR #3345: Improve importer architecture.
PR #3363 & #3379: Improve c.recursiveImport.
PR #3376: Improve python importer.
Large code changes
PR #3365: Simplify mypy annotations (128 files).
PR #3367: Import Callable from collections.abc instead of typing (50 files).
Retire three plugins
PR #3215: Retire the settings_finder, backlink, and quickMove plugins.
50+ issues and 70+ pull requests.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.4 Issues](leo-editor/leo-editor#issues)
[6.7.4 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.7.3 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.3
@<file> nodes.Leo supports Python’s standard os.path expansions. Leo no longer supports {{python-expression}} in headlines.
Several large code cleanups: 460+ files changed.
Commands
PR #3227: Add commands to add/remove numbers from headlines.
PR #3255: Add write-zip-archive command.
PR #3192: Add show-color-settings and the show-font-settings commands.
Other changes
PR #3208: Add ‘reload-settings’ hook.
PR #3214: Optionally expand headlines on mouse-over.
PR #3224: Improve mod_autosave plugin.
PR #3241: Simplify Leo’s path wrappers.
PRs #3264 and #3277: Simplify Leo’s path-related code.
Tweaks and small bug fixes: 20+ issues and 30+ pull requests.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.3 Issues](leo-editor/leo-editor#issues)
[6.7.3 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.7.2 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.2
PR #3019: Leo’s website has moved to GitHub Pages: https://leo-editor.github.io/leo-editor/
Commands:
PR #3031: Add check-nodes command. It helps keep @clean files in sync.
PR #3056: Leo’s beautify command is now PEP8 compliant.
PR #3140: Run pylint on node.
PR #3166: Add the execute-external-file command.
Settings and features:
PR #2979: Add @bool run-flake8-on-write setting.
PR #2983: Add –black-sentinels command-line option.
PR #3038: Add @string rst3-action setting.
PR #3053: Add @string gxn-kind setting: Support gnxs formatted as UUIDs.
PR #3132: Add @bool rst3-remove-leo-directives setting.
Other changes:
80+ issues and 100+ pull requests.
Links
[Install Leo](https://leo-editor.github.io/leo-editor/installing.html)
[6.7.2 Issues](leo-editor/leo-editor#issues)
[6.7.2 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.7.1 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.7.1
Several enhancements to leoserver.py.
Add support for ocaml syntax coloring.
Improve markdown importer.
@bool plain-key-outline-search is False by default, disabling a confusing feature.
Several minor code cleanups.
Remove four unused commands.
Links
[6.7.1 Issues](leo-editor/leo-editor#issues)
[6.7.1 Pull Requests](leo-editor/leo-editor)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.6.3 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo, https://leo-editor.github.io/leo-editor/ is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.6.3
Enhance leoserver.py to support LeoInteg and LeoJS.
Improve how Leo handles url’s.
Simplify the GlobalConfigManager class.
The usual assortment of tweaks and bug fixes.
Links
6.6.3 issues: leo-editor/leo-editor#issues
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.6.2 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.6.2
Add “File Only” option in Leo’s Find Pane.
Remove pylint-leo.py, pyflakes-leo.py and related code.
Add mypy annotations for Leo’s most important files.
Fixed 9 minor bugs.
6.6.2 Links
[6.6.2 issues](leo-editor/leo-editor#issues)
[6.6.2 pull requests](leo-editor/leo-editor)
[6.6.2 bug fixes](leo-editor/leo-editor#issues)
[6.6.2 enhancements](leo-editor/leo-editor#issues)
[6.6.2 code-level improvements](leo-editor/leo-editor#issues)
General Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.6.1 is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/6.6.1/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.6.1
Improve support for Python 3.10 and PyQt6.
Simplify the TokenOrderGenerator class in leoAst.py.
Improve argument handling when running leo.core.leoAst externally. Run python -m leo.core.leoAst -h for details.
Control-clicking on a file name searches for the corresponding @<file> node.
Create clickable links when copying text into the log pane.
Leo’s mypy command runs without blocking Leo.
Improve the add-mypy-annotations command.
Clean all files with reindent.
The usual minor bug fixes.
6.6.1 Links
[6.6.1 issues](leo-editor/leo-editor#issues)
[6.6.1 pull requests](leo-editor/leo-editor)
[6.6.1 bug fixes](leo-editor/leo-editor#issues)
[6.6.1 enhancements](leo-editor/leo-editor#issues)
[6.6.1 code-level improvements](leo-editor/leo-editor#issues)
General Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.6 final is now available on [GitHub](leo-editor/leo-editor) and [pypi](https://pypi.org/project/leo/6.6/).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.6
Replaced @raw and @end_raw with @section-delims.
Leo recognizes section references only when they appear on an otherwise blank line.
Many improvements to the python-to-typescript command.
Improved python importer.
Added plugins/picture_viewer.py, a stand-alone app that displays images.
Added plugins/remove_duplicate_pictures.py, an app that finds duplicate pictures.
The user may choose other commands after starting repeat-complex-command.
Improved leoserver.py to support leointeg.
Many bug fixes.
6.6 Links
[6.6 issues](leo-editor/leo-editor#issues)
[6.6 pull requests](leo-editor/leo-editor)
[6.6 bug fixes](leo-editor/leo-editor#issues)
[6.6 enhancements](leo-editor/leo-editor#issues)
[6.6 code-level improvements](leo-editor/leo-editor#issues)
General Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
Leo https://leo-editor.github.io/leo-editor/ 6.5 is now available on [GitHub](leo-editor/leo-editor).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.5
Add python-to-typescript and view-recent-commands.
Add c.findCommands.interactive_search_helper.
Leo now uses only traditional unit tests. Remove support for @test and @suite. Remove leoTest.py.
Many code-level cleanups.
450+ pull requests.
6.5 Links
[6.5 issues](leo-editor/leo-editor#issues)
[6.5 pull requests](leo-editor/leo-editor)
[6.5 bug fixes](leo-editor/leo-editor#issues)
[6.5 enhancements](leo-editor/leo-editor#issues)
[6.5 code-level improvements](leo-editor/leo-editor#issues)
General Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nowrap
#2256: view-recent-commands leo-editor/leo-editor#2256
#2267: python-to-typescript leo-editor/leo-editor#2267
#1766: Use traditional unit tests leo-editor/leo-editor#1766 PR: leo-editor/leo-editor#2159
#2194: black-compatible sentinels leo-editor/leo-editor#2194
#2219: c.findCommands.interactive_search_helper leo-editor/leo-editor#2219
@data python-to-typescript-types
A list of key/value pairs. Keys are argument names (as used in Leo); values are typescript type names.
leoTest2.py create temporary Leo applications and outlines for unit tests.
Remove @test, @suite, unitTest.leo and leoTest.py.
Leo https://leo-editor.github.io/leo-editor/ 6.4 is now available on [GitHub](leo-editor/leo-editor).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.4
Support for [LeoInteg](boltex/leointeg): “Leo in vs-code”. - Add leoserver.py, stand-alone server for Leo. - Add support for .leojs, a json outline format.
Support for Qt6.
The wax_off.py script converts function annotations to stub (.pyi) files.
Remove support for @root. Create a conversion script.
Simplify and generalize rst3 command.
Add git-diff-pr command: Leonine diffs for Pull Requests and .leo files.
Add execute-general-script command and c.general_script_helper.
Several significant code-level changes.
Fixed 160+ issues and merged almost 400 Pull Requests.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
For a list of all the bugs fixed in Leo 6.4 see: leo-editor/leo-editor#issues
For a list of all changes to codebase see: leo-editor/leo-editor#issues
Only the highlights are shown below.
Add c.general_script_helper.
Add commands: - convert-at-root: #1832. - copy-gnx: #1841. - mypy: #1831. - reformat-selection: #1754. - show-all-tags.
Change commands: - reload-settings now changes settings in all open outlines.
Add c.general_script_helper.
w.see works for the first time ever!
Leo’s Qt docks caused great confusion. Leo is better off without them.
Add c.general_script_helper.
Added gdc.diff_pull_request.
Note: Leo can not recognize @path directives in the body text of @file nodes!
This script creates stub (.pyi) files from def lines containing annotations, then removes the annotations.
The wax_off script allows you to add annotations directly in your .py files, and then move most of the clutter to stub files.
Imo, the wax_off script makes my make_stub_files project obsolete.
Add @bool allow-text-zoom = True leo-editor/leo-editor#1923
Add support for –trace-speed. leo-editor/leo-editor#1936
Add settings for Leo’s mypy command: leo-editor/leo-editor#1831 leo-editor/leo-editor#2049 @data mypy-arguments @int mypy-link-limit @string mypy-config-file
Add settings for highlighting the selected line: @bool highlight-body-line = False @string line-highlight-color = None
Leo 6.3, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.3
leoAst.py: The unification of Python’s token and ast worlds.
Retired all Qt Dock code.
Improved viewrendered and viewrendered3 plugins.
Improved several importer plugins.
Refactored Leo’s key handling code.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
For a list of all bugs fixed in Leo 6.3 see: leo-editor/leo-editor#issues The first comment in each bug contains a summary of the bug and its fix.
Crash on reloading workbook while simulating newbie experience leo-editor/leo-editor#1381
Headline icons doubled leo-editor/leo-editor#1559
Abbreviations w/ German keyboards leo-editor/leo-editor#1563
Open theme file fails on posix leo-editor/leo-editor#1564
Tab pane disappears leo-editor/leo-editor#1570 PR: leo-editor/leo-editor#1660
No command function for ‘About…’ leo-editor/leo-editor#1595
Crash in c.executeMinibufferCommand leo-editor/leo-editor#1596
leoAst.py fails for python 3.8 leo-editor/leo-editor#1600
Typescript colorizer does not color block comments properly leo-editor/leo-editor#1602
Exit after refresh-from-disk leo-editor/leo-editor#1603
open-theme-file on arch linux leo-editor/leo-editor#1621
Set language for cloned nodes leo-editor/leo-editor#1625
forward-word-extend-selection doesn’t work the same as back-word-extend-selection leo-editor/leo-editor#1653
Remove duplicates in nested splitter Open Window list leo-editor/leo-editor#1678
Performance bugs on open leo-editor/leo-editor#1688
@test nodes not colored correctly leo-editor/leo-editor#1696
Problems with marked bits leo-editor/leo-editor#1694
Bug in php importer leo-editor/leo-editor#1717
unittest fails w/ python3.8 leo-editor/leo-editor#1700
Major change
Refactor Leo’s key handling code leo-editor/leo-editor#1269
Other changes
Remove pylint complaints from npyscreen sources leo-editor/leo-editor#1709
Remove pyflakes complaints from mod_http.py leo-editor/leo-editor#1710
contract-all-subheads leo-editor/leo-editor#1632
cycle-editor-focus (Restored) leo-editor/leo-editor#1575
import-legacy-external-files leo-editor/leo-editor#1581
paste-as-template leo-editor/leo-editor#1593
move-lines-to-next-node leo-editor/leo-editor#1606
open-leo-py-ref-leo (Aka leo-py-ref-leo)
restart-leo leo-editor/leo-editor#1128
show-settings: Add [T] to legend to indicate theme file settings. leo-editor/leo-editor#1698
JS importer fails with reveal.js leo-editor/leo-editor#1481
Python importer does not import black.py properly leo-editor/leo-editor#1493
Create a Rust importer leo-editor/leo-editor#1538
Create a cython importer leo-editor/leo-editor#1608
Fix ts importer problems leo-editor/leo-editor#1617
Fix c++ importer problems leo-editor/leo-editor#1626
Major features
leoAst.py: Unify the ast and token worlds leo-editor/leo-editor#1440
Retire qt docks leo-editor/leo-editor#1672
Other features
Better alt-click popups leo-editor/leo-editor#1286
Add support for –trace=zoom leo-editor/leo-editor#1569
Ctrl-click should ignore defs in @nosearch leo-editor/leo-editor#1592
Show github branch in outline title leo-editor/leo-editor#1616
Add support for @language json leo-editor/leo-editor#1619
#1620: git-diff clones added nodes leo-editor/leo-editor#1620
Added @button write-leoPyRef.leo leo-editor/leo-editor#1716
Added @bool add-context-to-headline leo-editor/leo-editor#1605
Removed the following command-line options:
–dock –global-docks –init-docks –no-dock –use-docks
Added support for –trace=zoom
Render asciidoc and pandoc markup in VR leo-editor/leo-editor#333
VR plugin should honor headline directives leo-editor/leo-editor#1287
Plugins:About does not show VR https://github.com/leo-editor/leo-editor/issues/1332
Use standard opml tags leo-editor/leo-editor#1473
Context menu leo-editor/leo-editor#1531
Deprecated settings_finder plugin leo-editor/leo-editor#1669
Leo 6.2.1, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an [IDE, outliner and PIM](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.2
Added the fstringify-files and diff-fstringify-files commands.
Improved the beautify-files command. Added the diff-beautify-files commands.
Added the TokenOrderGenerator and TokenOrderTraverser classes in leoAst.py. Leo’s fstringify and beautify commands use these classes.
Added importers for the rust language and todo.txt files.
Added the viewrendered3 plugin.
Leo’s legacy layout is now the default.
Fixed all known bugs, including some notable, long-standing bugs.
Fixed several “fit and finish” issues.
Removed unused settings from leoSettings.leo.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Convert Leo’s code to fstrings: leo-editor/leo-editor#1421
Unify the ast and token worlds: leo-editor/leo-editor#1440 This was a major project: - Add TokenOrderGenerator and TokenOrderTraverser classes. - Add the Fstringify and Orange classes.
Simplify startup logic: leo-editor/leo-editor#1472
Retire @doc file convention: leo-editor/leo-editor#1496
Add ivars for command1/2 event handlers: leo-editor/leo-editor#1508
Replace idle-time handlers with QApplication.processEvents: https://groups.google.com/d/msg/leo-editor/EvBDDCybV2E/tnRAZDqXCgAJ Changed g.recursiveUNLSearch and QtIconBarClass.goto_command.
Rewrote c.deletePositionsInList: leo-editor/leo-editor#1539
Added fstringify-files and diff-fstringify-files commands.
Improved beautify-files command and add diff-beautify-files command.
Removed beautify-node and beautify-tree commands.
Restored Leo’s pane commands: leo-editor/leo-editor#1518 At present, they work only w/o docks.
Persistent body editors: leo-editor/leo-editor#1268
Improve alt-click popups: leo-editor/leo-editor#1286
Add tool tips for headlines: leo-editor/leo-editor#1310
Add an importer for todo.txt files leo-editor/leo-editor#1499
For a list of all bugs fixed in Leo 6.2 see: leo-editor/leo-editor#issues The first comment in each bug contains a summary of the bug and its fix.
Notable bugs:
Leo-Bridge can be wrong about an outline read from a file: leo-editor/leo-editor#1437 The fix is due to Vitalije Milosevic.
Possible problems with marks: leo-editor/leo-editor#1484
execute_shell_commands creates zombie processes: leo-editor/leo-editor#1489
Leo’s legacy layout is now the default: leo-editor/leo-editor#1514 - Add –use-docks option. - Deprecate –no-dock option. - The–global-docks command-line option implies –use-docks. - The default for @string initial-split-orientation is horizontal.
Retired the @bool beautify-autobeautify setting.
Removed many unused settings from leoSettings.leo.
Leo 6.1, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.1
Pyzo in Leo: Pyzo can optionally run within Leo.
Added support for asciidoc and asciidoctor.
Added support for pandoc and sphinx.
Added support for black.
The history_tracer plugin animates git commits.
Integration of Leo with VS code.
New command-line arguments: –global-docks and –window-spot.
New cursor-movement commands.
Special thanks to Vitalije Milosevic, Brian Theado, and Matt Wilkie for their contributions to Leo 6.1.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
leo-editor/leo-editor#1093 The pyzo_in_leo plugin embeds pyzo (https://pyzo.org/) within Leo.
Issues related to asciidoc: leo-editor/leo-editor#issues
Background
asciidoc3 is a python tool. asciidoctor is a ruby tool, claiming to be 100 times faster than asciidoc.
The asciidoc markup language is virtually identical, regardless of the tool used. For full details, see the asciidoctor User manual: https://asciidoctor.org/docs/user-manual/
Here are the recent improvements…
Live rendering of asciidoc and pandoc markup
The VR plugin recognizes @adoc node and @language md. The VR plugin renders only p.b.
Improved adoc command
Given an @adoc node of the form @adoc <full path>, this command does the following:
Scan the @adoc tree, writing the result to adoc_test.adoc.
The scan converts headlines to section markup. See help-for-command for adoc for more details.
Calls asciidoctor or asciidoc3 to convert adoc_test to adoc.html.
This command prefers asciidoctor to to asciidoc3 if both exist.
New adoc-with-preview command
Runs the adoc command, then shows the resulting html in the default browser.
Background
pandoc is a tool for converting pandoc markup (a variant of markdown) to html, and many other formats.
Support for @language pandoc
leo/modes/pandoc.py is based on leo/modes/md.py.
Live rendering of pandoc markup
The VR plugin recognizes @pandoc nodes (see below) and @language pandoc.
The VR plugin renders only p.b.
New pandoc and pandoc-with-preview commands
Much like the corresponding adoc commands, but uses pandoc markup, which is a variant of markdown.
The pandoc tool must exist, because Leo uses it to convert @pandoc trees to html.
#1266: orange (beautify & blacken) leo-editor/leo-editor#1266
#1272: Added support for black (https://pypi.org/project/black/) leo-editor/leo-editor#1272
#1325: black keeps overindented comments: leo-editor/leo-editor#1325
This page shows all bugs related to Leo 6.1: leo-editor/leo-editor#issues
#0490: scroll wheel problems leo-editor/leo-editor#490
#1273: dashed border after dialog leo-editor/leo-editor#1273
#1274: leoQt.py should return None for everything when in bridge leo-editor/leo-editor#1274
#1276: clear-*-uas don’t set outline dirty leo-editor/leo-editor#1276
#1285: Control-clicks can find definitions in the wrong outline leo-editor/leo-editor#1285
#1295: too many @first lines leo-editor/leo-editor#1295
#1307: @first/last invalid in @clean leo-editor/leo-editor#1307
#1318: better arrangement for docks in new windows leo-editor/leo-editor#1318
#1327: Missing outlines for non-existent files leo-editor/leo-editor#1327
#1333: undo glitch leo-editor/leo-editor#1333
#1334: @language C crashes Leo leo-editor/leo-editor#1334
#1335: ipython–exec leo-editor/leo-editor#1336
#1340: body/outline ratio in new files leo-editor/leo-editor#1344
#1345: unit tests fail from bridge leo-editor/leo-editor#1345
#1347: @asis problems leo-editor/leo-editor#1347
#1349: Find Status leo-editor/leo-editor#1349
#1361: at.precheck is broken leo-editor/leo-editor#1361
#1362: crash when reloading leo-editor/leo-editor#1362
#1373: Adoc writes to Scripts folder instead of .leo folder when no @path given leo-editor/leo-editor#1373
#1379: Crash on saving workbook while simulating a new user’s experience leo-editor/leo-editor#1378
#1380: Opening workbook for new user selects top-level nodes repeatedly leo-editor/leo-editor#1380
#1381: Crash on reloading workbook while simulating newbie experience leo-editor/leo-editor#1381
#1385: Console gui doesn’t ask to create leoid leo-editor/leo-editor#1385
#1392: external file not always saved leo-editor/leo-editor#1392
#1403: Catch exceptions during startup leo-editor/leo-editor#1403
#1404: ensure well-formed gnx’s leo-editor/leo-editor#1404
#1415: crash when .leo doesn’t exist leo-editor/leo-editor#1415
#1416: select first .leo file on the command line leo-editor/leo-editor#1416
g.getUrlFromNode was expanding path expressions in body text!
This was a serious bug that could lead to the execution of unchecked code.
See also: #1341: limit path expressions leo-editor/leo-editor#1341
#1316: unify g.TypedDict classes leo-editor/leo-editor#1316
#1323: convert to fstrings leo-editor/leo-editor#1323
#1350: LeoBridge option to not use the cache leo-editor/leo-editor#1350
#1364: Use “”” for all docstrings leo-editor/leo-editor#1364
#1394: External file not always saved leo-editor/leo-editor#1394 - p.setDirty() is now much faster than before. - Added c.all_positions_for_v generator.
This page shows all enhancements related to Leo 6.1: leo-editor/leo-editor#issues
#1253: Support @language asciidoc leo-editor/leo-editor#1253
#1297: warnings about @first & @last leo-editor/leo-editor#1297
#1342: use labels in Find Tab leo-editor/leo-editor#1342
#1351: removed click/drag commands leo-editor/leo-editor#1351
#1353: new cursor commands leo-editor/leo-editor#1353
#1371: support pandoc and @language pandoc leo-editor/leo-editor#1371
#1383: Expand ~ in all paths leo-editor/leo-editor#1383
#1398: Support path expressions in @rst, @adoc, @pandoc and @sphinx nodes leo-editor/leo-editor#1398
New show-clone-ancestors and show-clone-parents commands
Leo 6.0 final, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 6.0
Leo’s default gui uses Qt Docks. Use –no-dock to use Leo’s legacy gui.
Several commands now generate clickable links in the Log pane. This greatly speeds navigation.
The usual assortment of bug fixes and minor improvements.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
The following people contributed significantly to Leo 6.0:
Terry Brown: Born in New Zealand, living in Duluth, Minnesota for 22 years. Ross Burnett Josef Dalcolmo: Born in Italy, living and working in Germany. Chris George: Notch Hill, British Columbia, Canada. Bob Hossley Seth Johnson Rob Keeney: Suwanee, Georgia, USA. John Lunzer. Виталије Милошевић (Vitalije Milosevitch): Serbia. Lewis Neal, Sydney, Australia. Viktor Ransmayr: Munich, Germany. Matt Wilkie: Whitehorse, Yukon, Canada. 周琦 (ZoomQuiet): China.
The following people have made numerous contributions to Leo throughout the years:
Offray Vladimir Luna Cárdenas: Bogotá, Colombia. Kent Tenney: Ashland Wisconsin, USA. Ville M. Vainio.
EKR lives in Madison, Wisconsin, USA
Complete transition to python 3 leo-editor/leo-editor#1137
Chinese characters in command names leo-editor/leo-editor#1121
Use super wherever possible leo-editor/leo-editor#1169
Leo now uses Qt dock widgets by default.
With default settings, Leo looks very much like it always has, but using Qt docks allows you to rearrange the screen to your liking.
Leo remembers the layout of docks when you close Leo, and restores that layout when you restart layout.
Two new settings customize the appearance of docks:
@bool dockable-log-tabs = False
@string central-dock-widget = outline
See the corresponding nodes in leoSettings.leo for full details.
Note: When changing the above settings, it’s best to add the –init-docks setting the next time you run Leo.
Note: Right-clicking the title area of any dock brings up a menu of docks. You can show or hide any dock (except the central widget) using this menu. Don’t be afraid to hide any dock. You can restore it at any later time, including after restarting Leo.
Issues related to Leo docks:
Support docks in Leo’s core leo-editor/leo-editor#1150
Use –no-dock to use Leo’s legacy Qt gui. leo-editor/leo-editor#1171
This page shows all bugs related to Leo 6.0: leo-editor/leo-editor#issues
Duplicate headlines leo-editor/leo-editor#1127
LeoWapp key handling in minibuffer leo-editor/leo-editor#1131
insert-child duplicates p.b leo-editor/leo-editor#1142
Ctrl-S doesn’t save leo-editor/leo-editor#1143
LeoWapp focus issues leo-editor/leo-editor#1146
Problems syntax coloring TeX and LaTeX files leo-editor/leo-editor#1088
git-diff crash leo-editor/leo-editor#1136
Fixed a serious crasher leo-editor/leo-editor#1161
Ctrl-minus selects multiple nodes leo-editor/leo-editor#1168
Recent files menu leo-editor/leo-editor#1188
–maximize doesn’t work leo-editor/leo-editor#1189
open-outline buglet leo-editor/leo-editor#1200
Log pane does not report full commit number leo-editor/leo-editor#1209
Never crash during startup leo-editor/leo-editor#1215
Fix the ctagscompleter plugin leo-editor/leo-editor#1211
Status Bar Won’t Accept Style leo-editor/leo-editor#1218
vim-mode-*-border settings do not work on Qt 5 leo-editor/leo-editor#1221
gui=console. delete line command d is not working leo-editor/leo-editor#1224
gui=console. Backspace, delete keys not working leo-editor/leo-editor#1238
The bookmarks plugin is polluting the .leo file with inappropriate data leo-editor/leo-editor#1247
vr-lock gets overwritten leo-editor/leo-editor#1256
Hard crash in @contextmenu plugin if file not found leo-editor/leo-editor#1257
stickynoteenc traceback leo-editor/leo-editor#1265
Fixed misalignment in LeoQtLog.put
This page shows all enhancements related to Leo 6.0: leo-editor/leo-editor#issues
Huge speed up of replace-all leo-editor/leo-editor#1152
Added find-long-lines. Uses @bool max-find-long-lines-length = 110
Added find-missing-docstrings. Honors @nopylint. leo-editor/leo-editor#1178
Added import-free-mind-files
Added print-window-state. This command is for Leo’s developers.
The pylint command generates clickable log messages. leo-editor/leo-editor#1173
The pylint command honors @nopylint. leo-editor/leo-editor#1178
Improved python_terminal plugin. Important: this plugin segfaults when Leo starts up on some machines. leo-editor/leo-editor#1212
Reform how Leo handles git time stamps leo-editor/leo-editor#1126
Added unit tests for find methods leo-editor/leo-editor#1179
Suppress menu items at load time leo-editor/leo-editor#1199
Added g.es_clickable_link.
Added g.GetRepresentativeObjects
Disallow nested @<file> nodes: a failed experiment leo-editor/leo-editor#1134
Support colorizing of Lua long brackets leo-editor/leo-editor#1175
Add dock commands to Window Menu leo-editor/leo-editor#1261
New command-line arguments:
–init-docks leo-editor/leo-editor#1205
–no-dock Use Leo’s legacy gui instead of the new Qt docks gui.
–trace=aList leo-editor/leo-editor#1145
New settings:
For the find-long-lines command: @bool max-find-long-lines-length = 110
For docks: @bool dockable-log-tabs = False @string central-dock-widget = outline
Leo 5.9 final, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 5.9
This will be the last version of Leo that supports Python 2.
Major features - LeoWapp: Leo in a browser. - Optional syntax coloring using pygments. - Optional you may use @color & @font directives instead of pygments styles. - Integrated debugger.
Other features - Experimental: nested @clean nodes, useful for LaTex files. - A major refactoring of the code that writes external files. - Better error recovery. - Support for continuous integration with TravisCI. - More than 50 minor bug fixes.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
For the complete list, see: leo-editor/leo-editor#issues
Changed various style sheets as a workaround for a serious Qt bug.
fc.setCachedBits scans all nodes for cached data. This simplifies fc.compute_attribute_bits.
The culprit was a mistaken fix to #690: leo-editor/leo-editor#690
Leo no longer generates @nonl sentinels, so regularizing trailing ws is much easier.
#1048 @clean: leo-editor/leo-editor#1048 #1037 @file: leo-editor/leo-editor#1037
Removed @string qt-ui-file-name.
This was an ancient bug!
The fix was to call c.setFileTimeStamp(fileName) in x.replaceFileWithString.
This is an experimental feature. It may be removed in future.
See this posting: https://groups.google.com/forum/#!msg/leo-editor/WGQIzBzQ058/QTJRUvl9CwAJ
Leo now optionally supports syntax coloring with pygments. See https://pygments.org/docs/
Related Leo issues:
New settings (defaults as shown):
@bool use-pygments = False
@bool use-pygments-styles = True
@string pygments-style-name = default
Created a ‘leonine’ style. See: leo-editor/leo-editor-contrib
TravisCI: https://travis-ci.org/
Added the xdb command and various db-* commands, corresponding to the pdb commands:
xdb: Start a Leo’s integrated debugger in a separate thread.
At present, you should run Leo from a console window. That will change soon. See below.
Start the debugger from any part of any @<file> tree. Now you are ready to execute all the db-* commands. You can execute these commands from the minibuffer, or, if the xdb_pane.py plugin is enabled, from the the Debug pane. The following correspond to the pdb commands:
db-b: Set a breakpoint at the line shown in Leo. It should be an executable line. db-c: Continue, that is, run until the next breakpoint. db-h: Print the help message (in the console, for now) db-l: List a few lines around present location. db-n: Execute the next line. db-q: End the debugger. db-r: Return from the present function/method. db-s: Step into the next line. db-w: Print the stack.
There are two additional commands:
db-again: Run the previous db-command. db-input: Prompt for any pdb command, then execute it.
The db-input command allows you can enter any pdb command at all. For example: “print c”.
But you don’t have to run these commands from the minibuffer, as discussed next.
Setting breakpoints in the gutter
When @bool use_gutter = True, Leo shows a border in the body pane. By default, the line-numbering.py plugin is enabled, and if so, the gutter shows correct line number in the external file.
After executing the xdb command, you can set a breakpoint on any executable line by clicking in the gutter to the right of the line number. You can also set a breakpoint any time the debugger is stopped.
Using the gutter is optional. You can also set breakpoints with the db-b command or by typing “d line-number” or “d file-name:line-number using the db-input command, or by using the Debug pane (see below)
The Debug pane
The xdb_pane.py plugin creates the Debug pane in the Log pane. The pane contains buttons corresponding to all the commands listed above. In addition, there is an input area in which you can enter pdb commands. This is a bit easier to use than the db-input command.
Soon, all xdb/pdb output will be sent to an output area in the debug pane. Once that happens, you will be able to run the debugger without running Leo from a console window.
Leo 6.8.8 removes support for LeoWapp and –gui=browser. Use LeoJS or LeoInteg instead.
LeoWapp (Leo as a web browser), implemented using flexx: https://flexx.readthedocs.io/en/stable/
Start Leo using the –gui=browser option. Like this:
leo --gui=browser
leo --gui=browser-firefox-browser
The code is in leo/plugins/leoflexx.py, but this is not a plugin.
Install flexx: https://flexx.readthedocs.io/en/stable/start.html
You should see the flexx (Tornado) server start up in the console. Something that looks like Leo should then appear in the browser. Everything you see is real, and most of it is “live”.
When saving a file, Leo now raises a dialog warning if quitting might lose data.
There are three related issues: leo-editor/leo-editor#1031 leo-editor/leo-editor#1050 leo-editor/leo-editor#1003
The following call FastRead().readFileFromClipboard:
fc.getLeoOutlineFromClipBoard.
fc.getLeoOutlineFromClipBoardRetainingClones.
fc.getPos/VnodeFromClipboard.
Added warning when @asis or @nosent files change outside of Leo.
This branch removes all Python 2 compatibility code. It will be the basis of Leo 6.0.
command line–script relative path is relative to leo/core instead of file-system
Removed –session-save and –session-restore command-line arguments.
Leo saves and restores loaded files only if file names are not given on the command line.
Startup
If the command line contains file names, Leo will load only those files. In that case, Leo does not save session data on exit.
Otherwise, Leo loads files from the previously saved session data in session.leo. If session.leo does not exist, Leo will load the default workbook.leo
Shutdown - Leo saves session data to leo.session only if g.app.loaded_session is True.
This will work as usual for newbies: Leo will open the default Workbook.
Copies the headlines of all descendants to the parent’s body text.
This was a major refactoring of Leo’s code.
See this post: https://groups.google.com/forum/#!topic/leo-editor/JfAUMMOSdvQ
This module contains the fast-redraw code that used to be in leoflexx.py.It deserves to be in Leo’s core because it does not in any way depend on which gui is in effect.
leo-editor/leo-editor#1085 This branch assumes Python 3. It will be the basis of Leo 6.0.
Removed isPython3 switches.
Removed g.u.
Removed g.ue.
The following methods will not be removed: - Replace isBytes, isCallable, isInt, isList, isString
New settings (defaults as shown):
@bool use_gutter = False
@bool use-pygments = False
@bool use-pygments-styles = True
@bool use_xdb_pane_output_= True
@string pygments-style-name = default
Created a ‘leonine’ style. See: leo-editor/leo-editor-contrib
Changed/improved settings:
Improved –trace-coloring traces
#993: use -, not underscore, for settings names.
Removed settings:
Removed –session-save and –session-restore command-line arguments.
Removed @string trailing-body-newlines.
Remove @string qt-ui-file-name. leo-editor/leo-editor#993
Leo 5.8 final, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 5.8
Much faster file-read code.
Leo no longer caches file contents. Removed –no-cache!
Leo using ElementTree instead of sax to read .leo files.
Refactored and improved Leo’s key-handling code.
Improved Leo’s outline drawing code.
The usual minor bug fixes.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
For the full list, see: leo-editor/leo-editor#issues
Changes:
LM.openEmptyWorkBook now saves/restores clipboard.
Deleted qt_gui.setClipboardSelection. It is now a synonym for replaceClipboardWith.
qtew.setSelectionRange now sets the selection only if there is selected text.
The change was to load_session.
The fix was in abbrev.init_tree_abbrev_helper.
added update_nodes method.
The fix was to getVnodeFromClipboard.
The fix was to set @<file> nodes dirty by brute force in find.changeAllCommand.
See also:
leo-editor/leo-editor#722 leo-editor/leo-editor#880
async is a new keyword.
See c.backup_helper.
url = link.url()
AttributeError: ‘QUrl’ object has no attribute ‘url’
It now works in folders besides the leo-editor folder.
leo-editor/leo-editor#969 The fix: call c.treeWantsFocusNow in tt.selectTab.
Fixed #970 with several small, subtle, tweaks:
fast.readWithElementTree simply returns False if the .leo file is invalid.
This necessitated further tweaks:
LM.readOpenedLeoFile never closes Leo by setting finish_quit kwarg to True.
LM.getPreviousSettings uses global settings if the file is invalid.
LM.computeThemeFilePath uses global settings if the file is invalid.
fast.getGlobalData is more careful to handle exceptions.
The legacy code (plugins.regularizeName) tries to import leo.plugins.x if x.py is given in the @enabled-plugins node.
The new code just makes regularizeName more flexible.
12766782 function calls (12734775 primitive calls) in 8.997 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.571 1.571 1.857 1.857 {built-in method exec_}
584 1.029 0.002 1.029 0.002 {built-in method __new__ of type object at 0x00000000664AB3F0}
6787 0.217 0.000 0.217 0.000 {built-in method nt.stat}
145181 0.205 0.000 0.421 0.000 spellCommands.py:243(add_expanded_line)
165 0.181 0.001 0.353 0.002 leoAtFile.py:5163(scan_lines)
630654 0.162 0.000 0.222 0.000 leoGlobals.py:5551(isUnicode)
212111 0.140 0.000 0.247 0.000 leoGlobals.py:4530(match_word) #
35851 0.130 0.000 0.261 0.000 ntpath.py:471(normpath)
608210 0.124 0.000 0.124 0.000 {method 'find' of 'str' objects}
1829 0.119 0.000 0.229 0.001 sre_parse.py:470(_parse)
204516 0.106 0.000 0.106 0.000 leoNodes.py:198(__init__) # Position!!!
105948 0.097 0.000 0.168 0.000 leoFileCommands.py:184(characters) # sax !!!
204348 0.096 0.000 0.202 0.000 leoNodes.py:1338(copy) # !!! Creates new position.
360621 0.096 0.000 0.228 0.000 leoGlobals.py:5628(toUnicode) #
11498 0.095 0.000 0.095 0.000 leoGlobals.py:2961(<listcomp>) # g.compute_directives_re
679634 0.095 0.000 0.095 0.000 {method 'add' of 'set' objects}
891774 0.093 0.000 0.094 0.000 {built-in method builtins.isinstance}
106763 0.093 0.000 0.316 0.000 leoNodes.py:1203(moveToThreadNext)
10434 0.093 0.000 0.405 0.000 leoGlobals.py:4494(is_special)
1251070 0.092 0.000 0.093 0.000 {built-in method builtins.len}
11498 0.092 0.000 0.306 0.000 leoGlobals.py:2911(get_directives_dict)
357802 0.085 0.000 0.085 0.000 {method 'replace' of 'str' objects}
5428 0.083 0.000 0.083 0.000 {built-in method winreg.OpenKey}
132725 0.083 0.000 0.211 0.000 leoNodes.py:2228(headString)
98090 0.078 0.000 0.106 0.000 leoNodes.py:1150(moveToNext)
72669 0.078 0.000 0.371 0.000 leoCommands.py:812(all_unique_positions)
58372 0.074 0.000 0.102 0.000 ntpath.py:121(splitdrive)
122175 0.073 0.000 0.112 0.000 leoNodes.py:780(hasNext)
12535 0.072 0.000 0.088 0.000 leoNodes.py:1931(__init__)
158376 0.071 0.000 0.118 0.000 leoGlobals.py:4585(skip_line)
692 0.067 0.000 0.067 0.000 {built-in method marshal.loads}
2 0.061 0.031 0.106 0.053 spellCommands.py:132(add_words_from_dict)
393812 0.061 0.000 0.061 0.000 {method 'startswith' of 'str' objects}
1070 0.058 0.000 0.058 0.000 {method 'splitlines' of 'str' objects}
239689 0.055 0.000 0.055 0.000 leoNodes.py:1025(_parentVnode)
2718 0.050 0.000 0.285 0.000 {built-in method builtins.__build_class__}
175148 0.048 0.000 0.049 0.000 {built-in method builtins.hasattr}
58267 0.047 0.000 0.113 0.000 leoGlobals.py:6958(toUnicodeFileEncoding)
46 0.046 0.001 0.373 0.008 {method 'Parse' of 'pyexpat.xmlparser' objects}
459482 0.044 0.000 0.044 0.000 {method 'lower' of 'str' objects}
185835 0.044 0.000 0.060 0.000 leoGlobals.py:5579(isWordChar)
1 0.042 0.042 0.665 0.665 mod_scripting.py:521(createAllButtons)
506941 0.041 0.000 0.041 0.000 {method 'append' of 'list' objects}
754 0.041 0.000 0.041 0.000 {built-in method io.open}
119664 0.039 0.000 0.229 0.000 leoNodes.py:654(headString)
268078 0.039 0.000 0.042 0.000 {method 'get' of 'dict' objects}
895 0.038 0.000 0.217 0.000 leoNodes.py:740(get_UNL)
312129 0.038 0.000 0.038 0.000 {method 'strip' of 'str' objects}
2 0.037 0.019 0.469 0.234 spellCommands.py:231(read_words)
122208 0.036 0.000 0.036 0.000 sre_parse.py:232(__next)
695 0.036 0.000 0.061 0.000 <frozen importlib._bootstrap_external>:830(get_data)
119664 0.034 0.000 0.263 0.000 leoNodes.py:1601(__get_h)
40561 0.034 0.000 0.102 0.000 leoNodes.py:517(self_and_parents)
9827 0.033 0.000 0.105 0.000 todo.py:525(loadIcons)
93422 0.031 0.000 0.035 0.000 {method 'join' of 'str' objects}
11993 0.030 0.000 0.053 0.000 leoGlobals.py:6665(os_path_expandExpression)
118705 0.029 0.000 0.064 0.000 sre_parse.py:253(get)
8 0.027 0.003 0.027 0.003 {built-in method setStyleSheet}
55751 0.026 0.000 0.036 0.000 leoNodes.py:1184(moveToParent)
8005 0.026 0.000 0.287 0.000 leoGlobals.py:6784(os_path_join)
7894 0.025 0.000 0.497 0.000 leoGlobals.py:6744(os_path_finalize_join)
932 0.025 0.000 0.028 0.000 sre_compile.py:250(_optimize_charset)
695 0.025 0.000 0.025 0.000 {method 'read' of '_io.FileIO' objects}
206990 0.025 0.000 0.025 0.000 leoNodes.py:282(__bool__)
3386 0.025 0.000 0.382 0.000 leoGlobals.py:2965(get_directives_dict_list)
50243 0.023 0.000 0.023 0.000 {method 'match' of '_sre.SRE_Pattern' objects}
4659 0.023 0.000 0.025 0.000 leoFileCommands.py:1187(handleVnodeSaxAttributes)
541 0.022 0.000 0.022 0.000 {method 'read' of '_io.BufferedReader' objects}
6 0.022 0.004 0.144 0.024 leoCommands.py:1317(checkGnxs)
20098 0.022 0.000 0.038 0.000 editCommands.py:834(getIconList)
10469 0.022 0.000 0.054 0.000 ntpath.py:74(join)
750/1 0.021 0.000 9.016 9.016 {built-in method builtins.exec}
14584 0.021 0.000 0.339 0.000 re.py:286(_compile)
250111 0.020 0.000 0.020 0.000 {method 'isalnum' of 'str' objects}
13190 0.020 0.000 0.166 0.000 leoGlobals.py:6717(os_path_expanduser)
13769 0.019 0.000 0.080 0.000 leoNodes.py:1282(safeMoveToThreadNext)
17085 0.019 0.000 0.032 0.000 nodetags.py:185(get_tags)
1 0.018 0.018 0.018 0.018 {msleep}
64193 0.018 0.000 0.025 0.000 leoGlobals.py:5543(isString)
24206 0.018 0.000 0.021 0.000 leoNodes.py:1117(moveToFirstChild)
11498 0.018 0.000 0.123 0.000 leoGlobals.py:2954(compute_directives_re)
5428 0.017 0.000 0.017 0.000 {built-in method winreg.EnumKey}
19656 0.017 0.000 0.100 0.000 leoCommands.py:749(all_positions)
65 0.016 0.000 0.016 0.000 {method 'execute' of 'sqlite3.Connection' objects}
13025 0.016 0.000 0.027 0.000 leoFileCommands.py:143(<listcomp>)
19424 0.016 0.000 0.022 0.000 leoNodes.py:1104(moveToBack)
4659 0.015 0.000 0.119 0.000 leoFileCommands.py:1155(createSaxVnode)
17/15 0.015 0.001 0.024 0.002 {built-in method _imp.create_dynamic}
4 0.015 0.004 0.015 0.004 {built-in method show}
3362 0.015 0.000 0.440 0.000 leoCommands.py:1936(scanAtPathDirectives)
6737 0.015 0.000 0.031 0.000 leoGlobals.py:4572(skip_id)
524 0.015 0.000 0.015 0.000 {built-in method nt._isdir}
26695 0.015 0.000 0.024 0.000 leoGlobals.py:4516(match)
134173 0.014 0.000 0.014 0.000 {built-in method nt.fspath}
13593 0.014 0.000 0.032 0.000 leoFileCommands.py:198(endElement)
13593 0.014 0.000 0.109 0.000 leoFileCommands.py:258(startElement)
3186/403 0.014 0.000 0.057 0.000 sre_compile.py:64(_compile)
1 0.014 0.014 0.132 0.132 mimetypes.py:230(read_windows_registry)
11130 0.014 0.000 0.068 0.000 leoNodes.py:1999(findAtFileName)
169 0.014 0.000 0.015 0.000 leoAtFile.py:225(initReadIvars)
13775 0.013 0.000 0.107 0.000 leoCommands.py:832(safe_all_positions)
9834 0.013 0.000 0.013 0.000 {built-in method today}
27 0.013 0.000 0.013 0.000 {built-in method repaint}
46946 0.013 0.000 0.023 0.000 leoNodes.py:2599(__get_u)
4755 0.013 0.000 0.026 0.000 ntpath.py:199(split)
834 0.013 0.000 0.013 0.000 {built-in method winreg.QueryValueEx}
36552 0.013 0.000 0.013 0.000 {method 'split' of 'str' objects}
2 0.013 0.006 0.018 0.009 QNCalendarWidget.py:35(build)
67396 0.012 0.000 0.012 0.000 {method 'pop' of 'list' objects}
8 0.012 0.001 0.012 0.002 {built-in method addTab}
1347 0.012 0.000 0.935 0.001 leoGlobals.py:3448(fullPath)
105011 0.011 0.000 0.012 0.000 sre_parse.py:248(match)
13593 0.011 0.000 0.123 0.000 expatreader.py:332(start_element)
26391 0.011 0.000 0.011 0.000 {method 'finditer' of '_sre.SRE_Pattern' objects}
1307 0.011 0.000 0.139 0.000 <frozen importlib._bootstrap_external>:1233(find_spec)
17084 0.011 0.000 0.061 0.000 leoChapters.py:245(parseHeadline)
8200 0.011 0.000 0.015 0.000 leoGlobals.py:4654(skip_ws)
39321 0.010 0.000 0.015 0.000 todo.py:607(getat)
13196 0.010 0.000 0.017 0.000 ntpath.py:308(expanduser)
7582 0.010 0.000 0.062 0.000 leoGlobals.py:6748(<listcomp>)
10437 0.010 0.000 0.424 0.000 leoNodes.py:2116(isAtIgnoreNode)
19424 0.010 0.000 0.049 0.000 leoNodes.py:697(getBack)
4659 0.009 0.000 0.028 0.000 leoNodes.py:112(scanGnx)
13025 0.009 0.000 0.047 0.000 leoFileCommands.py:138(attrsToList)
13025 0.009 0.000 0.011 0.000 xmlreader.py:308(getNames)
29515 0.009 0.000 0.156 0.000 leoCommands.py:737(all_unique_nodes)
2 0.009 0.004 0.009 0.004 {built-in method setCalendarWidget}
727 0.009 0.000 0.009 0.000 {method 'connect' of 'PyQt5.QtCore.pyqtBoundSignal' objects}
1 0.009 0.009 0.009 0.009 backend.py:71(Backend)
2 0.009 0.004 0.162 0.081 leoChapters.py:318(setAllChapterNames)
8780 0.009 0.000 0.082 0.000 ntpath.py:538(abspath)
8780 0.008 0.000 0.008 0.000 {built-in method nt._getfullpathname}
7582 0.008 0.000 0.484 0.000 leoCommands.py:1884(os_path_finalize_join)
17318 0.008 0.000 0.008 0.000 {method 'search' of '_sre.SRE_Pattern' objects}
4043 0.008 0.000 0.012 0.000 leoMenu.py:247(<listcomp>)
190 0.008 0.000 0.008 0.000 {built-in method _hashlib.openssl_md5}
172 0.008 0.000 0.008 0.000 {built-in method nt.access}
4669/10 0.008 0.000 0.128 0.013 leoFileCommands.py:1138(createSaxChildren)
9828/1 0.008 0.000 0.189 0.189 todo.py:497(new)
1 0.008 0.008 0.063 0.063 backlink.py:412(loadLinksInt)
677 0.008 0.000 0.008 0.000 {method 'decode' of 'bytes' objects}
4706 0.007 0.000 0.041 0.000 leoFileCommands.py:389(startVnode)
14989 0.007 0.000 0.012 0.000 {built-in method builtins.getattr}
104772 0.007 0.000 0.007 0.000 {built-in method builtins.ord}
12535 0.007 0.000 0.015 0.000 leoNodes.py:102(new_vnode_helper)
34954 0.007 0.000 0.007 0.000 {method 'lstrip' of 'str' objects}
96309 0.007 0.000 0.007 0.000 {method 'isspace' of 'str' objects}
5893 0.007 0.000 0.018 0.000 enum.py:801(__and__)
5628 0.007 0.000 0.013 0.000 leoGlobals.py:1881(add)
16355 0.007 0.000 0.013 0.000 leoNodes.py:2173(bodyString)
1 0.007 0.007 0.173 0.173 todo.py:519(loadAllIcons)
42287 0.006 0.000 0.006 0.000 {method 'group' of '_sre.SRE_Match' objects}
4158 0.006 0.000 0.034 0.000 leoFileCommands.py:361(tnodeAttributes) 4706 0.006 0.000 0.029 0.000 leoFileCommands.py:406(vnodeAttributes) 5632 0.006 0.000 0.067 0.000 leoGlobals.py:6826(os_path_normpath)
8005 0.006 0.000 0.167 0.000 leoGlobals.py:6801(<listcomp>) 2294 0.006 0.000 0.030 0.000 leoAtFile.py:3705(putCodeLine) 4252 0.006 0.000 0.063 0.000 leoKeys.py:2956(registerCommandShortcut) 5220 0.006 0.000 0.015 0.000 leoAtFile.py:4321(os)
19 0.006 0.000 0.073 0.004 leoCommands.py:1181(setChanged)
6405 0.006 0.000 0.027 0.000 leoConfig.py:1728(getShortcut)
24357 0.006 0.000 0.006 0.000 leoNodes.py:2621(__get_gnx) 13593 0.006 0.000 0.037 0.000 expatreader.py:335(end_element)
98 0.006 0.000 0.009 0.000 {built-in method builtins.sorted}
12884 0.006 0.000 0.007 0.000 enum.py:515(__new__)
- 1928 0.006 0.000 0.370 0.000 leoConfig.py:1898(visitNode)
1 0.006 0.006 1.436 1.436 leoAtFile.py:703(readAll)
4605 0.006 0.000 0.051 0.000 leoGlobals.py:6641(os_path_basename)
15928 0.006 0.000 0.018 0.000 leoNodes.py:651(bodyString) 12535 0.006 0.000 0.007 0.000 leoNodes.py:45(check_gnx) 14212 0.006 0.000 0.336 0.000 re.py:231(compile)
- 167 0.006 0.000 0.049 0.000 leoGlobals.py:3683(readFileIntoString)
1 0.006 0.006 0.040 0.040 qt_gui.py:46(__init__) 7 0.005 0.001 0.058 0.008 leoKeys.py:2264(makeBindingsFromCommandsDict)
749 0.005 0.000 0.162 0.000 <frozen importlib._bootstrap>:870(_find_spec) 693 0.005 0.000 0.007 0.000 <frozen importlib._bootstrap_external>:430(_validate_bytecode_header)
13208 0.005 0.000 0.009 0.000 leoGlobals.py:207(__init__) 15928 0.005 0.000 0.023 0.000 leoNodes.py:1572(__get_b)
80 0.005 0.000 0.008 0.000 qt_frame.py:4354(__init__)
8005 0.005 0.000 0.031 0.000 leoGlobals.py:6792(<listcomp>) 6570 0.005 0.000 0.013 0.000 <frozen importlib._bootstrap_external>:57(_path_join)
693 0.005 0.000 0.178 0.000 <frozen importlib._bootstrap_external>:743(get_code)
4055 0.005 0.000 0.057 0.000 leoNodes.py:2014(anyAtFileNodeName) 4252 0.005 0.000 0.069 0.000 leoKeys.py:2913(registerCommand)
13517 0.005 0.000 0.007 0.000 sre_parse.py:163(__getitem__)
11685846 function calls (11653798 primitive calls) in 8.145 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
145181 0.208 0.000 0.422 0.000 spellCommands.py:243(add_expanded_line)
# Benchmark: scan_lines is fast. # Cumulative time is a bit surprising. It calls regex methods and the Vnode ctor.
165 0.162 0.001 0.333 0.002 leoAtFile.py:5163(scan_lines)
1829 0.119 0.000 0.230 0.001 sre_parse.py:470(_parse) # Expected.
# Marks big surprises. # These take almost as long as fast_at.scan_line.
679649 0.093 0.000 0.093 0.000 {method ‘add’ of ‘set’ objects}
691 0.088 0.000 0.088 0.000 {built-in method marshal.loads}
5428 0.087 0.000 0.087 0.000 {built-in method winreg.OpenKey}
57936 0.072 0.000 0.100 0.000 ntpath.py:121(splitdrive)
2 0.061 0.030 0.105 0.053 spellCommands.py:132(add_words_from_dict)
1070 0.058 0.000 0.058 0.000 {method ‘splitlines’ of ‘str’ objects}
- 2718 0.042 0.000 0.279 0.000 {built-in method builtins.__build_class__}
1 0.041 0.041 0.655 0.655 mod_scripting.py:521(createAllButtons) #
40356 0.033 0.000 0.101 0.000 leoNodes.py:517(p.self_and_parents)
6 0.031 0.005 0.031 0.005 {method ‘feed’ of ‘xml.etree.ElementTree.XMLParser’ objects}
696 0.028 0.000 0.028 0.000 {method ‘read’ of ‘_io.FileIO’ objects} #
521491 0.138 0.000 0.188 0.000 leoGlobals.py:5551(g.isUnicode) # 212321 0.135 0.000 0.243 0.000 leoGlobals.py:4530(g.match_word) # 355472 0.095 0.000 0.229 0.000 leoGlobals.py:5628(g.toUnicode) #
11373 0.095 0.000 0.095 0.000 leoGlobals.py:2961(<listcomp>) # g.compute_directives_re 10435 0.093 0.000 0.397 0.000 leoGlobals.py:4494(g.is_special) # 11373 0.091 0.000 0.302 0.000 leoGlobals.py:2911(g.get_directives_dict) #
57881 0.048 0.000 0.115 0.000 leoGlobals.py:6958(g.toUnicodeFileEncoding) #
186038 0.044 0.000 0.061 0.000 leoGlobals.py:5579(g.isWordChar) #
204403 0.104 0.000 0.104 0.000 leoNodes.py:198(p.__init__) # Very bad 204235 0.094 0.000 0.198 0.000 leoNodes.py:1338(p.copy) # Very bad 106781 0.091 0.000 0.311 0.000 leoNodes.py:1203(p.moveToThreadNext) # 132602 0.082 0.000 0.214 0.000 leoNodes.py:2228(v.headString) #
72681 0.079 0.000 0.367 0.000 leoCommands.py:812(c.all_unique_positions) # 98137 0.078 0.000 0.105 0.000 leoNodes.py:1150(p.moveToNext) #
122195 0.073 0.000 0.111 0.000 leoNodes.py:780(p.hasNext) # 239756 0.053 0.000 0.053 0.000 leoNodes.py:1025(v._parentVnode) # 119593 0.039 0.000 0.231 0.000 leoNodes.py:654(p.headString) # 119593 0.034 0.000 0.265 0.000 leoNodes.py:1601(p.__get_h) #
55575 0.026 0.000 0.035 0.000 leoNodes.py:1184(p.moveToParent) #
11685846 function calls (11653798 primitive calls) in 8.145 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
# Probably from cProfile, not a big deal…:
1 1.129 1.129 1.305 1.305 {built-in method exec_}
584 1.025 0.002 1.025 0.002 {built-in method __new__ of type object at 0x00000000664AB3F0}
6775 0.219 0.000 0.219 0.000 {built-in method nt.stat}
# Surprise, but not horrible:
145181 0.208 0.000 0.422 0.000 spellCommands.py:243(add_expanded_line) #
# The first benchmark: 165 files scanned in about 0.16 seconds. Very good:
165 0.162 0.001 0.333 0.002 leoAtFile.py:5163(fast_at.scan_lines)
# marks routines that have way too many calls, and add way too much time
# Each of these items adds almost as much time as scan_lines!:
521491 0.138 0.000 0.188 0.000 leoGlobals.py:5551(g.isUnicode) #
212321 0.135 0.000 0.243 0.000 leoGlobals.py:4530(g.match_word) #
35564 0.131 0.000 0.260 0.000 ntpath.py:471(normpath)
1829 0.119 0.000 0.230 0.001 sre_parse.py:470(_parse) # Expected, imo.
585766 0.119 0.000 0.119 0.000 {method 'find' of 'str' objects}
204403 0.104 0.000 0.104 0.000 leoNodes.py:198(__init__)
355472 0.095 0.000 0.229 0.000 leoGlobals.py:5628(g.toUnicode) #
11373 0.095 0.000 0.095 0.000 leoGlobals.py:2961(g.compute_directives_re()) #
204235 0.094 0.000 0.198 0.000 leoNodes.py:1338(p.copy) # Very bad, very surprising.
679649 0.093 0.000 0.093 0.000 {method 'add' of 'set' objects}
10435 0.093 0.000 0.397 0.000 leoGlobals.py:4494(g.is_special) #
11373 0.091 0.000 0.302 0.000 leoGlobals.py:2911(g.get_directives_dict) #
106781 0.091 0.000 0.311 0.000 leoNodes.py:1203(p.moveToThreadNext) # Slow!
# Benchmark: lots of calls, not too much time:
1236269 0.089 0.000 0.089 0.000 {built-in method builtins.len}
...
132602 0.082 0.000 0.214 0.000 leoNodes.py:2228(v.headString) #
72681 0.079 0.000 0.367 0.000 leoCommands.py:812(c.all_unique_positions) #
98137 0.078 0.000 0.105 0.000 leoNodes.py:1150(p.moveToNext) #
122195 0.073 0.000 0.111 0.000 leoNodes.py:780(p.hasNext) #
57936 0.072 0.000 0.100 0.000 ntpath.py:121(splitdrive)
158556 0.069 0.000 0.115 0.000 leoGlobals.py:4585(g.skip_line) #
248025 0.067 0.000 0.067 0.000 {method 'replace' of 'str' objects}
# Another benchmark: about the expected number of calls, and a reasonable time:
12544 0.067 0.000 0.082 0.000 leoNodes.py:1931(v.__init__)
2 0.061 0.030 0.105 0.053 spellCommands.py:132(add_words_from_dict)
393127 0.061 0.000 0.061 0.000 {method 'startswith' of 'str' objects}
1070 0.058 0.000 0.058 0.000 {method 'splitlines' of 'str' objects}
239756 0.053 0.000 0.053 0.000 leoNodes.py:1025(p._parentVnode) #
57881 0.048 0.000 0.115 0.000 leoGlobals.py:6958(g.toUnicodeFileEncoding) # ???
166257 0.046 0.000 0.047 0.000 {built-in method builtins.hasattr}
186038 0.044 0.000 0.061 0.000 leoGlobals.py:5579(g.isWordChar) #
...
# The last benchmarks: Python’s readers are very fast:
6 0.031 0.005 0.031 0.005 {method 'feed' of 'xml.etree.ElementTree.XMLParser' objects}
696 0.028 0.000 0.028 0.000 {method 'read' of '_io.FileIO' objects}
9245840 function calls (9213587 primitive calls) in 7.827 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.727 1.727 2.014 2.014 {built-in method exec_}
584 1.022 0.002 1.022 0.002 {built-in method __new__ of type object at 0x00000000664AB3F0}
6785 0.212 0.000 0.212 0.000 {built-in method nt.stat}
145181 0.184 0.000 0.355 0.000 spellCommands.py:243(add_expanded_line)
165 0.165 0.001 0.337 0.002 leoAtFile.py:5163(scan_lines)
37909 0.139 0.000 0.275 0.000 ntpath.py:471(normpath)
12016 0.099 0.000 0.099 0.000 leoGlobals.py:2988(<listcomp>) # g.compute_directives_re
692 0.081 0.000 0.081 0.000 {built-in method marshal.loads}
97755 0.078 0.000 0.272 0.000 leoNodes.py:1202(moveToThreadNext) # reasonable. 61012 0.076 0.000 0.105 0.000 ntpath.py:121(splitdrive)
12677 0.071 0.000 0.087 0.000 leoNodes.py:1930(__init__) 91198 0.070 0.000 0.094 0.000 leoNodes.py:1149(moveToNext) 73099 0.067 0.000 0.313 0.000 leoCommands.py:812(all_unique_positions) #
113534 0.066 0.000 0.099 0.000 leoNodes.py:779(hasNext) # 258990 0.065 0.000 0.065 0.000 {method ‘replace’ of ‘str’ objects}
2 0.062 0.031 0.107 0.053 spellCommands.py:132(add_words_from_dict) #
1070 0.057 0.000 0.057 0.000 {method ‘splitlines’ of ‘str’ objects}
89903 0.056 0.000 0.114 0.000 leoNodes.py:2226(headString)
61081 0.050 0.000 0.099 0.000 leoGlobals.py:7007(toUnicodeFileEncoding)
224156 0.048 0.000 0.048 0.000 leoNodes.py:1024(_parentVnode) 234204 0.045 0.000 0.045 0.000 {method ‘find’ of ‘str’ objects} 167094 0.043 0.000 0.044 0.000 {built-in method builtins.hasattr}
74688 0.042 0.000 0.042 0.000 leoNodes.py:198(p.__init__) # Improved
385978 0.041 0.000 0.041 0.000 {method ‘append’ of ‘list’ objects}
- 74513 0.039 0.000 0.081 0.000 leoNodes.py:1337(p.copy) # Improved
748 0.038 0.000 0.038 0.000 {built-in method io.open} # Benchmark
122261 0.037 0.000 0.037 0.000 sre_parse.py:232(__next) 298205 0.036 0.000 0.036 0.000 {method ‘strip’ of ‘str’ objects}
695 0.036 0.000 0.061 0.000 <frozen importlib._bootstrap_external>:830(get_data)
9902 0.034 0.000 0.106 0.000 todo.py:525(loadIcons)
748/1 0.034 0.000 7.845 7.845 {built-in method builtins.exec}
246489 0.033 0.000 0.036 0.000 {method ‘get’ of ‘dict’ objects} 329433 0.033 0.000 0.033 0.000 {method ‘lower’ of ‘str’ objects}
2 0.032 0.016 0.397 0.199 spellCommands.py:231(read_words)
- 12629 0.031 0.000 0.050 0.000 leoGlobals.py:6714(os_path_expandExpression)
6 0.031 0.005 0.031 0.005 {method ‘feed’ of ‘xml.etree.ElementTree.XMLParser’ objects}
47 0.030 0.001 0.030 0.001 {method ‘execute’ of ‘sqlite3.Connection’ objects}
124514 0.030 0.000 0.042 0.000 leoGlobals.py:5585(isUnicode) # Improved 118750 0.029 0.000 0.065 0.000 sre_parse.py:253(get)
895 0.029 0.000 0.140 0.000 leoNodes.py:738(get_UNL)
- 87970 0.029 0.000 0.032 0.000 {method ‘join’ of ‘str’ objects}
8 0.027 0.003 0.027 0.003 {built-in method setStyleSheet}
8417 0.027 0.000 0.288 0.000 leoGlobals.py:6833(os_path_join)
76292 0.026 0.000 0.122 0.000 leoNodes.py:652(headString) # 41651 0.026 0.000 0.063 0.000 leoNodes.py:515(self_and_parents) #
695 0.026 0.000 0.026 0.000 {method ‘read’ of ‘_io.FileIO’ objects}
8308 0.025 0.000 0.502 0.000 leoGlobals.py:6793(os_path_finalize_join)
- 54732 0.024 0.000 0.033 0.000 leoNodes.py:1183(moveToParent)
932 0.024 0.000 0.027 0.000 sre_compile.py:250(_optimize_charset)
- 197714 0.023 0.000 0.023 0.000 leoNodes.py:282(__bool__)
50253 0.023 0.000 0.023 0.000 {method ‘match’ of ‘_sre.SRE_Pattern’ objects} 12016 0.023 0.000 0.131 0.000 leoGlobals.py:2981(compute_directives_re) # 20236 0.022 0.000 0.038 0.000 editCommands.py:834(getIconList) 10881 0.022 0.000 0.055 0.000 ntpath.py:74(join) 16381 0.022 0.000 0.338 0.000 re.py:286(_compile)
3598 0.022 0.000 0.370 0.000 leoGlobals.py:2992(get_directives_dict_list) # Improved!
- 76292 0.021 0.000 0.143 0.000 leoNodes.py:1600(__get_h)
541 0.021 0.000 0.021 0.000 {method ‘read’ of ‘_io.BufferedReader’ objects}
- 4731/6 0.021 0.000 0.052 0.009 leoFileCommands.py:2689(v_element_visitor) # benchmark
- 13788 0.021 0.000 0.169 0.000 leoGlobals.py:6766(os_path_expanduser)
6 0.020 0.003 0.107 0.018 leoCommands.py:1317(checkGnxs) # Improved
17125 0.018 0.000 0.031 0.000 nodetags.py:185(get_tags) 13994 0.018 0.000 0.063 0.000 leoNodes.py:1281(safeMoveToThreadNext)
- 5428 0.017 0.000 0.017 0.000 {built-in method winreg.EnumKey}
1 0.017 0.017 0.017 0.017 {msleep}
- 19806 0.017 0.000 0.098 0.000 leoCommands.py:749(all_positions)
4 0.016 0.004 0.016 0.004 {built-in method show}
17/15 0.016 0.001 0.025 0.002 {built-in method _imp.create_dynamic} 62440 0.016 0.000 0.022 0.000 leoGlobals.py:5571(isString) 22448 0.015 0.000 0.018 0.000 leoNodes.py:1116(moveToFirstChild)
3574 0.015 0.000 0.449 0.000 leoCommands.py:1936(scanAtPathDirectives)
19424 0.015 0.000 0.021 0.000 leoNodes.py:1103(moveToBack)
- 140295 0.015 0.000 0.015 0.000 {built-in method nt.fspath}
- 6737 0.015 0.000 0.030 0.000 leoGlobals.py:4593(skip_id)
524 0.015 0.000 0.015 0.000 {built-in method nt._isdir}
1 0.014 0.014 0.134 0.134 mimetypes.py:230(read_windows_registry)
- 11554 0.014 0.000 0.064 0.000 leoNodes.py:1997(findAtFileName)
169 0.014 0.000 0.015 0.000 leoAtFile.py:225(initReadIvars)
38576 0.013 0.000 0.013 0.000 {method ‘split’ of ‘str’ objects} 47187 0.013 0.000 0.023 0.000 leoNodes.py:2597(__get_u)
- 9909 0.013 0.000 0.013 0.000 {built-in method today}
834 0.013 0.000 0.013 0.000 {built-in method winreg.QueryValueEx}
4747 0.012 0.000 0.025 0.000 ntpath.py:199(split) 1406 0.012 0.000 0.925 0.001 leoGlobals.py:3476(fullPath)
2 0.012 0.006 0.017 0.009 QNCalendarWidget.py:35(build) 8 0.011 0.001 0.012 0.001 {built-in method addTab}
27635 0.011 0.000 0.011 0.000 {method ‘finditer’ of ‘_sre.SRE_Pattern’ objects} 13794 0.011 0.000 0.018 0.000 ntpath.py:308(expanduser)
1307 0.011 0.000 0.134 0.000 <frozen importlib._bootstrap_external>:1233(find_spec)
45828 0.011 0.000 0.015 0.000 leoGlobals.py:5617(isWordChar) # 18002 0.011 0.000 0.017 0.000 leoGlobals.py:4540(match)
8200 0.011 0.000 0.015 0.000 leoGlobals.py:4675(skip_ws)
683 0.010 0.000 0.010 0.000 {method ‘decode’ of ‘bytes’ objects}
8006 0.010 0.000 0.059 0.000 leoGlobals.py:6797(<listcomp>)
17124 0.009 0.000 0.053 0.000 leoChapters.py:245(parseHeadline) 17991 0.009 0.000 0.009 0.000 {method ‘search’ of ‘_sre.SRE_Pattern’ objects}
- 25 0.009 0.000 0.009 0.000 {built-in method repaint}
1 0.009 0.009 0.009 0.009 backend.py:71(Backend) 2 0.009 0.004 0.009 0.004 {built-in method setCalendarWidget}
48232 0.009 0.000 0.009 0.000 {method ‘pop’ of ‘list’ objects} 14000 0.009 0.000 0.074 0.000 leoCommands.py:832(safe_all_positions)
721 0.009 0.000 0.009 0.000 {method ‘connect’ of ‘PyQt5.QtCore.pyqtBoundSignal’ objects}
9202 0.009 0.000 0.085 0.000 ntpath.py:538(abspath) 9202 0.008 0.000 0.008 0.000 {built-in method nt._getfullpathname} 4040 0.008 0.000 0.012 0.000 leoMenu.py:247(<listcomp>)
- 184 0.008 0.000 0.008 0.000 {built-in method _hashlib.openssl_md5}
2 0.008 0.004 0.150 0.075 leoChapters.py:318(setAllChapterNames)
8006 0.008 0.000 0.491 0.000 leoCommands.py:1884(os_path_finalize_join) 8712 0.008 0.000 0.014 0.000 leoGlobals.py:4554(match_word) # Much improved
109997 0.008 0.000 0.008 0.000 {method ‘isalnum’ of ‘str’ objects} 9903/1 0.008 0.000 0.185 0.185 todo.py:497(new)
1 0.008 0.008 0.062 0.062 backlink.py:412(loadLinksInt)
37052 0.007 0.000 0.007 0.000 {method ‘lstrip’ of ‘str’ objects} 14946 0.007 0.000 0.012 0.000 {built-in method builtins.getattr}
172 0.007 0.000 0.007 0.000 {built-in method nt.access}
- 17008 0.007 0.000 0.013 0.000 leoNodes.py:2171(bodyString)
6248 0.007 0.000 0.070 0.000 leoGlobals.py:6875(os_path_normpath) 5920 0.007 0.000 0.018 0.000 enum.py:801(__and__)
96311 0.007 0.000 0.007 0.000 {method ‘isspace’ of ‘str’ objects} 12677 0.007 0.000 0.014 0.000 leoNodes.py:102(new_vnode_helper)
5628 0.007 0.000 0.013 0.000 leoGlobals.py:2053(add) 8417 0.007 0.000 0.171 0.000 leoGlobals.py:6850(<listcomp>)
1 0.007 0.007 0.174 0.174 todo.py:519(loadAllIcons)
42452 0.007 0.000 0.007 0.000 {method ‘group’ of ‘_sre.SRE_Match’ objects} 29691 0.006 0.000 0.113 0.000 leoCommands.py:737(all_unique_nodes)
8417 0.006 0.000 0.029 0.000 leoGlobals.py:6841(<listcomp>)
- 10931 0.006 0.000 0.012 0.000 leoGlobals.py:2103(get)
4250 0.006 0.000 0.059 0.000 leoKeys.py:2956(registerCommandShortcut) 2294 0.006 0.000 0.029 0.000 leoAtFile.py:3705(putCodeLine)
- 12946 0.006 0.000 0.007 0.000 enum.py:515(__new__)
5220 0.006 0.000 0.014 0.000 leoAtFile.py:4321(os) 6406 0.006 0.000 0.027 0.000 leoConfig.py:1728(getShortcut)
- 96 0.006 0.000 0.009 0.000 {built-in method builtins.sorted}
1 0.006 0.006 1.403 1.403 leoAtFile.py:703(readAll)
- 4603 0.006 0.000 0.047 0.000 leoGlobals.py:6690(os_path_basename)
1 0.006 0.006 0.040 0.040 qt_gui.py:46(__init__)
16628 0.006 0.000 0.024 0.000 leoNodes.py:1571(__get_b)
- 1928 0.005 0.000 0.281 0.000 leoConfig.py:1898(visitNode)
167 0.005 0.000 0.047 0.000 leoGlobals.py:3711(readFileIntoString)
- 16628 0.005 0.000 0.018 0.000 leoNodes.py:649(bodyString)
7 0.005 0.001 0.058 0.008 leoKeys.py:2264(makeBindingsFromCommandsDict)
749 0.005 0.000 0.156 0.000 <frozen importlib._bootstrap>:870(_find_spec)
- 15370 0.005 0.000 0.334 0.000 re.py:231(compile)
8853 0.005 0.000 0.008 0.000 leoGlobals.py:4606(skip_line) # Much improved.
- 12677 0.005 0.000 0.007 0.000 leoNodes.py:45(check_gnx)
- 693 0.005 0.000 0.007 0.000 <frozen importlib._bootstrap_external>:430(_validate_bytecode_header)
1 0.005 0.005 0.005 0.005 qt_gui.py:879(getIconImage)
- 4267 0.005 0.000 0.055 0.000 leoNodes.py:2012(anyAtFileNodeName)
19 0.005 0.000 0.055 0.003 leoCommands.py:1181(setChanged)
693 0.005 0.000 0.194 0.000 <frozen importlib._bootstrap_external>:743(get_code)
- 4250 0.005 0.000 0.065 0.000 leoKeys.py:2913(registerCommand)
2 0.005 0.002 0.005 0.002 {built-in method minimumSizeHint}
- 13566 0.005 0.000 0.007 0.000 sre_parse.py:163(__getitem__)
171 0.005 0.000 0.026 0.000 leoExternalFiles.py:334(checksum)
- 1386 0.005 0.000 0.014 0.000 <frozen importlib._bootstrap_external>:263(cache_from_source)
6 0.005 0.001 0.005 0.001 leoFileCommands.py:2655(scanTnodes)
6570 0.005 0.000 0.012 0.000 <frozen importlib._bootstrap_external>:57(_path_join)
- 12956 0.005 0.000 0.013 0.000 enum.py:265(__call__)
84 0.005 0.000 0.005 0.000 {built-in method nt.listdir}
- 1034 0.005 0.000 0.008 0.000 <frozen importlib._bootstrap>:157(_get_module_lock)
- 80 0.005 0.000 0.007 0.000 qt_frame.py:4354(__init__)
1 0.004 0.004 0.078 0.078 backlink.py:116(fixIDs)
4265 0.004 0.000 0.008 0.000 leoConfig.py:1129(canonicalizeSettingName)
- 17694 0.004 0.000 0.004 0.000 leoGlobals.py:539(__hash__)
165 0.004 0.000 0.657 0.004 leoAtFile.py:464(read)
- 16834 0.004 0.000 0.004 0.000 {built-in method builtins.min}
6570 0.004 0.000 0.006 0.000 <frozen importlib._bootstrap_external>:59(<listcomp>)
- 17862 0.004 0.000 0.004 0.000 leoGlobals.py:2038(_checkKeyType)
- 82 0.004 0.000 0.008 0.000 <frozen importlib._bootstrap_external>:1067(_path_hooks)
1 0.004 0.004 0.063 0.063 nodetags.py:175(get_tagged_gnxes) 1 0.004 0.004 0.062 0.062 nodetags.py:140(initialize_taglist)
1928 0.004 0.000 0.016 0.000 leoConfig.py:713(parseHeadline)
- 23391 0.004 0.000 0.004 0.000 leoNodes.py:775(hasBack)
2 0.004 0.002 0.021 0.011 QNCalendarWidget.py:20(__init__)
876 0.004 0.000 0.150 0.000 leoConfig.py:845(set)
165 0.004 0.000 0.010 0.000 leoAtFile.py:5120(post_pass) 714 0.004 0.000 0.018 0.000 <frozen importlib._bootstrap>:504(_init_module_attrs)
6286 0.004 0.000 0.007 0.000 leoGlobals.py:458(write) 9902 0.003 0.000 0.021 0.000 editCommands.py:842(setIconList) 5428 0.003 0.000 0.021 0.000 mimetypes.py:243(enum_types)
6 0.003 0.001 0.110 0.018 leoCommands.py:1516(checkOutline)
- 145181 g.isUnicode:__init__,read_words,add_expanded_line,toUnicode
66369 g.isUnicode:__get_h,headString,headString,toUnicode 52902 g.isUnicode:get_UNL,__get_h,headString,headString 11400 g.isUnicode:munge,os_path_normpath,toUnicodeFileEncoding,toUnicode
8924 g.isUnicode:shortFileName,os_path_basename,toUnicodeFileEncoding,toUnicode 7744 g.isUnicode:get_directives_dict,__get_b,bodyString,bodyString 7488 g.isUnicode:<listcomp>,os_path_expanduser,toUnicodeFileEncoding,toUnicode 7449 g.isUnicode:anyAtFileNodeName,findAtFileName,headString,toUnicode 6986 g.isUnicode:v_element_visitor,v_element_visitor,v_element_visitor,v_element_visitor 6539 g.isUnicode:os_path_finalize_join,<listcomp>,os_path_expandExpression,toUnicode 5643 g.isUnicode:get_directives_dict,__get_h,headString,headString
4841 g.isUnicode:isAnyAtFileNode,isAnyAtFileNode,headString,toUnicode 4797 g.isUnicode:idle_check_commander,isAnyAtFileNode,isAnyAtFileNode,headString 4580 g.isUnicode:os_path_finalize_join,os_path_join,toUnicodeFileEncoding,toUnicode 4565 g.isUnicode:anyAtFileNodeName,findAtFileName,skip_id,toUnicode 4044 g.isUnicode:anyAtFileNodeName,anyAtFileNodeName,findAtFileName,headString 3405 g.isUnicode:isAnyAtFileNode,anyAtFileNodeName,findAtFileName,headString 2489 g.isUnicode:createAllButtons,__get_h,headString,headString 2280 g.isUnicode:parse,parse,feed,characters 2054 g.isUnicode:visitNode,__get_h,headString,headString 1866 g.isUnicode:putLine,putCodeLine,onl,os 1747 g.isUnicode:visitNode,parseHeadline,skip_id,toUnicode 1715 g.isUnicode:putBody,putLine,putCodeLine,os 1302 g.isUnicode:parseHeadline,__get_h,headString,headString
==== After 1
- 52902 g.isUnicode:get_UNL,__get_h,headString,headString
7459 g.isUnicode:get_directives_dict,__get_b,bodyString,bodyString 6986 g.isUnicode:v_element_visitor,v_element_visitor,v_element_visitor,v_element_visitor 5423 g.isUnicode:get_directives_dict,__get_h,headString,headString 3919 g.isUnicode:anyAtFileNodeName,anyAtFileNodeName,findAtFileName,headString 2489 g.isUnicode:createAllButtons,__get_h,headString,headString 2280 g.isUnicode:parse,parse,feed,characters 2132 g.isUnicode:idle_check_commander,isAnyAtFileNode,isAnyAtFileNode,headString 2054 g.isUnicode:visitNode,__get_h,headString,headString 1866 g.isUnicode:putLine,putCodeLine,onl,os 1715 g.isUnicode:putBody,putLine,putCodeLine,os 1550 g.isUnicode:isAnyAtFileNode,anyAtFileNodeName,findAtFileName,headString 1302 g.isUnicode:parseHeadline,__get_h,headString,headString
===== After 2
- 10 g._toUnicode:read,openFileForReading,readFileToUnicode,toUnicode
7 g._toUnicode:readAll,readOneAtCleanNode,read_at_clean_lines,toUnicode 6 g._toUnicode:openLeoFile,getLeoFile,readFile,toUnicode 5 g._toUnicode:read,read_into_root,readFileIntoString,toUnicode 3 g._toUnicode:read_into_root,readFileIntoString,getPythonEncodingFromString,toUnicode 2 g._toUnicode:__init__,__init__,read_words,toUnicode 1 g._toUnicode:createOutline,init_import,readFileIntoString,toUnicode
584 g.is_special:readExternalFiles,readAll,isAtIgnoreNode,isAtIgnoreNode 474 g.is_special:putVnode,putVnode,isAtIgnoreNode,isAtIgnoreNode 134 g.is_special:onCreate,createAllButtons,isAtIgnoreNode,isAtIgnoreNode
43 g.is_special:putVnodes,putVnode,isAtIgnoreNode,isAtIgnoreNode 32 g.is_special:visitNode,doCommands,isAtIgnoreNode,isAtIgnoreNode
6 g.is_special:visitNode,doButtons,isAtIgnoreNode,isAtIgnoreNode 5 g.is_special:findReference,findReference,isAtIgnoreNode,isAtIgnoreNode
# After s.bat.
# Yikes: createAllButtons takes a long time. 244179 g.match_word:createAllButtons,isAtIgnoreNode,isAtIgnoreNode,is_special
76017 g.match_word:doHandlersForTag,callTagHandler,onCreate,createAllButtons 16801 g.match_word:onCreate,createAllButtons,isAtIgnoreNode,isAtIgnoreNode
# Nothing else matters much… 7540 g.match_word:writeFromString,writeOpenFile,putBody,directiveKind4 2861 g.match_word:readAll,isAtIgnoreNode,isAtIgnoreNode,is_special 2572 g.match_word:putVnode,isAtIgnoreNode,isAtIgnoreNode,is_special 1824 g.match_word:fullPath,anyAtFileNodeName,anyAtFileNodeName,findAtFileName 1646 g.match_word:putLine,putAtOthersLine,putBody,directiveKind4 1089 g.match_word:isAnyAtFileNode,isAnyAtFileNode,anyAtFileNodeName,findAtFileName
===== After
7540 g.match_word:writeFromString,writeOpenFile,putBody,directiveKind4 1646 g.match_word:putLine,putAtOthersLine,putBody,directiveKind4 1645 g.match_word:fullPath,anyAtFileNodeName,anyAtFileNodeName,findAtFileName
76528 p.__init__:fullPath,get_directives_dict_list,self_and_parents,copy 31818 p.__init__:readAll,fullPath,get_directives_dict_list,copy
2196 p.__init__:idle_check_at_file_node,fullPath,get_directives_dict_list,copy
30701 p.__init__:safe_all_positions,safeMoveToThreadNext,self_and_parents,copy 30158 p.__init__:fixIDs,all_unique_nodes,all_unique_positions,copy 22121 p.__init__:setChanged,all_unique_nodes,all_unique_positions,copy 24422 p.__init__:checkOutline,checkGnxs,safe_all_positions,copy 19398 p.__init__:readAll,fullPath,self_and_parents,copy 15079 p.__init__:finishCreate,setAllChapterNames,all_unique_positions,copy 14756 p.__init__:find_at_persistence_node,findNodeAnywhere,all_unique_positions,copy 17211 p.__init__:new,loadAllIcons,all_positions,copy 12537 p.__init__:readExternalFiles,restoreDescendentAttributes,all_unique_positions,copy 10726 p.__init__:getLeoFile,resolveTnodeLists,all_unique_positions,copy
9991 p.__init__:contractAllHeadlinesCommand,contractAllHeadlines,all_positions,copy 5008 p.__init__:set,get_UNL,self_and_parents,copy 4327 p.__init__:putVnodes,clearAllVisited,all_unique_positions,copy
9315 p.__init__:doBool,set,get_UNL,copy 6745 p.__init__:doColor,set,get_UNL,copy 6004 p.__init__:doString,set,get_UNL,copy 1973 p.__init__:createSettingsDicts,traverse,visitNode,copy 1706 p.__init__:doData,set,get_UNL,copy 1563 p.__init__:doInt,set,get_UNL,copy 1531 p.__init__:eventFilter,__get_p,currentPosition,copy 1129 p.__init__:drawChildren,drawNode,rememberItem,copy 1120 p.__init__:visitNode,set,get_UNL,copy 1001 p.__init__:doFont,set,get_UNL,copy
This branch incorporates Vitalije’s great new read code. This code reads external files (from @file nodes) almost exactly as fast as when using the cacher.
As a result, file caching is no longer needed, The –no-cache option is gone.
** Highlights of the fast-read branch **
It includes the no-sax branch. That is, the fast-read branch contains new code for reading both external files and .leo files.
Caching has been radically simplified:
No file caching whatever is done. The cache contains only non-essential items, such as marked and expanded bits.
~/.leo/db now contains only two sub-folders: g_app_db and global_data. g_app_db corresponds to the old “global” folder. It contains the cached result of g.app.db. The global_data folder contains all expanded and marked bits, plus some other data. The keys are simply the full path names of each .leo file. This should be safe enough.
Leo writes only a vestigial <globals> element in .leo files. This should be enough to allow old (Leo 4.5 and above) versions of Leo to read .leo files.
Leo no longer writes expanded and marked bits to the root node of @file trees.
As a result of 2, 3 and 4, all Leo files are essentially “fixed”. Their contents will change much less often than before. As a result, the c.fixed switch has been eliminated, along with the @bool fixedwindow setting.
The g.enableDB switch has been eliminated. The –no-cache command-line argument has been deprecated.
Summary
Leo now works as if –no-cache were permanently in effect. In other words, Leo always recreates outlines directly from external files. This eliminates an important source of confusion.
Leo’s new read code is almost exactly as fast as reading cached data, a remarkable accomplishment.
Leo no longer pollutes .leo files with non-essential data, resulting in fewer diffs of .leo files.
Code
This branch greatly reduces overhead during startup.
All generators yielding positions now accept a “copy” kwarg.
The default value is True, for compatibility with user scripts.
When True, these generators yield copies of all positions.
Leo’s core sets copy=False in several places, greatly reducing unnecessary positions.
g.isUnicode and g.toUnicode are simpler and faster.
Rewrote g.is_special, greatly reduced calls to g.match_words.
# get_UNL makes way too many copies.
- 11831 p.copy:visitNode,doBool,set,get_UNL
6827 p.copy:visitNode,doColor,set,get_UNL 9217 p.copy:doBool,set,get_UNL,getBack 6717 p.copy:visitNode,doString,set,get_UNL 4581 p.copy:doString,set,get_UNL,getBack 4287 p.copy:doColor,set,get_UNL,getBack 2470 p.copy:visitNode,doData,set,get_UNL 2089 p.copy:visitNode,doInt,set,get_UNL 1986 p.copy:doData,set,get_UNL,getBack 1673 p.copy:doInt,set,get_UNL,getBack 1668 p.copy:doBool,set,get_UNL,self_and_parents 1503 p.copy:doColor,set,get_UNL,self_and_parents 1477 p.copy:traverse,visitNode,set,get_UNL 1282 p.copy:doString,set,get_UNL,self_and_parents 1183 p.copy:visitNode,set,get_UNL,getBack 1001 p.copy:visitNode,doFont,set,get_UNL
6828 p.copy:readAll,fullPath,get_directives_dict_list,self_and_parents 4303 p.copy:putLeoOutline,putVnodes,clearAllVisited,all_unique_positions 4220 p.copy:checkGnxs,safe_all_positions,safeMoveToThreadNext,self_and_parents 4183 p.copy:getLeoFile,checkOutline,checkGnxs,safe_all_positions 4080 p.copy:openLeoFile,getLeoFile,resolveTnodeLists,all_unique_positions 3762 p.copy:readExternalFiles,readAll,fullPath,get_directives_dict_list 2372 p.copy:readExternalFiles,readAll,fullPath,self_and_parents 2054 p.copy:computeLocalSettings,createSettingsDicts,traverse,visitNode
67470 p.copy:readAll,fullPath,get_directives_dict_list,self_and_parents 31172 p.copy:readExternalFiles,readAll,fullPath,get_directives_dict_list
30497 p.copy:checkGnxs,safe_all_positions,safeMoveToThreadNext,self_and_parents
24119 p.copy:getLeoFile,checkOutline,checkGnxs,safe_all_positions
18974 p.copy:readExternalFiles,readAll,fullPath,self_and_parents 17110 p.copy:__init__,new,loadAllIcons,all_positions 15083 p.copy:finishOpen,finishCreate,setAllChapterNames,all_unique_positions 14756 p.copy:update_after_read_foreign_file,find_at_persistence_node,findNodeAnywhere,all_unique_positions 10423 p.copy:openLeoFile,getLeoFile,resolveTnodeLists,all_unique_positions
4327 p.copy:putLeoOutline,putVnodes,clearAllVisited,all_unique_positions 3983 p.copy:getLeoFile,readExternalFiles,restoreDescendentAttributes,all_unique_positions 3264 p.copy:idle_check_at_file_node,fullPath,get_directives_dict_list,self_and_parents 1973 p.copy:computeLocalSettings,createSettingsDicts,traverse,visitNode 1559 p.copy:openFileForReading,fullPath,get_directives_dict_list,self_and_parents 1464 p.copy:idle_check_commander,idle_check_at_file_node,fullPath,get_directives_dict_list
1264 p.copy:visitNode,doColor,set,get_UNL 1113 p.copy:visitNode,doBool,set,get_UNL 1050 p.copy:visitNode,doString,set,get_UNL
6828 p.copy:readAll,fullPath,get_directives_dict_list,self_and_parents 4303 p.copy:putLeoOutline,putVnodes,clearAllVisited,all_unique_positions 4220 p.copy:checkGnxs,safe_all_positions,safeMoveToThreadNext,self_and_parents 4183 p.copy:getLeoFile,checkOutline,checkGnxs,safe_all_positions 4080 p.copy:openLeoFile,getLeoFile,resolveTnodeLists,all_unique_positions 3762 p.copy:readExternalFiles,readAll,fullPath,get_directives_dict_list 2372 p.copy:readExternalFiles,readAll,fullPath,self_and_parents 2054 p.copy:computeLocalSettings,createSettingsDicts,traverse,visitNode
1307 p.copy:visitNode,doBool,set,get_UNL 1270 p.copy:visitNode,doColor,set,get_UNL 1068 p.copy:visitNode,doString,set,get_UNL
# After changing p.safeMoveToThreadNext, g.get_directives_dict_list, c.checkGnxs.
4303 p.copy:putLeoOutline,putVnodes,clearAllVisited,all_unique_positions
4080 p.copy:openLeoFile,getLeoFile,resolveTnodeLists,all_unique_positions
3762 p.copy:readExternalFiles,readAll,fullPath,get_directives_dict_list 2372 p.copy:readExternalFiles,readAll,fullPath,self_and_parents 1881 p.copy:readAll,fullPath,get_directives_dict_list,self_and_parents
2054 p.copy:computeLocalSettings,createSettingsDicts,traverse,visitNode 1307 p.copy:visitNode,doBool,set,get_UNL 1270 p.copy:visitNode,doColor,set,get_UNL 1068 p.copy:visitNode,doString,set,get_UNL
# These copies are essential.
# self_and_parents makes one copy, so this also is minimal.
This is the presently active commander, that is, g.app.log.c.
This is an important simplification of the code.
Leo now redraws the screen only once during startup.
Removed qtree.update_appearance and qtree.update_appearance_idle.
In fact, this setting has existed for a long time.
Commands that DO use the printer:
print-body print-html print-node print-expanded-body print-expanded-html print-marked-bodies print-marked-html print-marked-nodes print-tree-bodies print-tree-html print-tree-nodes
Commands that DON’T use the printer:
gc-show-summary show-all-uas show-bindings show-buttons show-commands show-focus show-node-uas show-plugin-handlers show-plugins-info show-settings show-stats show-style-sheet
The present code converts a straight quote (single or double) to an opening curly quote if the cursor is at the start of a line or if a blank or tab precedes the cursor. Otherwise, the code converts a straight quote (single or double) to a closing curly quote.
Better tracing if the cursor gui fails to load.
This is for debugging only.
https://groups.google.com/forum/#!topic/leo-editor/Nun7rRRhato
This command just calls g.printStats, which prints the contents of g.app.statsDict.
Put the following snippet at the start of any function/method you wish to profile:
if not g.app.statsLockout:
g.app.statsLockout = True
try:
d = g.app.statsDict
key = 'g.isUnicode:' + g.callers()
d [key] = d.get(key, 0) + 1
finally:
g.app.statsLockout = False
To see the stats, restart Leo, then do show-stats.
This pattern produces superb statistics that show how many times the callers of a routine called the routine. Here are before/after statistics for g.match_word:
# Yikes: createAllButtons takes a long time.
244179 g.match_word:createAllButtons,isAtIgnoreNode,isAtIgnoreNode,is_special
76017 g.match_word:doHandlersForTag,callTagHandler,onCreate,createAllButtons
16801 g.match_word:onCreate,createAllButtons,isAtIgnoreNode,isAtIgnoreNode
# Nothing else matters much...
7540 g.match_word:writeFromString,writeOpenFile,putBody,directiveKind4
2861 g.match_word:readAll,isAtIgnoreNode,isAtIgnoreNode,is_special
2572 g.match_word:putVnode,isAtIgnoreNode,isAtIgnoreNode,is_special
1824 g.match_word:fullPath,anyAtFileNodeName,anyAtFileNodeName,findAtFileName
1646 g.match_word:putLine,putAtOthersLine,putBody,directiveKind4
1089 g.match_word:isAnyAtFileNode,isAnyAtFileNode,anyAtFileNodeName,findAtFileName
# After improvements...
7540 g.match_word:writeFromString,writeOpenFile,putBody,directiveKind4
1646 g.match_word:putLine,putAtOthersLine,putBody,directiveKind4
1645 g.match_word:fullPath,anyAtFileNodeName,anyAtFileNodeName,findAtFileName
https://groups.google.com/forum/#!topic/leo-editor/09H5wX1QRxw
Added .latex and *.sty files, would automatically be recognized as LaTeX.
Leo 5.5 March 23, 2017
[Leo](https://leo-editor.github.io/leo-editor/) 5.5 is now available on [SourceForge](https://sourceforge.net/projects/leo/files/Leo/) and on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
Simulating Leo’s features in Vim, Emacs or Eclipse is possible, just as it is possible to simulate Python in assembly language…
The highlights of Leo 5.5
Syntax coloring is 20x faster than before. The “big-text” hack is no longer needed.
Leo’s importers are now line/token oriented, allowing them to handle languages like javascript more robustly.
New perl and javascript importers.
Pylint now runs in the background.
Pyflakes can optionally check each file as it is written.
Greatly simplified argument-handling for interactive commands.
Documented how to do Test-Driven Development in Leo.
Links
[Leo’s home page](https://leo-editor.github.io/leo-editor/)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
The horrible big text hack is no longer needed.
Fixes #273: Qt Bug involving large text nodes.
Completes #365: Use pyzo syntax coloring.
Revolutionizes Leo’s approach to Qt’s QSyntaxHighlighter class. Everything happens automatically. When changing nodes, Leo need only re-init the underlying jEdit colorizing code so that the proper language is colorized.
No need for any of the interface in the ColorizerMixin class. No need to “lock out” coloring: it happens automatically whenever Leo’s body pane changes! Heh. As I write this I see that colorizer.colorize is no longer ever called!
I don’t think I have ever misunderstood a class as badly as I have misunderstood QSyntaxHighlighter class. Set up and used properly, it is an amazing helper. To be fair, Leo uses this class in a very unusual manner. The mistake I made was subtle, and the Qt documents don’t warn against it.
The performance bug created by calling QSyntaxHighlighter explicitly caused a “series of unfortunate events” ;-) Seeing the speed pyzo’s pure python syntax colorer was the key breakthrough.
Enabled using @bool run-pyflakes-on-write = True
https://groups.google.com/d/msg/leo-editor/RDi2jffWjzI/K-mh4H5QBQAJ
The new javascript and perl importers know nothing about parsing. They know only about how to scan tokens accurately. The importers copy only entire lines from the text file to Leo nodes. As a result, the new importers much more reliable than previous importers.
New in Leo 5.5: optionally colorize doc parts using reStructuredText
Added @bool color-doc-parts-as-rest
The only changes were to match_doc_part and its restarter.
For example, execute-script will work on the following node:
@language rest
Comments...
@language python
print('hi')
@language md
More comments...
@language python
print('abc')
The new g.extractExecutableString function removes all lines that are in the range of @language rest/md/markdown. It truncates the script, with a warning, if it sees two “executable” @language directives, such as C and Python.
Note: Even if a node contains multiple executable languages, the user can select a range of lines to execute. All will be well, provided the selected text contains at most one executable language.
leo-editor/leo-editor#334 This was a large project. See the issue tracker for extensive notes.
Full documentation is here: leo-editor/leo-editor
New, line-oriented scanning code in leo/importers/linescanner.py replaces old, character-oriented, code in leo/importers/basescanner.py.
The xml and html importers now regularize whitespace. xml and html are outliers because they have neither explicit brackets nor strict indentation rules.
Leo no longer hangs waiting for this command to finish. leo-editor/leo-editor#328
Here is the docstring for k.get1Arg, which also discusses k.getNextArg:
k.get1Arg: Handle the next character the user types when accumulating a user argument from the minibuffer. Ctrl-G will abort this processing at any time.
Commands should use k.get1Arg to get the first minibuffer argument and k.getNextArg to get all other arguments.
Before going into the many details, let’s look at some examples. This code will work in any class having a ‘c’ ivar bound to a commander.
Example 1: get one argument from the user:
@cmd(‘my-command’) def myCommand(self, event):
k = self.c.k k.setLabelBlue(‘prompt: ‘) k.get1Arg(event, handler=self.myCommand1)
- def myCommand1(self, event):
k = self.c.k # k.arg contains the argument. # Finish the command. … # Reset the minibuffer. k.clearState() k.resetLabel() k.showStateAndMode()
Example 2: get two arguments from the user:
@cmd(‘my-command’) def myCommand(self, event):
k = self.c.k k.setLabelBlue(‘first prompt: ‘) k.get1Arg(event, handler=self.myCommand1)
- def myCommand1(self, event):
k = self.c.k self.arg1 = k.arg k.setLabelBlue(‘second prompt: ‘) k.getNextArg(handler=self.myCommand2)
- def myCommand2(self, event):
k = self.c.k # k.arg contains second argument. # Finish the command, using self.arg1 and k.arg. … # Reset the minibuffer. k.clearState() k.resetLabel() k.showStateAndMode()
k.get1Arg and k.getNextArg are a convenience methods. They simply pass their arguments to the get_arg method of the singleton GetArg instance. This docstring describes k.get1arg and k.getNextArg as if they were the corresponding methods of the GetArg class.
k.get1Arg is a state machine. Logically, states are tuples (kind, n, handler) though they aren’t represented that way. When the state machine in the GetArg class is active, the kind is ‘getArg’. This constant has special meaning to Leo’s key-handling code.
The arguments to k.get1Arg are as follows:
event: The event passed to the command.
when the user completes the argument by typing <Return> or (sometimes) <tab>.
tabList=[]: A list of possible completions.
completion=True: True if completions are enabled.
oneCharacter=False: True if k.arg should be a single character.
stroke=None: The incoming key stroke.
False allows sort-lines, for example, to show the selection range.
Added reload-settings command. This does style-reload automatically.
leo-editor/leo-editor#343 Exception creating path” error when evaluating a path with accents in a @clean expression
The fix was to g.os_path_expandExpression.
This setting was used: @string view-rendered-default-kind
Added “use_default” keyword arg to BaseColorizer.scanLanguageDirectives.
vr.get_kind sets use_default to False, and uses the setting by default.
leo-editor/leo-editor#348 XML CDATA Sections not preserved on round-trip save
ssm.expand_css_constants no longer adds constants.
leo-editor/leo-editor#352 Importer unit tests create both @clean and @file
The fix was disappointingly simple: just init ic.treeType in ic.createOutline and ic.scannerUnitTest.
createCommonButton now sets the gnx for AtButtonCallback.
QtIconBarClass.goto_command now completes the selection at idle time. There seems to be no way to do this in one step.
Note: ScriptingController.open_gnx uses g.openWithFileName to open settings files. So the focus problem is pretty strange.
The fix was to extractExecutableString
leo-editor/leo-editor#374 This caused problems in the importers.
leo-editor/leo-editor#380 New colorizing code doesn’t update properly after changing @language directives.
Added g.getEncodingAt(p)
The problem:
abbrev.init_tree_abbrev changes the outline’s changed indicator (*) during startup. Simply reversing this in c.new causes the * to flip back and forth.
The changes were a bit tricky:
init_tree_abbrev calls c.pasteOutline(…,redrawFlag=False)
pasteOutline calls c.setChanged(True, redrawFlag=redrawFlag)
c.new calls c.setChanged(False)
Added redrawFlag keyword arg to c.setChanged. When this is false, c.setChanged does not alter the outline’s changed indicator.
Suppressing the change indicator is a bit dangerous. It could be very confusing if the indicator gets out of sync with reality. But the fix should actually be safe enough, because only startup code is affected.
See the checkin log for details.
https://stackoverflow.com/questions/3254652/ several-ways-of-placing-an-image-in-a-qtextedit
Added g.input_, but this is not a great solution.
The fix was to v.atFileNodeName. It must recognize @thin as an @file node.
c.recursiveImport uncaught exception on broken (linux) symlinks leo-editor/leo-editor#408
The fix was to restore disabled code in jedit.colorRangeWithTag.
The fix, as expected, was to k.stroke2char.
Added a kludge in dehoistCallback that satisfies k.registerCommand.
Fixed #427: multiple vnodes with (same) gnx… All tests pass.
c.pasteOutline does not call c.checkOutline when tempOutline is True.
Also fixed several tree-drawing problems:
Refactored abbrev.init_tree_abbrev to suppress unwanted redraws.
Fixed an unrelated bug in abbrev.paste_tree. It must redraw the tree.
c.reloadSettingsHelper no longer redraws the tree.
goto.get_external_file_with_sentinels now calls the new g.composeScript.
Rewrote g.extractExecutableString. It now returns all lines under control of a given language.
leo-editor/leo-editor#430 rst import: titles with different underline characters on same level.
Create importer/writer tables only once, during startup. All tests pass. This resulted in a cascade of simplifications.
Moved ivars and methods from leoAtFile.py and leoImport.py into the LeoApp class: - Added atAutoWritersDict, writersDispatchDict, atAutoDict and classDispatchDict ivars. - Added createAllImporetersData and its two helpers. - Added scanner_for_at_auto and scanner_for_ext.
leoPersistence.py: - Moved ConvertController class to the attic. - Moved pd.convert_at_file_to_at_auto to the attic. - Moved pd.prepass & helper to the attic.
As a result, the prepass argument to the importers is no more.
leoTest.py: - All unit tests now restore the screen when done.
leo/plugins/linescanner.py: - Removed the prepass keyword arg and related logic from i.run.
plugins/qt_frame.py: - Added a disabled trace to createAtFileNode code, called from the drag/drop logic.
Added a guard to fc.parse_leo_file. This is defensive coding.
Changed sf.copy_to_my_settings to reflect recent changes to p.getUnl.
It suffers from mysterious bugs.
A recent in doPlainChar change to handle #14 ruined bracket matching.
The proper place to init settings is in write_rst_tree. rst.rst3 simply inits the file count, n_written
- File “c:leo.repoleo-editorleocoreleoKeys.py”, line 414, in auto_completer_state_handler
kind), color=’red’)
TypeError: putStatusLine() got an unexpected keyword argument ‘color’
It can now import demo-it.el.
Changed LM.openEmptyWorkBook and LM.computeWorkbookFileName.
The new code uses the new importer code to clean nodes.
Passing parent=None to ic.createOutline puts the imported node as the last top-level node. Changed ic.create_top_node, ic.setDefaultDirectory and undo.createCommonBunch.
g.getEncodingAt now uses a BOM if it exists. No warning is given.
ic.scanUnknownFileType no longer adds @ignore. No idea why it ever did.
This was an irritating hangnail that affected, for example, the pylint command.
g.openUrlOnClick now catches all exception.
More generally, added @g.callback decorator, which does the same.
g.findRootsWithPredicate now preserves node order.
https://groups.google.com/d/msg/leo-editor/kmj7wQq7qTk/5U9hSTswBQAJ
The singleton g.app.backgroundProcessManager instance of the BackgroundProcessManager (BPM) class handles all details of running separate processes in the background without blocking Leo.
The BPM manages a queue of background processes, and runs them one after another in the background. It registers a handler with the IdleTimeManager that checks to see if the presently running background process has completed. If so, it writes its output to the log and starts another background process in the queue.
Because only one background process from the queue is ever running, the background processes can write their output to Leo’s log without the output becoming intermixed.
You can kill all processes by calling BPM.kill(). That’s what kill-pylint does. You can add processes to the queue at any time. For example, you can rerun the pylint command while a background process is running.
The BackgroundProcessManager is completely safe: all of its code runs in the main process.
c.all_roots, c.all_unique_roots, p.nearest_roots, p.nearest_unique_roots (aka p.nearest)
Useful for finding nodes on which to run commands.
‘’’ A generator yielding all the root positions “near” p1 = self that satisfy the given predicate. p.isAnyAtFileNode is the default predicate.
The search first proceeds up the p’s tree. If a root is found, this generator yields just that root.
Otherwise, the generator yields all nodes in p.subtree() that satisfy the predicate. Once a root is found, the generator skips its subtree. ‘’’
Added g.findRootWithPredicate, an important helper. Used it to greatly rst.processTopTree, pyflakes.run, and pylint.run. This improves the rst3 command
Leo’s pyflakes and pylint commands can be applied to files that depend on the presently selected node. They first search down c.p’s tree, then up the tree, looking for @<file> nodes. If no nodes are found, and c.p is a clone, these commands expand the search to the entire tree, looking for an @<file> node that has c.p in its tree.
g.findRootWithPredicate now formalizes and regularizes this search process. For example:
def predicate(p):
return p.isAnyAtFileNode() and p.h.strip().endswith('.py')
roots = g.findRootsWithPredicate(c, root, predicate)
I added this helper because the rst3 command was not as clever as the pylint and pyflakes commands in this regard. Now it is. It would have been unbearable to repeat the pylint/pyflakes code one more time…
Here is g.findRootWithPredicate:
def findRootsWithPredicate(c, root, predicate):
'''
Commands often want to find one or more **roots**, given a position p.
A root is the position of any node matching a predicate.
This function formalizes the search order used by the pylint, pyflakes and
the rst3 commands, returning a list of zero or more found roots.
'''
roots = set()
# 1. Search p's tree.
for p in root.self_and_subtree():
if predicate(p):
roots.add(p.copy())
if roots:
return list(roots)
# 2. Look up the tree.
for p in root.parents():
if predicate(p):
return [p.copy()]
# 3. Expand the search if root is a clone.
clones = []
for p in root.self_and_parents():
if p.isCloned():
clones.append(p.v)
if clones:
for p in c.all_positions():
if predicate(p):
# Match if any node in p's tree matches any clone.
for p2 in p.self_and_subtree():
if p2.v in clones:
return [p.copy()]
return []
https://groups.google.com/d/msg/leo-editor/hJWv-nL-9s0/2QbaGBgtBQAJ
leoApp.py now contains the IdleTimeManager (ITM) class, with a singleton instance, g.app.idleTimeManager. This class handles all details of running code at idle time, including running ‘idle’ hooks.
The new encapsulation has simplified code all over Leo:
ITM ivars replace several LeoApp ivars.
LM.load now calls g.app.idleTimeManager.start() to start idle-time processing, leaving all the details to the ITM class.
The g.idle time functions in leoGlobals.py now simply set g.app.idle_time_hooks_enabled. This is the only other remaining LeoApp ivar pertaining to idle-time processing.
To schedule code for running at idle time, code calls g.app.idleTimeManager.add_callback(callback).
Details
leoApp.py: - ITM.on_idle now handles idle-hooks. - Removed g.app.idle_timer. - ‘idle’ hooks called if and only if g.app.idle_time_hooks_enabled is True. - Only one timer is ever started by Leo: g.app.idle_time_manager_timer. - Removed call to g.enableIdleTimeHook in at the end of LM.doPostPluginsInit.
It is not needed: g.app.idle_time_hooks_enabled is True initially.
The enable/disable/toggle-idle-time-events commands now just set g.app.idle_time_hooks_enabled.
leoGlobals.py: - g.enable/disableIdleTimeHook now just set g.app.idle_time_hooks_enabled.
They remain for compatibility only.
g.idleTimeHookHandler is now a stub. It just prints a warning. The original has been moved to the attic (leoNotes.txt).
All of Leo’s generators yielding positions automatically yield copies of those positions. The following works as expected:
aList = [p for p in c.all_positions()]
There is no longer any need to do this:
aList = [p.copy() for p in c.all_positions()]
Of course, copied positions will typically become invalid when the outline changes, so some care is needed.
Fixed a horrible bug in g.handleUrl that opened a file browser by mistake. All tests pass.
Add g.handleUnl, that can never open a browser.
g.recursiveUNLSearch selects the desired at idle time.
sf.find_setting no longer puts up a wonky dialog.
sf.find_setting calls g.handleUnl instead of g.handleUrl.
sf.copy_to_my_settings copies the settings tree only if it doesn’t exist.
Leo’s core code now uses None instead of c.nullPosition(). c.p can be None during startup, which necessitated a few new guards. As a result, the following are all valid tests:
if not p: # Correct, pre-Leo 5.5. if not p.v: # Correct, pre-Leo 5.5 if p is not None # Correct, Leo 5.5 and later. if p is None: # Correct, Leo 5.5 and later.
Now that these tests “just work”, there is no need to document them in the scripting tutorial.
Most changed methods are in the startup logic:
*.injectIvars c.redraw NullTree.edit_widget QtStatusLineClass.update
And a few others:
c.executeScriptHelper EditBodyTestCase.ctor
The new code works, and is much simpler than the old.
An important simplification of the leoGlobals functions that read files into strings. All tests pass.
Most calls to g.readFileIntoString and g.readFileIntoEncodedString contain no keyword args.
g.readFileIntoString is the most important helper. Simplifying it helps a lot.
at.compareFiles calls g.readFileIntoEncodedString instead of g.readFileIntoString(raw=True)
leoImport.py: Removed unnecessary encoding arg from call to readFileIntoString.
Removed unnecessary “silent” args in two call to g.readFileIntoEncodedString
Slideshows, screencasts & screenshots
demo.pyCreates slides, screen shots and slide shows, replacing screencast.py, screenshots.py and slideshow.py
User Interface
bookmarks.pyManages bookmarks using a separate pane.
dragdropgoodiesDumps files dropped into Leo.
python_terminal.pyEmbeds an python interpreter in Leo’s log pane.
QNCalendarWidgets.pyAdds a calendar widget.
richtext.pyEnables rich text using the CKEditor editor.
settings_finder.pyAdds the Edit Settings menu tree to the Settings menu.
systray.pyAdds Leo to the system tray.
wikiview.pyHides/shows parts of urls in the body editor.
Files and nodes
jinjarender.pyRenders @jinja nodes.
leoOPML.pyRead and write .leo files in OPML.
notebook.pyAdds a QML notebook.
Commands and directives
codewisecompleter.pyUses the ctags database to provide an autocompletion list.
ctagscompleter.pyUses ctags to provide an autocompletion list.
ftp.pySupports uploading of files via ftp.
gitarchive.pyStores snapshots of outline in git.
leofeeds.pyReads from rss, atom or other sources.
leomail.pySync local mailbox files over to Leo.
markup_inline.pyAdds commands that create bold, italic or underlined text.
nodediff.pyProvides commands to run text diffs on node bodies within Leo.
sftp.pyAdds @edit-like functionality for remote files over SFTP.
threadutil.pyAdds utilities for asynchronous operation of commands.
xml_edit.pyAdds commands for importing and exporting xml to and from Leo outlines.
leo-editor/leo-editor#349 Command line option to select type of @<file> node to when opening non-outline files
The scripting tutorial contains a few more examples before jumping into the details.
Removed all abbrev-* commands except abbrev-kill-all and abbrev-list.
https://groups.google.com/d/msg/leo-editor/-mv2x_6TAdM/Bgntt7b9AgAJ
Removed all macro-* commands.
Removed all register-* commands.
advertised-undo digit-argument negative-argument number-command number-command-0 … number-command-9 universal-argument
Note: Leo 5.4 previously removed all buffer-* and register-* commands.
Decluttering replaces @clean, @file, etc. by icons in headlines. This reduces screen space. The setting: @bool tree-declutter = True enables decluttering.
The setting, @data tree-declutter-patterns should contain patterns like:
# remove @clean and use an icon
RULE ^@clean (.*)
REPLACE \1
ICON file_icons/file_clean.png
# show the last part of long filenames
RULE ^.{1,1000}([/\\])(.{25})
REPLACE …\1\2
# if the node name starts with 'peacock node DEMO', make a mess of it
RULE ^(peacock node DEMO)
REPLACE LOOK: \1
ICON Tango/16x16/emotes/face-grin.png
ICON Tango/16x16/emotes/face-wink.png
FG @solarized-magenta
BG white
FONT Times
PX 40
ITALIC 1
WEIGHT Bold
Here’s the commit message for 05df9ac
add @cmd justify-toggle-auto and @bool autojustify-on-at-start
The @int autojustify behavior is very useful for writing prose (not code) when you want text wrapped at a particular column with a real newline, not just visually wrapped at the window edge. To be usable it needs a command to toggle activation, and a setting to decide whether it’s on by default, this commit adds those.
The setting @int autojustify itself has been around for a while, I’d forgotten about it, I’ve been wanting this feature for years, made a failed attempt to add it once, but just (re)discovered the when I realized how it should be done, and found that it already was :-)
More discussion here: leo-editor/leo-editor#14
Thanks to Tsuchi Noko for these.
Ctrl-click on UNL’s goes to the UNL. This already existed, as an Easter Egg for file:// url’s.
leoSettings.leo: - Added two new patterns to @data wikiview-link-patterns.
leoColorizer.py: - Added jedit.match_unl. - Added support for unl’s at end of jedit.colorRangeWithTag.
leoGlobals.py: - g.recursiveUNLSearch expands found node if it has children. - g.handleUnl looks for files in various places. - g.openUrlHelper adds support for UNLs.
wikiview.py: - Added a unl linking to the plugins settings. So cool.
The leomail plugin reads .mbox mail archive files into a tree of Leo nodes. This saves a lot of work.
Google “<your favorite mail client> archive to mbox” for instructions on generating .mbox files.
The new code contains the following improvements:
It works with both Python 2 and 3. The old code could corrupt .leo files by including strings that the sax parser barfed on. The new code appears safe to use. The conversion involved tricky details in libraries, as well as the usual cursed bytes/string/unicode issues.
The new code organizes messages by threads. Messages that start with “re:” become children of the node that started the thread.
Better warning and informational messages, and a better docstring.
https://groups.google.com/d/msg/leo-editor/8moMUEOOgWA/HE0cl-aADQAJ
Leo’s markdown importer converts all sections to use ‘#’ markup. The technical justification appears at the bottom of the page for #342. The rest of this post explains the change from a user’s point of view.
tl;dr: Converting all sections to ‘#’ markup is Leonine, simplest and best. Only existing .md files that Leo didn’t write could be changed. If such changes don’t work for you, just insert @ignore yourself when git or diff reports differences.
Imo, this change is fully justified:
It is more Leonine.
When creating and changing .md files from within Leo, @auto-md works much more smoothly. Indeed, as I have just verified, converting an @nosent x.md file to @auto-md x.md “just works”.
There is absolutely no reason to use underlined sections when using Leo. The headlines proclaim the section structure far better than flat text of any kind, whether ### section name or underlined section names.
Perfect import check should not wag the dog.
The markdown importer is one of the simplest of all. The possibility of dropping data seems remote. Requiring a typical perfect import check to pass would preclude regularizing section markup. It’s just that simple.
Furthermore, the existing unit tests for the markup importer do check imported section structure, albeit imperfectly That should suffice for now. In the unlikely event that real problems are reported, these after-the-fact unit tests can be improved.
Summary
Importing markdown files containing underlined sections could only pass typical perfect import checks if existing underlining were somehow retained. That’s a bad idea. Instead, Leo’s markdown importer now implicitly converts all sections to ‘#’ markup. In essence, the markup disappears from the outline, to be automagically reinserted when Leo writes the outline.
This new scheme can change existing .md files, but only files that Leo didn’t write. If that is inconvenient for you, just add @ignore yourself.
https://groups.google.com/d/msg/leo-editor/L4EAfY7NJbw/NgSv5zSDEwAJ
This is buggy.
Settings:
@bool autojustify-on-at-start
@bool color-doc-parts-as-rest
@bool run-pyflakes-on-write
@bool tree-declutter = True
@data tree-declutter-patterns
Command-line options:
--load-type=LOAD_TYPE
--fail-fast # sets failfast option in unit tests.
Leo 5.6 September 25, 2017
[Leo](https://leo-editor.github.io/leo-editor/) 5.6 is now available on [SourceForge](https://sourceforge.net/projects/leo/files/Leo/) and on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
Simulating Leo’s features in Vim, Emacs or Eclipse is possible, just as it is possible to simulate Python in assembly language…
The highlights of Leo 5.6
The cursesGui2.py plugin creates a console gui for Leo.
Added “Yes to All” and “No to All” buttons to file-changed dialog.
Improved how Leo switches between git branches.
Created outline-oriented git-diff command.
Links
[Leo’s home page](https://leo-editor.github.io/leo-editor/)
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
For a list of all enhancements added in Leo 5.6, see this page: leo-editor/leo-editor#issues
A new chapter in Leo’s documentation: https://leo-editor.github.io/leo-editor/console-gui.html
The new git-diff command shows the diffs between any uncommitted work and git’s HEAD in an outline. This is, by far, the best outline-oriented diff in Leo’s history. The command works for all kinds of external files.
Outline organization
This command creates a single tree as the last top-level node of the outline:
- git diff # The single organizer node for the command
- file A # The organizer node for file A.
# Body contains the text diff of the entire file.
- Added # An organizer node for all added nodes, created only if necessary.
- node 1 # A copy of the first added node.
- node 2 # A copy of the second added node.
...
- Deleted # An organizer node for all deleted nodes, created only if necessary.
- node 1 # A copy of the first deleted node.
...
- Changed # An organizer node for all changed nodes, created only if necessary.
- node 1 # An organizer node for the changed node.
# Body contains the text diff of that node.
- old: node1 # A copy of the old node.
- new: node1 # A copy of the new node.
This command does not use git diff in any way. For example, moving a node affects only the overall diff in the organizer node for the file. Moved nodes do not otherwise appear in the diff.
Text diffs
Organizer nodes for files and changed nodes contain text diffs. Diffs look like this:
@language patch
--- HEAD
+++ uncommitted
@@ -553,8 +553,8 @@
c1 = self.make_outline(fn, s1, self.rev1)
c2 = self.make_outline(fn, s2, self.rev2)
assert c1 and c2
- for p in c1.all_positions():
- print('%25s %s' % (p.gnx, p.h))
+ # for p in c1.all_positions():
+ # print('%25s %s' % (p.gnx, p.h))
self.make_diff_outlines(fn, c1, c2)
# try:
# c.disable_redraw()
@@ -578,6 +578,7 @@
...
@language python
Settings
leoSettings.leo contains new colorizer settings for @language patch.
Theory of operation
For each diffed file, this command uses a variant of the atFile read logic to create the corresponding outline in a hidden commander. Separate hidden commanders contain the “before” and “after” versions of the file. These outlines preserve gnx’s, so it is easy to create dicts of inserted, deleted and changed nodes. The command uses difflib (not git diff) to create all diffs, after the external file has been split into nodes.
The new code eliminates hidden time bombs when switching branches.
Changes to read/write code: - at.writeAll writes files at most once. - at.write updates cache. Previously only at.read updated the cache! - at.deleteUnvisitedNodes no longer creates resurrected nodes. - at.new_createThinChild4 always updates headlines. - at.terminateBody just sets v.tempRoots.
It no longer calls at.indicateNodeChanged.
fc.handleNodeConflicts reports changed headlines differently.
Changes to cacher code: - Added cacher.checkForChangedNodes. - Added tempRoots logic. - Added always_warn switch to cacher.reportIfNodeChanged.
For a list of all bugs fixed in Leo 5.6, see this page: leo-editor/leo-editor#issues
leo-editor/leo-editor#386 All changes made to leo/modes/md.py
See also: leo-editor/leo-editor#449 The original fix was in i.run in linescanner.py.
leo-editor/leo-editor#451 refresh-from-disk doesn’t always restore focus to the correct node
at.readOneAtAutoNode returns the new position.
c.refreshFromDisk selects that position.
leo-editor/leo-editor#453 Focus jumps to de body pane when expanding an abbreviation in a headline.
The fix was in find_place_holder. It should not set focus if no placeholder found.
leo-editor/leo-editor#457 Wrap around search now works properly.
leo-editor/leo-editor#458 Set a Qt flag in tt.createControl.
Missing end-of-line characters at the Log Pane leo-editor/leo-editor#459
fc.handleNodeConflicts now prints a prominent warning in the log and console if it doesn’t create a recovered-nodes node.
Simplified signon logic and g.pr. - Removed app.signon_printed ivar. - Changed (slightly), the print statements in app.computeSignon. - Changed log message in app.setIDFromFile. - Changed (slightly), the log messages in app.writeWaitingLog. - Greatly simplified g.pr and codewise variant. They no longer queue messages. - Rewrote bridge.getLeoID() and app.setLeoID() without using sections.
Added LeoHighlighter.force_rehighlight.
Rewrote ‘recolor’ command (c.force_recolor).
Rewrote c.recolor_now.
Added calls to c.recolor_now to c.moveOutline*.
Reverted leo_h.force_rehighlight.
2017-04-28 06:34:10.
leoColorizer.py: - Inserted force_rehighlight
leoCommands.py: - Replaced c.updateSyntaxColor(p) with c.recolor_now(p) in 4 move commands. - Lines 4629, 4661, 4689, 4759, etc.
UnicodeDecodeError in writeRecentFilesFileHelper leo-editor/leo-editor#471
The fix was in rf.writeRecentFilesFileHelper.
Solved: the checks are made only if @bool check_for_changed_external_files = True
Changed code in efc.on_idle and efc.idle_check_commander.
leo-editor/leo-editor#479 Preserve brython indentation when importing .html files
With a new installation of Leo there is no leo.session file. It is apparently created only after using the –session-save command line option.
If the –session-restore option is also used before that file is created, then Leo fails to open (splash screen displays, then nothing else happens).
This was the new-read branch.
The new code eliminates hidden time bombs when switching branches.
Changes to read/write code: - at.writeAll writes files at most once. - at.write updates cache. Previously only at.read updated the cache! - at.deleteUnvisitedNodes no longer creates resurrected nodes. - at.new_createThinChild4 always updates headlines. - at.terminateBody just sets v.tempRoots.
It no longer calls at.indicateNodeChanged.
fc.handleNodeConflicts reports changed headlines differently.
Changes to cacher code: - Added cacher.checkForChangedNodes. - Added tempRoots logic. - Added always_warn switch to cacher.reportIfNodeChanged.
No real changes were made. Plugins should not create bindings by calling k.registerCommand. Such bindings happen “too late” in the startup process to be over-ridden in settings files. Instead, plugins can define suggested bindings in leoSettings.leo.
Note: The mod_scripting plugins creates bindings from @button and @command nodes. Again, these are “late” bindings that can not be over-ridden in settings files. I don’t believe this is a big problem. The problem arises because Leo loads plugins after loading all outlines. It’s not a direct consequence of using settings files.
Leo now has two new command-line options. These provide more detail than the print-binding or show-settings commands, but only for a single setting or binding. Examples:
- --trace-setting=http-port
# setting name
- --trace-setting=cff
# command name
- --trace-binding=shift-ctrl-f
# key binding
See also: How to make Unicode charset in cmd.exe by default? https://stackoverflow.com/questions/14109024
Rewrote rf.createRecentFiles, rf.readRecentFilesFile and rf.writeRecentFilesFileHelper.
The bug gave way too many bindings for the move-lines commands.
ga.show_tab_list wasn’t showing commands without any shortcuts!
Fixed plugins.registerOneHandler and plugins.registerOneExclusiveHandler
The unit test “@test xml non-ascii tags” failed on Python 2, but not Python 3.
The fix was in xml_i.scan_tag & helper
It must return True if g.app.externalFilesController is None.
The change was to pylint.run_pylint.
This removes a major source of confusion.
The new code eliminates hidden time bombs when switching branches.
Changes to read/write code: - at.writeAll writes files at most once. - at.write updates cache. Previously only at.read updated the cache! - at.deleteUnvisitedNodes no longer creates resurrected nodes. - at.new_createThinChild4 always updates headlines. - at.terminateBody just sets v.tempRoots.
It no longer calls at.indicateNodeChanged.
fc.handleNodeConflicts reports changed headlines differently.
Changes to cacher code: - Added cacher.checkForChangedNodes. - Added tempRoots logic. - Added always_warn switch to cacher.reportIfNodeChanged.
Redrawing the screen happens only as the result of an explicit call to c.redraw. In particular, neither c.selectPosition nor its helpers redraw the screen.
c.redraw_later() sets a flag requesting that c.outerUpdate call c.redraw if necessary. Any call to c.redraw resets this flag. cc.selectChapterForPosition calls c.redraw_later.
c.disable_redraw() sets a flag disabling all outline redraws. c.enable_redraw() re-enables redrawing. This is similar to the old begin_update/end_update scheme, but simpler and more explicit. Use this as follows:
c.disable_redraw() # Code that might otherwise redraw the tree.
c.enable_redraw()
c.outerUpdate has been drastically simplified. It no longer handles requests for redraws, recoloring, bring-to-front or de-iconification. It now handles requests for delayed focus changes and delayed redraws. It also handles “childrenModified” and “contentModified” hooks.
Added ‘recursive’ keyword arg to c.recursiveImport and RecursiveImportController ctor. Recursive is not the same as not one_file.
leoGlobals.py the following functions and their helpers in the .Git subtree:
branch, commit = g.gitInfo(path = None)
date, build = g.jsonCommitInfo()
branch = g.gitBranchName(path = None)
commit = g.getCommitNumber(path = None)
The path should be a folder containing a .git subfolder. If the path is None, the leo-editor folder is used.
Leo’s cacher code will soon use the branch name returned by g.gitInfo() to ensure that switching git branches works properly.
As a happy side effect, these methods completely collapse the complexity of leoVersion.py.
This makes explicit which importers actually generate section reference. At present, only the javascript importer sets this arg.
These traces detected nothing unusual and have been disabled.
Removed the allow_at_auto_section switch in leoAtFile.py.
When writing @auto files << handle line at s[i] >> in at.putBody now expands section references in @auto files if they are defined. Otherwise, lines containing undefined section references are written as plain code lines.
Ding dong, the switch is dead, the wicked old switch is dead.
20 years of lint removed from leoAtFile.py: https://groups.google.com/d/msg/leo-editor/o5GtCDCZDSo/KO__cZZ-AAAJ
Warning: The p.b and p.h setters and p.setDirty() are very expensive:
p.b = s calls c.setBodyString(p, s) which will recolor body text and update the node’s icon.
p.h = s calls c.setHeadString(p, s) which calls p.setDirty().
p.setDirty() changes the icons of all ancestor @file nodes.
In contrast, the corresponding p.v.b and p.v.b setters and p.v.setDirty() are extremely fast.
Usually, code should use the p.b and p.h setters and p.setDirty(), despite their cost, because they update Leo’s outline pane properly. Calling c.redraw() is not enough.
These performance gotchas become important for repetitive commands, like cff, replace-all and recursive import. In such situations, code should use p.v.b and p.v.h setters instead of p.b and p.h setters.
Improved g.SherlockTracer.do_line, g.gitInfo, g.is_binary_external_file, g.log, g.readFileToUnicodeString.
The edit-recent-files command creates a new last top-level node containing a list of all recent files as they appear in the File:Recent File menu.
The write-edited-recent files command writes the body text node to leoRecentFiles.txt. The command assumes that the user has not changed the headline of the node created by the edit-recent-files command.
Made several changes to find.batchChange.
This command is surprisingly useful. It toggles between a flattened view (@edit) and an outline view (@auto) of an external file containing no sentinels.
This command preserves the presently selected line when flattening/un-flattening the outline. You can run this command from any descendant of an @auto node.
@cmd(‘toggle-at-auto-at-edit’) def toggleAtAutoAtEdit(self, event):
‘’’Toggle between @auto and @edit, preserving insert point, etc.’’’ p = self.c.p if p.isAtEditNode():
self.toAtAuto(p) return
- for p in p.self_and_parents():
- if p.isAtAutoNode():
self.toAtEdit(p) return
g.es_print(‘Not in an @auto or @edit tree.’, color=’blue’)
‘’’Convert p from @edit to @auto.’’’ c = self.c # Change the headline. p.h = ‘@auto’ + p.h[5:] # Compute the position of the present line within the file. w = c.frame.body.wrapper ins = w.getInsertPoint() row, col = g.convertPythonIndexToRowCol(p.b, ins) # Ignore preceding directive lines. directives = [z for z in g.splitLines(c.p.b)[:row] if g.isDirective(z)] row -= len(directives) row = max(0, row) # Reload the file, creating new nodes. c.selectPosition(p, enableRedrawFlag=False) c.refreshFromDisk() # Restore the line in the proper node. c.gotoCommands.find_file_line(row+1) p.setDirty() c.setChanged() c.redraw() c.bodyWantsFocus()
‘’’Convert p from @auto to @edit.’’’ c = self.c w = c.frame.body.wrapper p.h = ‘@edit’ + p.h[5:] # Compute the position of the present line within the selected node c.p ins = w.getInsertPoint() row, col = g.convertPythonIndexToRowCol(c.p.b, ins) # Ignore directive lines. directives = [z for z in g.splitLines(c.p.b)[:row] if g.isDirective(z)] row -= len(directives) row = max(0, row) # Count preceding lines from p to c.p, again ignoring directives. for p2 in p.self_and_subtree():
- if p2 == c.p:
break
lines = [z for z in g.splitLines(p2.b) if not g.isDirective(z)] row += len(lines)
# Reload the file into a single node. c.selectPosition(p, enableRedrawFlag=False) c.refreshFromDisk() # Restore the line in the proper node. ins = g.convertRowColToPythonIndex(p.b, row+1, 0) w.setInsertPoint(ins) p.setDirty() c.setChanged() c.redraw() c.bodyWantsFocus()
leo-editor/leo-editor#495 Leo already supports the point and mark.
Added ec.pushCursor and ec.popCursor. Added ec.finishOfLine & ec.startOfLine & extend variants. Extended ec.moveWithinLineHelper.
beginning of line is before first character in line start of line is first nonwhite space text finish of line is last nonwhite space text end of line is after last character in line
navigating to these points is useful when using speech recognition and is frequently useful when creating macros to operate on text. Jump means you go to the location without remembering where you were. Push means remembering, in a stack, where you were and being able to return to that location with a pop command.
The push/pop model works well with speech recognition because you don’t have to give explicit navigation commands. You just go back to where you were.
Searches from c.p for any clone, not just a clone of c.p. Useful for eliminating all clones from a .leo file.
This command is different from goto-next-clone as follows:
goto-any-clone goes to the next clone, regardless of whether c.p is a clone.
goto-any-clone does not wrap. It prints a message when no clones remain.
How to debug npyscreen apps using two consoles: https://groups.google.com/forum/#!topic/npyscreen/nk2pjj71bok
The log-listen (aka listen-to-log) and kill-log-listen (aka, listen-log-kill) commands implement this logging cookbook recipe: https://docs.python.org/2/howto/logging-cookbook.html#sending-and-receiving-logging-events-across-a-network
The log-listen command creates a logging listener whose output goes to Leo’s console. The listener runs in a separate process so that Leo doesn’t hang.
Start the listener first, then start another process in another console. All logging output from the second process will be captured and displayed by the listener, provided that the second process includes a call to rootLogger.addHandler(socketHandler).
leo/external/log_broadcast.py contains example code. leo/plugins/cursesGui2.py uses this pattern to broadcast g.trace.
push-cursor Saves the location of the cursor, including node(position) on a stack. pop-cursor Restores the cursor position from the stack.
start-of-line Puts cursor at first non-blank character of the line. finish-line Puts the cursor at before the last non-blank character of the line.
The finish-line-extend-selection and start-of-line-extend-selection commands move the cursor and extend the selection range.
The finish-line command could put the cursor after the last non-blank character of the line, but that’s pretty much what end-of-line does.
Changed find.createCloneFindAllNodes and c.cloneFindMarkedHelper.
https://groups.google.com/d/msg/leo-editor/SUnqs1_YbeI/DIv0EbtFCgAJ
The indent-region and unindent-region just move the insert point if there is no text selected.
These commands (bound to ctrl-up/down by default) now work at the top or bottom of the body pane. The move-lines-up command inserts a new line below the moved line/lines when the lines are at the top of the body text. Similarly, the move-lines-down command inserts a line before the moved lines when at the bottom of the body text. Imo, this is a natural and useful.
leo-editor/leo-editor#479 Preserve brython indentation when importing .html files
The new code is simpler and handles dubious html syntax.
If the expansion of an abbreviation is a command name, that command will be executed. Alas, this isn’t very useful: typing destroys selection ranges.
This took only a few lines of code in abbrev.expandAbbrev.
Added new settings:
@bool log_show_save_time = False
@string log_timestamp_format = "%H%M%S"
Changed fc.putSavedMessage and at.replaceTargetFileIfDifferent.
at.promptForDangerousWrite puts up a dialog with a clearer cancel button.
It says “Cancel (No To All)”.
Added cancelMessage keyword arg to x.promptForDangerousWrite.
Use keyword args in LeoFrame.promptForSave and ns_do_context.
Rev b32259 transitions to a new caching scheme:
All hashes now use the full path to the external file. Previously, the headline of @file nodes was typically used instead. Surely this might have caused silent problems.
Leo’s hasher now includes the name of the present git branch in the hash. When switching git branches, this in essence disables hashing for all files changed in the previous branch.
The first UP-arrow to gives the previous command, the next up-arrow gives the next command, etc.
Changed g.computeWindowTitle.
https://groups.google.com/d/msg/leo-editor/sBGJr_oHeyk/3eUjoBC0CQAJ
@bool report_unchanged_files = True
Defaults are:
@bool color_trailing_whitespace = True
@color trailing_whitespace_color = red
Defaults are:
@bool log_show_save_time = False
@string log_timestamp_format = %H:%M:%S
These are bound to indent/unindent-region and can be used when no text is selected.
The disabled setting now contains this comment:
Note: This setting has been retired for the following reasons:
1. The new javascript importer always generate section references for non-trivial programs. As a result, the legacy value for this setting would cause the javascript importer to fail.
2. The new @auto write code writes expands section references if they exist. Otherwise, the write code writes the line as is, without any complaint. As a result, there should be no problem if an imported code contains something that looks like a section reference but isn’t.
Leo 5.7 final February 27, 2018
Leo 5.7 final, https://leo-editor.github.io/leo-editor/ is now available on [SourceForge](https://sourceforge.net/projects/leo/files/Leo/) and on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
Simulating Leo’s features in Vim, Emacs or Eclipse is possible, just as it is possible to simulate Python in C or assembly language…
The highlights of Leo 5.7
pip install leo.
A debian package for Leo.
A web-based Leo Viewer, written by Joe Orr.
Added diff-leo-files and diff-and-open-leo-files commands. These create outline-oriented diffs for .leo files.
New reload-settings command.
Leo optionally shows user tips on startup.
Added a new Tips page to Leo’s documentation.
A visual widget for editing cvs tables.
Spell checking works without pyenchant
Improved the console_gui plugin.
Added live links from urls in the log pane.
Unit tests use a string gui, making them faster and more robust.
The line_numbering plugin shows line numbers in external files.
Improved the javascript importer.
Added a TreePad importer.
Added 6 new commands.
Dozens of bug fixes.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
@nosearch
You can see all 5.7 issues by visiting: leo-editor/leo-editor#issues
TM.doTests now runs all unit tests with string gui (StringTextWrapper class).
This has three advantages:
The tests run much more quickly than before.
Leo does no redraws during the tests.
Clicks in the Leo window can now longer spoil running unit tests.
Leo uses the pyenchant spell checker if it has been installed.
Otherwise, Leo will use a pure python spell checker, provided that a spell dictionary exists at ~/.leo/main_spelling_dict.txt. You may download a compressed version of this dictionary from https://sourceforge.net/projects/leo/files/Miscellaneous/
The edit-pane-csv command opens a CSV table editor pane. Very useful for editing CSV data in Leo.
Here is a demo: https://youtu.be/hca3x5SXNqs
I’m happy to announce first releases of Leo 5.0 as a debian/ubuntu packages
Please try my builds on your debian based environment:
On Ubuntu :
sudo add-apt-repository ppa:davy39/ppa
sudo apt-get update
sudo apt-get leo
On other Debian based system :
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B84B2247
sudo add-apt-repository "https://ppa.launchpad.net/davy39/ppa/ubuntu utopic main"
sudo apt-get update
sudo apt-get leo
FYI, Debian no longer uses / supports add-apt-repository. It is my understanding that only ubuntu systems still support this. The procedure I used to successfully install Leo on Debian 8 was the following:
I added the key as instructed above.
I manually added the repository to my /etc/apt/sources.list
the command to install leo I needed was: sudo apt-get install leo
The menu item was found under “Development” and Leo appears to be working just fine.
The diff-leo-files command diffs arbitrarily many .leo files, two at a time. The diff-and-open-leo-files does the same, and addition opens the diffed files.
The CompareLeoOutlines class in leo/core/leoCompare.py allows scripts to generate outline-based diffs for arbitrarily many .leo files. Previously, only the git-diff command created outline-based diffs.
Here is an example script:
import leo.core.leoCompare as leoCompare
outlines = ['LeoDocs.leo', 'LeoDocs1.leo', 'LeoDocs2.leo']
paths = [g.os_path_finalize_join('~/compare', z) for z in outlines]
leoCompare.CompareLeoOutlines(c).diff_list_of_files(paths)
This script will present three sets of diffs, in a new top-level node whose nodes are as follows:
- outline diff
Body: LeoDocs.leo, LeoDocs1.leo, LeoDocs2.leo
- LeoDocs.leo, LeoDocs1.leo
Body: the entire diff of LeoDocs.leo and LeoDocs1.leo
- added
copies of added nodes
- deleted
copies of deleted nodes
- changed
diff nodes for all changed nodes.
Body: the diff of each node.
- LeoDocs.leo: copy of old node
- LeoDocs1: copy of new node
- LeoDocs.leo, LeoDocs1.leo
Ditto
- LeoDocs1.leo, LeoDocs1.leo
Ditto
Fixed dozens of bugs. See: leo-editor/leo-editor#issues
Serious unfixable bugs: https://leo-editor.github.io/leo-editor/console-gui.html#unfixed-bugs
This only happens when clicking the link in the VR pane, and only with Python 2.
Added k.remove_conflicting_definitions.
The fix was in ni.compute_last_index.
The bug was in LM.computeWorkbookFileName. It’s fine to return the name if the file already exists.
<module>,run,load,doPostPluginsInit,openEmptyWorkBook,loadLocalFile, openFileByName,initWrapperLeoFile,refreshFromDisk,readOneAtEditNode
loadOnePlugin: can not load enabled plugin: leo.plugins.viewrendered leo-editor/leo-editor#702
Leo fails to load when pyenchant is not installed leo-editor/leo-editor#707
TypeError: coercing to Unicode: need string or buffer, NoneType found leo-editor/leo-editor#712
TypeError: expected str, bytes or os.PathLike object, not NoneType leo-editor/leo-editor#713
LeoBridge not explicitly closing the Leo-Editor file leaves the Leo-Editor file open leo-editor/leo-editor#716
setup.py broken when installing from zipball: execGitCommand not available leo-editor/leo-editor#720
replace-all can not be saved with crtl + s leo-editor/leo-editor#722
Recover more gracefully from user errors in abbreviations leo-editor/leo-editor#725
help-for-command crashes when vr2 plugin is active leo-editor/leo-editor#734
@rclick buttons not generating commands in work files leo-editor/leo-editor#739
Let reformatting unit tests run in more environments leo-editor/leo-editor#577
@int page_width = 80 @int tab_width = -4
pagewidth = 75: From myLeoSettings.leo tabwidth = -4: From leoSettings.leo
@pagewidth 40 @tabwidth 8
The @g.commander_command decorator injects ivars into the Commands class.
g.findNodeInChildren, g.findNodeInTree, and g.findNodeAnywhere now take an “exact” keyword argument. The default (True) ensures current behavior does not change.
All three methods first look for an exact match, regardless of the exact keyword, just as before. If no match is found, and exact is False, these methods then search again, matching if the given headline is a prefix of the headline of any node.
The signature of c.backup_helper is:
def backup_helper(self, base_dir=None, env_key='LEO_BACKUP', sub_dir=None):
c.backup_helper uses the LEO_BACKUP environment variable as the base of the save if it exists. Otherwise it uses the given base_dir directory. If given, the sub_dir path is applied to the base directory.
This method does careful error checking and reporting. The body text of the following four @button backup nodes are all just one line:
c.backup_helper(sub_dir='leoPy') # In leoPy.leo
c.backup_helper(sub_dir='ekr-projects') # In ekr-projects.leo
c.backup_helper(sub_dir='ekr') # In ekr.leo
Changing just the LEO_BACKUP environment value will change the destination of all these scripts.
g.callers(verbose=True) returns the callers on separate lines, displaying file name, line number and class name. This is especially useful for gui programming, where there may be many ‘display, ‘edit’, ‘redraw’ and ‘update’ methods. It’s also useful where you just don’t have any idea where a function or method resides.
For example, these traces, in BoxTitle.edit:
g.trace('===== (BoxTitle:%s) entry_widget: %s' % (
self.__class__.__name__,
self.entry_widget.__class__.__name__))
g.trace('CALLERS', g.callers(verbose=True))
Produce:
trace: edit ===== (BoxTitle:BoxTitleLog) entry_widget: LeoLog
trace: edit CALLERS
line 32 apNPSApplication.py LeoApp.__remove_argument_call_main
line 2711 cursesGui2.py LeoApp.main
line 1632 cursesGui2.py LeoCursesGui.run
line 66 fm_form_edit_loop.py LeoForm.edit
Each line shows the line number and file containing the function or method. All the above lines show methods.
This project makes major improvements to Leo’s redraw logic with virtually no effect on existing code. The highlights of the changes are as follows:
Redrawing the screen happens only as the result of an explicit call to c.redraw. In particular, neither c.selectPosition nor its helpers redraw the screen immediately. However, cc.selectChapterForPosition ensures that a redraw happens eventually using…
c.redraw_later() sets a flag requesting that c.outerUpdate call c.redraw if necessary. Any call to c.redraw resets this flag.
c.disable_redraw() sets a flag disabling all outline redraws. c.enable_redraw() re-enables redrawing. Use these methods as follows:
try:
c.disable_redraw()
# Code that might otherwise redraw the tree.
finally:
c.enable_redraw()
This pattern is essential in the new git-diff code. Lots of redraw code changed, but in similar and straightforward ways. In effect, the new code is exactly the same as the old unless c.disable_redraw() has been called, I do not expect problems here.
c.outerUpdate has been drastically simplified. It now only handles requests for delayed focus changes (as before) and the new delayed redraws.
Note: cc.selectChapterForPosition calls c.redraw only if the chapter changes.
Added support for c.redraw_later, called from cc.selectChapterForPosition.
c.bringToFront now works without using c.outerUpdate.
c.widgetWantsFocusNow now just calls c.set_focus & clears c.requestedFocusWidget.
c.outerUpdate no longer handles recoloring or redrawing.
Replaced all calls to c.recolor_now by c.recolor.
Replaced all calls to redraw_now by redraw.
Removed all calls to body.forceFullRecolor.
Removed forceFullRecolorFlag.
Removed c.incrementalRecolorFlag.
c.selectPosition never calls c.redraw.
Removed c.requestRedrawFlag and c.outerUpdate never calls c.redraw.
fc.resolveArchivedPosition gives errors message only if there have been no read errors (at.errors == 0).
See https://groups.google.com/d/msg/leo-editor/RIwAHLAmq_0/s11zAcbECgAJ.
Added g.execute_shell_commands_with_options.
Status
This project does real checking, something that none of my type-related projects has ever done before. The cc.resolve* methods are simple and straightforward by the standards of tools like pylint and rope. Recent revs have cleaned up these methods a bit.
From the start, the code has been able to detect violations of naming conventions that neither pylint nor pyflakes are ever going to find. Speed has always been good enough. On my machine the checker checks the 77 of Leo’s sources in about 5.5 seconds. Greater speed would be possible using a one-pass algorithm, but that is not necessary now.
The “before and after” design/coding pattern is a spectacular success. It completely decouples the cc and cct classes. Neither is aware of each other in any way. In effect, before and after methods add to ast node visitors without changing those visitors in any way and without any knowledge of the node visitors.
The present code is sound. It parses the code correctly, and visits nodes in the proper order.
The initial prototype used regex patterns to do a quick, inaccurate, parse of the file. This strategy allowed me to focus on the cc.resolve* methods first, not later. Imo this was the only way I could have made the progress I did make.
Recent revs have removed all regex patterns from the code. This could only be done once the cc.resolve methods were in place. Removing regex patterns makes parsing sound, which simplifies code downstream.
The new cc.get_chain helper preprocesses chains like a.b.c or a.b().c or a.b[].c. This method is crucial, for several reasons:
It clarifies and simplifies various parts of the code.
It reveals the complexity of ast.Attribute trees.
It shows just where type inference or convention checking is likely to fail.
None of the benefits of cc.get_chain was obvious to me before creating it.
Summary
The cc command must be extended using @data settings and global patterns. It should also check keyword args.
The check-conventions command is a successful proof of concept:
It finds real problems quickly.
The code is sound. It parses code properly, and in the proper order.
Before and after methods collapse code complexity.
It will be easy for me to resume work on this project in future
As a result, this project is at a reasonable stopping point.
To do
[Most important] At present, the check-conventions (cc) command only knows about Leo conventions. Instead, the command should used @data nodes to define conventions.
[Important] The cc command should be able to check global naming conventions. For Leo, this would include the convention that self.c is a Commands object and that g is the leoGlobals module, etc.
[Important] At present the cc command does not check keyword arguments to function calls.
What percentage of chains can be resolved?
Use resolve_stack to bound recursion?
Add support for global patterns.
Support @data nodes.
check w, w.wrapper, w.widget?
Path demangling potentially alters the paths in the recent files list according to find/replace patterns in the @data path-demangle setting. For example:
REPLACE: .gnome-desktop WITH: My Desktop
The default setting specifies no patterns.
These commands always add the new node as the first/last node of the preceding node, regardless of the setting @bool insert_new_nodes_at_end.
These commands make it easier to use Leo’s reference .leo files. From time to time, developers needs to open reference Leo file and copy its content to and from their personal file.
These commands use a separation node, a top-level node** whose headline is:
---begin-private-area---
The body of the separation node contains the .leo reference, a path to the reference .leo file. Everything above this node is the public part of the outline. Everything below this node is the private part of the outline.
set-reference-file selects the reference .leo file corresponding to the local .leo file. It creates the separation node if it doesn’t exists, changing the .leo reference as needed.
read-ref-file reads the public part of this outline from the reference .leo file given in the separation node. Warning: This command deletes all nodes above separation node, recreating them from the reference file.
update-ref-file saves public part of this outline to reference .leo file.
You would typically execute the read-ref-file command after any git pull that changes any reference .leo file. Similarly, you would typically execute the update-ref-file command before doing a git commit that changes a .leo file.
This supports the already-existing g.app.trace_shutdown switch. Presumably –trace-shutdown was removed by mistake some time ago.
When True, Leo shows User Tips in a dialog on startup.
Added over two dozen enhancements. See leo-editor/leo-editor#issues
As a happy side effect, right clicking now always shows this popup. That’s because “New Outline” is always valid regardless of how many tabs there are and regardless of whether tabs have been detached.
This enhancement allows you to override bindings made in leoSettings.leo or myLeoSettings.leo by setting:
command-name = None
in the local .leo file, that is, outside of leoSettings.leo or myLeoSettings.leo. Important: binding:
do-nothing = <key>
does not work. That would eat <key> entirely. Instead, the new code calls k.handleUnboundKeys when it sees any key previously bound to command-name.
What I did: - k.masterKeyHandler handles k.killedBindings. - –trace-binding=BINDING works for bindings or command names. - Removed k.killBinding: it has no chance of working. - Added k.killedBindings, a list of command names for which bindings have been killed in local files. - ParserBaseClass.doShortcuts appends command names k.killedBindings. - Added c.config.isLocalSettingFile
Syntax coloring is based on C.
Changed qtree.declutter_node.
The code promotes replaces @others with the body text of the node’s child when the node has exactly one child. The singleton child becomes an organizer node without body text whose headline is ‘organizer’.
Later, the importer deletes organizer nodes after promoting their children. This is an iterative process, so that even more @others may be replaced later.
Leo uses the pyenchant spell checker if it has been installed.
Otherwise, Leo will use a pure python spell checker, provided that a spell dictionary exists at ~/.leo/main_spelling_dict.txt. You may download a compressed version of this dictionary from https://sourceforge.net/projects/leo/files/Miscellaneous/
The signature of c.backup_helper is:
def backup_helper(self, base_dir=None, env_key='LEO_BACKUP', sub_dir=None):
c.backup_helper uses the LEO_BACKUP environment variable as the base of the save if it exists. Otherwise it uses the given base_dir directory. If given, the sub_dir path is applied to the base directory.
This method does careful error checking and reporting. The body text of the following four @button backup nodes are all just one line:
c.backup_helper(sub_dir='leoPy') # In leoPy.leo
c.backup_helper(sub_dir='ekr-projects') # In ekr-projects.leo
c.backup_helper(sub_dir='ekr') # In ekr.leo
Changing just the LEO_BACKUP environment value will change the destination of all these scripts.
The diff-leo-files command diffs arbitrarily many .leo files, two at a time. The diff-and-open-leo-files does the same, and addition opens the diffed files.
The CompareLeoOutlines class in leo/core/leoCompare.py allows scripts to generate outline-based diffs for arbitrarily many .leo files. Previously, only the git-diff command created outline-based diffs.
Here is an example script:
import leo.core.leoCompare as leoCompare
outlines = ['LeoDocs.leo', 'LeoDocs1.leo', 'LeoDocs2.leo']
paths = [g.os_path_finalize_join('~/compare', z) for z in outlines]
leoCompare.CompareLeoOutlines(c).diff_list_of_files(paths)
This script will present three sets of diffs, in a new top-level node whose nodes are as follows:
- outline diff
Body: LeoDocs.leo, LeoDocs1.leo, LeoDocs2.leo
- LeoDocs.leo, LeoDocs1.leo
Body: the entire diff of LeoDocs.leo and LeoDocs1.leo
- added
copies of added nodes
- deleted
copies of deleted nodes
- changed
diff nodes for all changed nodes.
Body: the diff of each node.
- LeoDocs.leo: copy of old node
- LeoDocs1: copy of new node
- LeoDocs.leo, LeoDocs1.leo
Ditto
- LeoDocs1.leo, LeoDocs1.leo
Ditto
Add mark/unmark-first-parents commands leo-editor/leo-editor#714
Predefine script_p and script_gnx values in Leo scripts leo-editor/leo-editor#736
Improved js_i.clean_headline. This method now applies various regex patterns to the headline to simplify the “summary” of the function, including => functions.
leo-editor/leo-editor#488 Docs: https://leo-editor.github.io/leo-editor/console-gui.html
The highlights of recent work:
The label above the minibuffer now contains the present state. For example, after Ctrl-F the label is:
Mini-buffer: Search:
indicating that a search string is expected.
When selected, the tree pane highlights the ‘*’ line containing c.p.
The status pane shows Find options after Ctrl-F and various toggle-find-* and set-find-* commands.
So it is now clear what is going on at all times. This clarity is more important than features!
The minibuffer works with tab completion. Examples:
run-a<tab>l<tab><return> executes run-all-unit-tests-locally. toggle-find-r<tab><return> executes toggle-find-regex-option. # Shows results in status area.
This is a huge step forward in power.
Aha: the reason that all (enabled) unit tests work with the console gui is that the string representations of the body, tree and log (including headlines) are completely functional. True, the npyscreen views of same are weak and/or buggy, but that is a secondary matter.
For example, the Find commands probably work completely, even though the found text is not selected. Furthermore, there are workarounds. It is possible to select all lines containing the text selection, even though npyscreen does not support character selections.
Summary
The curses gui plugin is more functional and less confusing than before.
leo-c starts the test.
listen-to-log command to get message in THIS console.
Tab and Shift Tab switch panes.
Ran 918 tests in 40.317s (failures=4, errors=1, skipped=25)
Improve console gui chapter:
Arrow keys move within a pane, not between panes.
Link to npyscreen post: https://groups.google.com/d/msg/npyscreen/nk2pjj71bok/OZxBnuiJAQAJ
Without redraws: 34.5 sec. With redraws: 58.7 sec.
The new leo_cloud plugin allows subtrees within a .leo file to be stored in the cloud. It should be possible to support various cloud platforms, currently git is supported (i.e. you can use GitLab or GitHub or your own remote git server).
A leo_cloud subtree has a top node with a headline that starts with ‘@leo_cloud’. The rest of the headline is ignored. The body of this top node is used to describe the cloud service. For example:
type: Git
remote: git@gitlab.com:tnbrown/leo_cloud_storage.git
local: ~/.leo/leo_cloud/gitlab_leo_cloud_storage
ID: shortcuts
read_on_load: ask
write_on_save: ask
The first three lines can be repeated with different IDs to store different subtrees at the same remote cloud location.
read_on_load: / write_on_save: can be yes, no, or ask. If it’s not one of those three, there’s a warning dialog.
There’s also a file system backend, which would look like this:
type: FileSystem
root: ~/DropBox/leo_cloud
ID: my_notes
read_on_load: ask
write_on_save: ask
The FileSystem backend was meant to be for development, but of course if you map it into a folder that is sync’ed externally, as shown above, it can serve as a cloud adapter too.
This plugin shows real line numbers (as they are in external file) in the gutter.
Commands
line-numbering-toggle toggles whether this plugin has any effect.
toggle-line-numbering-root marks the presently selected node as fictive root for line numbering purposes.
Setting
Requires @bool use-gutter=True
Leo 5.7.1 April 6, 2018
Leo 5.7.1, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 5.7.1
Added –theme=<name> command-line option.
Added @string theme-name setting.
Leo warns if stylesheets contain undefined @-constants.
Replaced 5 vs-* commands by corresponding eval* commands.
Support @file x.md using html sentinels.
Allow @path in @<file> nodes, and optionally generate same in recursive imports.
Improved menus.
The usual minor bug fixes.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
is:issue milestone:5.7.1 is:closed https://github.com/leo-editor/leo-editor/issues?q=is%3Aissue+milestone%3A5.7.1+-label%3AWaiting+is%3Aclosed
leo-editor/leo-editor#812 PickleShareDB.keys should definitely not call g.glob_glob.
leo-editor/leo-editor#840 Changed c.config.getData and gcm.getData.
When True, adds @path directives to the root node of imported files.
leo-editor/leo-editor#839 The eval* commands are now in mod_scripting.py.
They have been replaced by new eval- commands.
leo-editor/leo-editor#467 @string initial-chooser-directory
Removed unnecessary check in g.get_directives_dict.
Command-line options:
Added –theme=<name>
Added –trace-themes
Settings:
Added @string theme-name
Added @string initial-chooser-directory Used by Ctrl-O (file-open-by-name)
May 7, 2018
Leo 5.7.2, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 5.7.2
Much improved support for Jupyter (.ipynb) files.
Fixed bugs that prevented switching between git branches easily.
Rewrote large parts of Leo’s key-handling code.
New command-line arguments to trace Leo’s code.
Removed about 20 unused settings.
The usual minor bug fixes.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
Related issues:
@auto x.ipynb now “just works”.
I can change any cell in Jupyter and save the file. If the corresponding .leo file is running the new code appears in the @auto tree. Simple as that.
I can also change the @auto tree. The Jupyter web page will (I think) eventually reload automatically. Or I can reload the page myself. Simple as that.
It now feels Leonine to author in Leo (with all of Leo’s organizing capabilities) and then render or run code in Jupyter.
Other features:
When writing, Leo uses @language directives to determine cell type.
When reading, Leo indents nodes based on body lines of the form:
<h1…9>title</h1…9>
Such markup affects Jupyter rendering, but the Leo headline of the node can be anything you want.
Leo now generates markdown section markup automatically, based on outline level and headlines.
Leo handles organizer nodes in the outline.
The new insert-jupyter-toc and insert-markdown-toc commands produce a toc (table of contents) for in the selected node, at insert point of the body text. They replace any selected text.
These two commands are almost identical. They very only in the details of how they generate the url part of markdown links. See Note 2 below.
Tip: These commands produce a toc only for the selected node and it’s descendants, but that is not a real limitation. For example, you can produce a complete toc for an @auto .ipynb tree by executing the command in the @auto node itself, then cutting and pasting the toc into the first child of the @auto node.
Notes
You must use the insert-jupyter-toc command inside .ipynb files. The Jupyter online notebook is picky about what links it will accept. In particular, case is important in url’s. You probably should use insert-markdown-toc for all other files.
Both commands clean both parts of markdown links, that is, the [*] part and the (*) part. It’s not clear what characters can be allowed in general, but for now the rules are:
Within [*] parts, all non alphanums are removed, except “:” and “-” and blanks.
Same for (*) parts, except that blanks are converted to “-“.
Similar logic is used in the exporter to clean section names.
The cleaning of markdown links is over-zealous, but it’s not clear exactly what characters are valid. In particular, html escapes will not work.
These two commands are defined in Leo’s core. They are completely separate from the @auto (importer/export) logic.
Summary
These two commands are important tools. Please try them and report any problems or desired improvements.
I will be happy to allow more characters in markdown links, should you want them. Just let me know.
The insert-markdown-toc is a component of #767: Add markdown command similar to rst3 command.
Leo’s –trace command-line arguments now allow users and devs to enable important traces without changing Leo’s sources in any way:
--trace-binding=KEY trace commands bound to a key
--trace-coloring trace syntax coloring
--trace-events trace non-key events
--trace-focus trace changes of focus
--trace-gnx trace gnx logic
--trace-ipython trace ipython bridge
--trace-keys trace key events
--trace-plugins trace imports of plugins
--trace-setting=NAME trace where named setting is set
--trace-shutdown trace shutdown logic
--trace-themes trace theme init logic
The following command-line arguments are new:
--trace-coloring
--trace-events
--trace-gnx
--trace-keys
--trace-ipython
The following settings are no longer used. They no longer appear in leoSettings.leo:
@bool gc_before_redraw = True @bool show_tree_stats = False @bool trace_bindings = False @bool trace_bindings_verbose = False @bool trace_color_parser = True @bool trace_colorizer = False @bool trace_doCommand = False @bool trace_f.set_focus = False @bool trace_focus = False @bool trace_g.app.gui.set_focus = False @bool trace_gc = False @bool trace_gc_calls = False @bool trace_gc_verbose = False @bool trace_key_event= False @bool trace_masterCommand = False @bool trace_masterFocusHandler = False @bool trace_masterKeyHandler = False @bool trace_minibuffer = False @bool trace_modes = False @bool trace_onBodyChanged = False @bool trace_plugins = False @bool trace_select = False @bool trace_status_line = False @bool trace_tree = False @bool trace_tree_alloc = False @bool trace_tree_edit = False @bool trace_tree_gc = False @bool trace_tree_redraw = False @bool verbose_trace_color_parser = False @string trace_bindings_filter = @string trace_bindings_pane_filter =
May 28, 2018 Leo 5.7.3, https://leo-editor.github.io/leo-editor/ is now available on [GitHub](leo-editor/leo-editor).
Leo is an IDE, outliner and PIM, as described [here](https://leo-editor.github.io/leo-editor/preface.html).
The highlights of Leo 5.7.3
Added support for Jedi autocompletion.
Much improved python_terminal plugin.
Much improved recursive import script.
New leo_babel plugin.
Leo’s pylint command writes clickable links.
Smart searches for functions and methods.
Allow separate bindings for numeric keypad keys
Added easy-to-use diff-related wrappers for scripts.
Allow local overrides of all abbreviations.
Improved TypeScript importer.
The usual minor bug fixes.
Links
Leo’s home page: https://leo-editor.github.io/leo-editor/
[Documentation](https://leo-editor.github.io/leo-editor/leo_toc.html)
[Tutorials](https://leo-editor.github.io/leo-editor/tutorial.html)
[Video tutorials](https://leo-editor.github.io/leo-editor/screencasts.html)
[Leo on GitHub](leo-editor/leo-editor)
[LeoVue](kaleguy/leovue)
[What people are saying about Leo](https://leo-editor.github.io/leo-editor/testimonials.html)
[A web page that displays .leo files](https://leo-editor.github.io/leo-editor/load-leo.html)
[More links](https://leo-editor.github.io/leo-editor/leoLinks.html)
A complete rewrite of the python_terminal plugin.
BackgroundProcessManager.start_process now takes two new kwargs: link_pattern and link_root:
link_pattern: a regex string or compiled regex pattern, used to determine whether a message contains a link.
link_root: the root @file node.
When present, bpm.put_log uses these as follows:
unl = link_root.get_UNL(with_proto=True, with_count=True)
nodeLink = "%s,%d" % (unl, -line)
c.frame.log.put(s + '\n', nodeLink=nodeLink)
A mass cleanup of Leo’s code, removing many unused tracing statements.
As usual, spellings are not significant. For example:
clone-find-all-flattened = Key_Pad+9
clone-find-all = keypad-PageUp
# Same as keypad+pageup, etc. etc.
Allow local overrides of @data global-abbreviations & @outline-data tree-abbreviations leo-editor/leo-editor#904
Commands that DO use the printer:
print-body print-html print-node print-expanded-body print-expanded-html print-marked-bodies print-marked-html print-marked-nodes print-tree-bodies print-tree-html print-tree-nodes
Commands that DON’T use the printer:
gc-show-summary show-all-uas show-bindings show-buttons show-commands show-focus show-node-uas show-plugin-handlers show-plugins-info show-settings show-stats show-style-sheet
For documentation, see the leo/plugins/leo_babel/doc folder.
The recursive import script now adds disambiguating headline comments as follows:
If a node is a descendant of a class node, the script prepends the class’s name:
aClass.headline
Otherwise, the script appends the file name:
headline (x.py)
This is a huge help when using the clone-find commands.
Clicking on underlined links in the log pane takes you to the proper node and line.
Removed @bool trace_import.
Removed @bool trace_bind_key_exceptions.
The find-def command is typically invoked by control-clicking a function name. This command now will search for possible alternative spellings of the name if no match is found initially:
If the original name contains an underscore, say x_y, the second search will be for the camelCase version, xY.
Otherwise, we assume the name may be camelCase, say xY, and we attempt to convert it to x_y.
A second search is attempted only if the converted name is different from the original. In particular, names starting with a leading underscore are never converted.
The new setting: @bool find-def-creates-clones (default False) controls whether a clone-find-flattened command is used to show all matching definitions. This setting has no effect when only one definition is found.