*voom.txt*      VOoM -- Vim two-pane outliner
Last Modified: 2014-06-22
Version: 5.1
VOoM -- Vim two-pane outliner, plugin for Python-enabled Vim 7.x
Website: http://www.vim.org/scripts/script.php?script_id=2657
Author: Vlad Irnov (vlad DOT irnov AT gmail DOT com)
License: CC0, see http://creativecommons.org/publicdomain/zero/1.0/


    Overview  . . . . . . . . . . . . . . . . . . . .|voom-overview|
    Requirements  . . . . . . . . . . . . . . . . . .|voom-requirements|
    Installation  . . . . . . . . . . . . . . . . . .|voom-install|
    Quick Start . . . . . . . . . . . . . . . . . . .|voom-quickstart|
    ALL MAPPINGS & COMMANDS . . . . . . . . . . . . .|voom-map|
    Options . . . . . . . . . . . . . . . . . . . . .|voom-options|
    OUTLINING (:Voom) . . . . . . . . . . . . . . . .|voom-Voom|
    EXECUTING NODES (:Voomexec) . . . . . . . . . . .|voom-Voomexec|
    __PyLog__ BUFFER (:Voomlog) . . . . . . . . . . .|voom-Voomlog|
    Add-ons . . . . . . . . . . . . . . . . . . . . .|voom-addons|
    Implementation notes  . . . . . . . . . . . . . .|voom-notes|


==============================================================================
Overview   [[[1~
                                                 *voom-overview*
VOoM (Vim Outliner of Markups) is a plugin for Vim that emulates a two-pane
text outliner.

Home page: http://www.vim.org/scripts/script.php?script_id=2657
Screenshots and an animation: http://vim-voom.github.io/
Bug reports, questions, requests: https://github.com/vim-voom/vim-voom.github.com/issues
Supplementary materials: https://github.com/vim-voom/VOoM_extras

VOoM was originally written to work with start fold markers with level numbers,
such as in this help file. This is the most versatile outline markup -- it is
suitable for organizing all kinds of files, including source code, and it
allows features not possible with other markups (|fold-marker|).
(Markers are specified by option 'foldmarker'. End fold markers with levels are
not supported.)

VOoM can currently handle a variety of markup formats that have headlines and
support an outline structure, including popular lightweight markup languages.
(Headlines are also called headings, headers, section headers, titles.)
Available markup modes:
    fmr, fmr1, fmr2  |voom-mode-fmr|
    wiki             |voom-mode-wiki|
    vimwiki          |voom-mode-vimwiki|
    dokuwiki         |voom-mode-dokuwiki|
    viki             |voom-mode-viki|
    org              |voom-mode-org|
    rest             |voom-mode-rest|
    markdown         |voom-mode-markdown|
    pandoc           |voom-mode-pandoc|
    hashes           |voom-mode-hashes|
    txt2tags         |voom-mode-txt2tags|
    asciidoc         |voom-mode-asciidoc|
    latex            |voom-mode-latex|
    html             |voom-mode-html|
    thevimoutliner   |voom-mode-thevimoutliner|
    vimoutliner      |voom-mode-vimoutliner|
    taskpaper        |voom-mode-taskpaper|
    python           |voom-mode-python|
    various other    |voom-mode-various|


FEATURES AND BENEFITS:
    - VOoM is a full-featured outliner. It has a complete set of commands for
      outline structure manipulation: move nodes up/down, promote/demote,
      copy/cut/paste, insert new node, sort in various ways, randomize.
    - There are many one-character mappings for efficient outline navigation
      which can be combined into complex commands, e.g., "UVD" selects all
      siblings of the current node.
    - VOoM is mice-friendly: outlines can be browsed with a mouse.
    - An outline can be searched (:Voomgrep). Boolean AND/NOT searches (OR is
      provided by |/bar|). Hierarchical searches (tag inheritance).
    - An outline is updated automagically on entering the corresponding Tree
      buffer.
    - VOoM works with Vim buffers, not with files on disk as ctags-based tools.
    - VOoM is not a 'filetype' plugin. It has (almost) no side effects on the
      buffer being outlined.
    - VOoM is not tied to a particular outline format. It works with many
      popular light-weight markup languages.
    - VOoM is fast and efficient enough to handle MB-sized files with >1000
      headlines. (Some markup modes are slower than other.)

There are four main Ex commands: Voom, Voomhelp, Voomexec, Voomlog.

:Voom [MarkupMode]
            Scan the current buffer for headlines and create an outline from
            them. By default, headlines are lines with a start fold marker
            (specified by option 'foldmarker') followed by a number.
            To work with headlines in a different format, an argument
            specifying the desired markup mode must be provided, see above and
            |voom-markup-modes|. There is an argument completion for installed
            markup modes: type ":Voom " and press <Tab> or <C-d>.
            The outline is displayed in a special buffer in a separate window
            which emulates the tree pane of a two-pane outliner. Such buffers
            are referred to as Tree buffers. The current buffer becomes a Body
            buffer. Each Tree line is associated with a region (node) of the
            corresponding source buffer (Body). Nodes can be navigated and
            manipulated in the Tree: moved up/down, promoted/demoted,
            copied/cut/pasted, marked/unmarked, sorted, etc.
            See OUTLINING (|voom-Voom|) for details.

                                                 *voom-Voomhelp*
:Voomhelp   Open help file voom.txt as an outline in a new tabpage. If voom.txt
            is installed via |helptags|, it is opened as a Vim help file
            (:tab help voom.txt) so that all help tags will be active.


VOoM also includes two utilities useful when working with Vim and Python
scripts -- commands :Voomexec and :Voomlog. They can be used independently of
the outlining functionality provided by the command :Voom. These commands
attempt to emulate similar features of Leo outlining editor. A Python file with
code snippets organized via fold markers, plus the command :Voomexec, plus the
PyLog buffer is an alternative to running Python's interactive interpreter.

:Voomexec   Execute the contents of the current node or fold as a Vim script or
            Python script. This is useful for testing code snippets and for
            organizing short scripts by segregating them into folds. This
            command does not require an outline to be created and can be used
            with any buffer that has folds and has fold method set to marker.
            See EXECUTING SCRIPTS (|voom-Voomexec|) for details.

:Voomlog    Create scratch buffer __PyLog__ and redirect Python's sys.stdout
            and sys.stderr to it. This is useful when developing Python scripts
            and when scripting Vim with Python. This feature is not related to
            folding or outlining and is completely independent from the rest of
            the plugin.
            See __PyLog__ BUFFER (|voom-Voomlog|) for details.

See |voom-quickstart| for a quick introduction to VOoM outlining.
See |voom-map| for a concise list of all VOoM commands (cheat sheet).

==============================================================================
Limitations   [[[2~

==============================================================================
File size   [[[3~

VOoM outlining is not scalable to large outlines. The bottleneck is the brute
force update of outline data. Such update, which scans the Body buffer for
headlines and recreates the outline, must be done whenever the user enters a
Tree buffer after modifying the corresponding Body--we can't possibly know what
the user did with the Body while he was away from the Tree.

Fortunately, the performance is good enough for comfortable work with MB-sized
files even on an old hardware. I developed VOoM on a 2002 notebook with 1.6GHz
Pentium 4 Mobile processor. Sample outline "calendar_outline.txt" is
approaching the usable size limit on such old hardware: >
    3.2 Mb, 56527 lines, 4160 headlines.
When moving to Tree after modifying Body, the pause due to outline update is
noticeable but still less than a second: 0.17-0.42 sec. A 2013 entry-level
notebook with 4x Intel Core i3-3120M @ 2.50GHz processor is 5-6 times faster.

Browsing an outline is always fast regardless of it's size.

In case of the stress-test file "calendar_outline.txt", the time-consuming step
is not just scanning for fold markers, but also comparing >4000 headlines
between the old and new outlines, or, if outlines are very different, setting
all lines in the Tree buffer. This means that much larger files can be outlined
comfortably if they have much fewer headlines.

==============================================================================
Numbered Markers: Pros and Cons   [[[3~

VOoM can now handle a variaty of markup formats, but it was originally designed
to work with start fold markers with levels: {{{1, {{{2, etc. Numbered start
fold markers have many advantages:
    - It is a built-in Vim folding method (:set fdm=marker).
    - Folding is fast, suitable for MB-sized files with >1000 headlines.
    - More flexible than indent-based or syntax-based folding. Suitable for
      outlining of most file types, including source code. This is really the
      only viable option for organizing the source code as an outline.
    - They are easy to parse and to search for. Area after the level number is
      a natural place for storing node attributes.
    - Fold markers without levels are handy for folding smaller regions.

One drawback of numbered fold markers is that inserting them is somewhat
awkward and slow. This is not a big deal if outline nodes have a lot of body
text: most of the time is spent writing the body text rather than creating
headlines. For outlines that consist mostly of headlines (e.g., a shopping
list) an indent based outlining mode is more appropriate. See plugins such as
Vim Outliner, The Vim Outliner, TaskPaper.

P.S. I wrote a simple plugin that helps insert start fold markers with levels:
http://www.vim.org/scripts/script.php?script_id=2891

==============================================================================
VOoM is not a 'filetype' plugin   [[[3~

This is a design philosophy rather than a limitation. VOoM is expected to work
with files of any 'filetype': source code, plain text notes, Vim help file, a
large wiki file, a custom GTD format. The command :Voom [markup], which creates
an outline, does not configure the current buffer (Body) in any substantial
way: it does not set Body syntax highlighting, indent settings, folding
settings, mappings (with the exception of |voom-shuttle-keys|).

In other words, VOoM is designed to have (almost) no side effects on the buffer
being outlined (Body). All mappings are bound to the Tree pane (except for
shuttle keys).

In contrast, other text outliners are usually geared toward taking notes and
managing tasks (VO, TVO, Emacs Org-mode). They use special format and typically
provide for custom syntax highlighting and folding, a tagging system, clickable
URLs, intra- and inter-outline linking, mappings to insert dates and other
things. VOoM does not provide such features because they should be
'filetype'-specific.

==============================================================================
Other text outliners  [[[2~

Leo outlining editor:
    http://leoeditor.com/
    - The __PyLog__ buffer, which is created by the command :Voomlog, is the
      equivalent of Leo's log pane.
    - The :Voomexec command is like Leo's Execute Script command when executed
      in a node which contains the @others directive.
    - Mark/Unmark nodes operations are modeled after identical Leo commands.
    - Like Leo, VOoM can save which nodes in the Tree are expanded/contracted
      and which node is the selected node. The difference from Leo is that this
      is done manually via Tree commands and mappings.

The "Tag List" Vim plugin:
    http://vim.sourceforge.net/scripts/script.php?script_id=273
    - Conceptually, VOoM is similar to the "Tag List" plugin and other source
      code browsers. "Tag List" uses the "ctags" program to scan files for
      tags. VOoM uses Python scripts to scan Vim buffer for start fold markers
      with levels or some other headline markers.

Other Vim scripts for outlining are listed at
    http://vim.wikia.com/wiki/Script:List_of_scripts_for_outlining?useskin=monobook

Emacs Org-mode:
    http://orgmode.org/
Emacs oultining modes:
    http://www.emacswiki.org/emacs/CategoryOutline

Code Browser:
    http://tibleiz.net/code-browser/

Listings of outliner programs:
    http://en.wikipedia.org/wiki/Outliner
    http://texteditors.org/cgi-bin/wiki.pl?OutlinerFamily
    http://www.outlinersoftware.com/topics/viewt/807/0/list-of-outliners

==============================================================================
Requirements   [[[1~
                                                 *voom-requirements*
VOoM uses Python and requires Python-enabled Vim 7.x, that is Vim compiled
with the Python interface. Your Vim is Python-enabled if it can do >
    :py print 2**0.5
    :py import sys; print sys.version
Python version should be 2.4 - 2.7. Python 3 is not supported.
Vim version 7.2 or above is preferred.
Vim should be compiled using "normal" or bigger feature list.

==============================================================================
Vim and Python on Windows   [[[2~

Getting Vim and Python to work together on Windows can be a bit tricky
(|python-dynamic|).
    - Obviously, Python must be installed. If not, use Python version 2.7.x
      Windows installer from http://www.python.org/ . The installer will put
      Python DLL in the system search path.
    - Vim must be compiled with the Python interface (:echo has("python")).
    - Finally, the version of Python DLL against which Vim was compiled must
      match the installed Python version.

There are several Vim installers for Windows:
Installer from vim.org, http://www.vim.org/download.php , installs Vim
compiled against Python 2.7 as of version 7.4 (gvim.exe only).
Installer from http://sourceforge.net/projects/cream/files/ (gVim one-click
installer for Windows) should have Vim compiled against Python 2.7.

It is not hard to compile your own Python-enabled Vim on Windows. See
http://vim.wikia.com/wiki/Build_Python-enabled_Vim_on_Windows_with_MinGW?useskin=monobook

==============================================================================
Installation   [[[1~
                                                 *voom-install*
To install VOoM plugin manually:
1) Move the contents of folders "autoload", "doc", "plugin" into the respective
folders in your local Vim directory, that is >
    $HOME/vimfiles/       (Windows)
    $HOME/.vim/           (Unix)
This should make commands :Voom, :Voomhelp, :Voomexec, :Voomlog availabe in all
buffers. (To find out what Vim sees as $HOME, do ":echo $HOME".)
2) Execute the :helptags command to update help tags (|add-local-help|): >
    :helptags $HOME/vimfiles/doc       (Windows)
    :helptags $HOME/.vim/doc           (Unix)

Alternatively, use Pathogen ( https://github.com/tpope/vim-pathogen )
and install VOoM as a bundle, or use a Vim plugin manager (vundle,
vim-addon-manager).

NOTE: VOoM uses the autoload mechanism (|autoload|). The bulk of its Vim script
code is in ../autoload/voom.vim . It is sourced, and the main Python module
../autoload/voom/voom_vim.py is imported, only after a Voom command is executed
for the first time.
NOTE: Directory ../autoload/voom contains VOoM Python modules.
When ../autoload/voom.vim is sourced, its Python code adds directory
../autoload/voom to sys.path and then imports "voom_vim.py" and other required
.py files. This folder will also contain .pyc files created by Python. In some
rare cases it may be necessary to delete the old .pyc files when installing a
new version.

==============================================================================
Quick Start   [[[1~
                                                 *voom-quickstart*
This Quick Start guide explains VOoM's most essential commands and principles.
For a concise list of all VOoM commands (a cheat sheet) see |voom-map|.
This guide teaches VOoM by use. You can use this help file, voom.txt, for
practice. It is organized as an outline using numbered start fold markers. You
can also practice with source files:
    ../autoload/voom.vim  or  ../autoload/voom/voom_vim.py  or even
    $VIMRUNTIME/autoload/netrw.vim  or  $VIMRUNTIME/doc/pi_netrw.txt .
Make sure not to save changes, or work with a copy of practice file.

1) CREATE OUTLINE (:Voom [markup])
----------------------------------
Open a practice file in Vim tabpage. Execute the command >
    :Voom
It will scan the current buffer for headlines and create a Tree buffer, as in
this screenshot: http://vim-voom.github.io/pics/voom_voomhelp.png
The current buffer becomes a Body buffer.

        Each VOoM Tree buffer is associated with exactly one Body buffer and
        vice versa.
        Tree buffers are 'nomodifiable' and should never be edited manually.

Press "q" in the Tree buffer to delete the outline and the Tree buffer.

        The outline is also deleted automatically whenever the Tree buffer is
        unloaded, so you can do :bun, :bd, :bw in the Tree buffer, or close
        Tree windows with "C-w c".

Create another outline with the command: >
    :Voom org
It will scan the current buffer for headlines in the Emacs Org-mode format:
lines starting with *, **, etc. Since there are no such lines, the Tree buffer
will contain only the title line. (It actually represents the node number 1,
the entire Body buffer in this case.).

Delete the wrong outline by pressing "q".
Create the correct outline again with the command :Voom .

        By default, the command :Voom without an argument creates the outline
        from lines with {{{1, {{{2, etc. The actual fold marker string is
        obtained from window-local option 'foldmarker'.
        To outline headlines in another format, an argument must be provided.
        For example, download AsciiDoc user guide from
        http://asciidoc.org/userguide.txt
        Open it Vim and execute
            :Voom asciidoc
        There is an argument completion: you can type "Voom a" and press <Tab>
        or <C-d>.
        Download reStructuredText user guide from
        http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.txt
        Open it Vim and execute
            :Voom rest
        Download Panoc user guide from
        https://raw.githubusercontent.com/jgm/pandoc/master/README
        Open it Vim and execute
            :Voom pandoc

2) SWITCHING BETWEEN TREE AND BODY BUFFERS (<Return> and <Tab>)
---------------------------------------------------------------
Since we are dealing with a two-pane outliner, it is important to have keys for
quick switching between the two panes. By default such keys are Normal mode
<Return> and <Tab> keys. (One may choose other keys, see |voom-shuttle-keys|)

<Return> (also known as <CR> or <Enter>) selects the node under the cursor and
then cycles between the corresponding Tree and Body windows. So, to select
another node, move to it with h, j, etc. and hit Return.

<Tab> simply cycles between Tree and Body windows without selecting new nodes.

Exercise:
- Make sure you are in Normal mode. Press <Tab> a few times. Stop when you are
  in the Tree window.
- Jump to the last line/node by pressing "G".
- Press <Return> once. The corresponding (last) node will be shown in the Body
  window, but the cursor will stay in the Tree window.
- Press <Return> again. The cursor will move to Body window. Subsequent presses
  of <Return> will shuttle the cursor between the Tree and Body.
- See what happens after you move to different regions of the Body buffer and
  press <Return> a few times.

        <Return> and <Tab> are the only keys that get mapped in Body buffers.
        All other VOoM mappings and most commands are for Tree buffers only.

        Whenever you need to do something with an outline, first make sure you
        are in Normal mode, then switch to the Tree buffer by pressing Tab or
        Return.
        The Tree buffer can be viewed as a custom Vim mode -- Outliner mode.
        Vim's Normal and Visual mode commands that modify text are changed in
        the Tree buffer to navigate and edit the outline structure. For
        example, "dd", instead of deleting a line, deletes a node and its
        subnodes.

        You can also use all standard Vim command to handle Tree and Body
        windows (|windows|): split them with :split, resize and reposition them
        with <C-w> commands, etc.
        Example: to duplicate the current outline in another tabpage, execute
        ":tab split" while in a Tree or Body buffer and then press <Return>.

3) OUTLINE NAVIGATION (<Space>, Arrow Keys, Mouse)
--------------------------------------------------
<Space> in the Tree buffer expands/contracts the node under the cursor without
selecting it. Standard Vim folding command (zo, zc, zR, zM, etc.) also
expand/contract nodes.

One can navigate the outline with only <Space>, <Return> and <Tab>:
move between Tree lines with j, k, H, M, L, etc.;
press <Space> to expand/contract branches if needed;
press <Return> and <Tab> to select nodes and to switch between Tree and Body.

<Up>, <Down>, <Left>, <Right> arrow keys move around the Tree and select nodes
(Normal mode).

The Left Mouse Click in the Tree window selects the node under mouse. If the
click is outside of the headline text, the node's expanded/contracted status is
toggled. This means the outline can be browsed with the mouse alone. This of
course requires mouse support (GUI Vim, :set mouse=a).

Tree buffers have many other mappings for outline navigation. For example, "P"
moves the cursor to the parent node. See |voom-map| for a complete list.

        Most VOoM mappings are for Normal mode. Some also work in Visual mode.
        Very few accept a count. You should always leave Insert mode if you
        need to work with an outline.

4) EDIT HEADLINES AND NODES ("i", "I")
--------------------------------------
Press "i" in the Tree buffer (Normal mode) to edit the headline of node under
the cursor. The cursor is moved into the Body window, placed on the first line
of the corresponding node and usually on the first character of the headline
text. Modify the headline text and go back into the Tree (Tab or Return): the
outline will be updated automatically.

Press "I" in the Tree buffer to go to the last Body line of the corresponding
node. This is useful when you want to append text to a node or view the end of
a long node.

To add (insert) a new headline: press "aa" or "AA" in the Tree buffer.

        As you can see, we don't actually edit the text of headlines or nodes.
        We edit the corresponding lines in the Body buffer, then switch back to
        the Tree buffer and let VOoM update the outline.
        The outline is always updated automatically on entering the Tree
        buffer (via BufEnter autocmd).

5) OUTLINE OPERATIONS
---------------------
To rearrange the outline structure, one must first move into the Tree buffer
(press Tab or Return). The following Tree mappings work on the node under the
cursor when in Normal mode, or on a range of sibling nodes when in Visual mode.

<C-Up>, <C-Down> move nodes Up/Down.
<C-Left>, <C-Right> move nodes Left/Right (promote/demote).
The above CTRL mapping may not be recognized in a terminal. One can also move
nodes Up/Down/Left/Right via two-key mappings:
    ^^  __  <<  >> 
or via LocalLeader mappings:
    <LocalLeader>u  <LocalLeader>d  <LocalLeader>l  <LocalLeader>r

"yy" copies nodes into the "+ register (system clipboard).

"dd" deletes nodes and copies them into the "+ register.

"pp" pastes nodes from the "+ register below the current node or fold.
One can move nodes over a long distance by cutting them with "dd", moving to a
new location, and pasting them with "pp".

Outline commands started in Visual mode always end in Visual mode. Paste ("pp")
ends in Visual mode if the pasted region contains >1 nodes. This makes it easy
to apply several commands to the same range of nodes. For example, there is no
command Paste-As-Child. Instead, one can always do "pp" followed by ">>".

To undo the most recent outline operation, switch to the Body buffer (press
Tab or Return) and do undo ("u").
Exercise:
- Select all lines/nodes in the Tree buffer except the first title line: 2GVG .
- Press "dd" to delete all selected nodes.
- Go to Body buffer (Tab or Return).
- Press "u" to undo.
- Go back to Tree (Tab or Return).

6) :Voomlog
-----------
The command :Voomlog creates the __PyLog__ buffer and redirects Python's stdout
and stderr to it. Examples: >
    :Voomlog
    :py assert 2==3
    :py print u"\u042D \u042E \u042F"
    :py import this
To delete the __PyLog__ buffer and restore Python's original stdout and stderr,
do :bun, :bd, or :bw .


==============================================================================
# ALL MAPPINGS & COMMANDS #   [[[1x=  ~
                                                 *voom-map*
------------------------------------------------------------------------------
    MAIN COMMANDS ~
------------------------------------------------------------------------------
:Voom [MarkupMode]  Create the outline for the current buffer. |voom-Voom|
:Voomhelp           Open voom.txt as an outline in a new tabpage. |voom-Voomhelp|
:Voomexec [vim|py]  Execute node or fold as [type] script. |voom-Voomexec|
:Voomlog            Create __PyLog__ buffer. |voom-Voomlog|

------------------------------------------------------------------------------
    SHUTTLE KEYS (BODY AND TREE BUFFERS) ~
------------------------------------------------------------------------------
                    These two keys shuttle the cursor between the corresponding
                    Tree and Body windows.
                    These are the only keys that get mapped in Bodies.
                    Body: Normal mode. Tree: Normal and Visual modes.
                    Configurable by the user, see |voom-shuttle-keys|.

<Return>            Select the node under the cursor. If already selected, move
                    the cursor to Tree or Body window. A Tree or Body window is
                    created in the current tabpage if there is none.

<Tab>               Move the cursor to Tree or Body window.


------------------------------------------------------------------------------
    OUTLINE NAVIGATION (TREE BUFFER) ~
------------------------------------------------------------------------------
<LeftRelease>       Mouse left button click. Select the node under mouse.
                    Toggle node's expanded/contracted state if the click is
                    outside of headline text. (N)
<2-LeftMouse>       Mouse left button double-click. Disabled.

<Up>                Move the cursor Up and select new node. (N)

<Down>              Move the cursor Down and select new node. (N)

<Right>             Move the cursor to the first child and select it. (N)
                    If the current node is contracted, it is expanded first.

<Left>              Move the cursor to the parent and select it. (N)
                    If the current node is expanded, it is contracted first.

------------------------------------------------------------------------------
    EXPAND/CONTRACT NODES
------------------------------------------------------------------------------
<Space>             Expand/contract the current node (node under the cursor). (N)

O                   Recursively expand the current node and its siblings. (N)
                    Recursively expand all nodes in Visual selection. (V)
                    Similar to |zO|.

C                   Recursively contract the current node and its siblings. (N)
                    Recursively contract all nodes in Visual selection. (V)
                    Similar to |zC|.

zc, zo, zM, zR, zv, etc.
                    These are Vim's standard folding commands.
                    They expand/contract nodes (|fold-commands|).
                    Note: zf, zF, zd, zD, zE are disabled.

------------------------------------------------------------------------------
    MOVE THE CURSOR TO ANOTHER NODE (in addition to j, k, H, M, L, etc.)
------------------------------------------------------------------------------
o                   Down to the first child of the current node (like |zo|). (N)

c                   Up to the parent node and contract it (like |zc|). (N)
P                   Up to the parent node. (N)

K                   Up to the previous sibling.   (N,V,count)
J                   Down to the next sibling.     (N,V,count)

U                   Up to the uppermost sibling.  (N,V)
D                   Down to the downmost sibling. (N,V)

=                   Put the cursor on the currently selected node. (N)

------------------------------------------------------------------------------
    GO TO SPECIALLY MARKED NODE |voom-special-marks|
------------------------------------------------------------------------------
x                   Go to next marked node (find headline marked with "x"). (N)
X                   Go to previous marked node. (N)

+                   Put the cursor on the startup node (node with "=" mark in
                    Body headline). Warns if there are several such nodes. (N)

------------------------------------------------------------------------------
    SHOW (ECHO) INFORMATION FOR NODE UNDER THE CURSOR
------------------------------------------------------------------------------
s                   Show Tree headline (text after the first '|'). (N)
S                   Show UNL. Same as :Voomunl (|voom-Voomunl|). (N)


------------------------------------------------------------------------------
    OUTLINE OPERATIONS (TREE BUFFER) ~
------------------------------------------------------------------------------
i                   Edit the first line (headline) of the current node. (N)
I                   Edit the last line of the current node. (N)

aa  <LocalLeader>a
                    Add a new node after the current node or fold. (N)

AA  <LocalLeader>A
                    Add a new node as the first child of the current node. (N)

R                   Switch to Body buffer, select the line range corresponding
                    to the current node or to nodes in Visual selection. (N,V)

^^  <C-Up>  <LocalLeader>u
                    Move node(s) Up. (N,V)

__  <C-Down>  <LocalLeader>d
                    Move node(s) Down. (N,V)

<<  <C-Left>  <LocalLeader>l
                    Move node(s) Left, that is  Promote. (N,V)
                    By default, this is allowed only if nodes are at the end of
                    their subtree, see |g:voom_always_allow_move_left|.

>>  <C-Right>  <LocalLeader>r
                    Move node(s) Right, that is Demote. (N,V)

yy                  Copy node(s). (N,V)

dd                  Cut node(s).  (N,V)

pp                  Paste node(s) after the current node or fold. (N)

                    NOTE: By default, Copy, Cut, Paste use the "+ register if
                    Vim  has clipboard support, the "o register otherwise.
                    See |g:voom_clipboard_register|.

------------------------------------------------------------------------------
    SORT |voom-sort|
------------------------------------------------------------------------------
:VoomSort [options] Sort siblings of node under the cursor.
                    Options are: "deep" (also sort all descendant nodes),
                    "i" (ignore-case), "u" (Unicode-aware), "r" (reverse-sort),
                    "flip" (reverse), "shuffle" (randomize).

:[range]VoomSort [options]
                    Sort siblings in the [range]. The start and end range lines
                    must be different.

------------------------------------------------------------------------------
    MARK/UNMARK |voom-special-marks|
------------------------------------------------------------------------------
<LocalLeader>m      Mark node(s): add "x" to Body headlines. (N,V)

<LocalLeader>M      Unmark node(s): remove "x" from Body headlines. (N,V)

<LocalLeader>=      Mark node as startup node: add "=" to Body headline and
                    remove "=" from all other headlines. When cursor is on
                    Tree line 1, all "=" marks are removed. (N)

------------------------------------------------------------------------------
    SAVE/RESTORE TREE BUFFER FOLDING |voom-tree-folding|
------------------------------------------------------------------------------
:[range]VoomFoldingSave
                    Save Tree folding (writes "o" marks in Body headlines).

:[range]VoomFoldingRestore
                    Restore Tree folding (reads "o" marks in Body headlines).

:[range]VoomFoldingCleanup
                    Cleanup "o" marks: remove them from nodes without children.

<LocalLeader>fs     Save Tree folding for the current node and all descendant
                    nodes. Same as :VoomFoldingSave. (N)

<LocalLeader>fr     Restore Tree folding for the current node and all descendant
                    nodes. Same as :VoomFoldingRestore. (N)

<LocalLeader>fas    Save Tree folding for entire outline.
                    Same as :%VoomFoldingSave. (N)

<LocalLeader>far    Restore Tree folding for entire outline.
                    Same as :%VoomFoldingRestore. (N)


------------------------------------------------------------------------------
    SEARCH NODES (Body and Tree buffers) ~
------------------------------------------------------------------------------
:Voomunl            Display node's UNL (Uniform Node Locator). |voom-Voomunl|

:Voomgrep [pattern(s)]
:Voomgrep {pattern1} and *{pattern2} not {pattern3} not *{pattern4} ...
                    Search the outline for pattern(s) and display UNLs of nodes
                    with matches in the quickfix window.
                    Patterns are separated by words "and"/"not" to indicate
                    Boolean AND/NOT search.
                    An "*" in front of a pattern triggers hierarchical search.
                    If no patterns are provided, the word under the cursor is used.
                    |voom-Voomgrep|

------------------------------------------------------------------------------
    QUIT (DELETE), TOGGLE OUTLINE ~
------------------------------------------------------------------------------
                    (see |voom-quit|)
q                   Delete outline. (Tree buffer Normal mode mapping)
:Voomquit           Delete outline. (Tree or Body buffer)
:VoomQuitAll        Delete all VOoM outlines. (any buffer)
:VoomToggle [MarkupMode]
                    Create outline if current buffer is a non-VOoM buffer.
                    Delete outline if current buffer is a Tree or Body buffer.
:Voomtoggle         Minimize/Restore Tree window. (Tree or Body)

------------------------------------------------------------------------------
    VARIOUS ~
------------------------------------------------------------------------------
Voominfo [all]      Print information about the current outline and VOoM
                    internals. Uses Python "print" function. (any buffer)

<LocalLeader>e      Execute node. Same as :Voomexec. Tree buffer only. (N)

The following commands are intended for VOoM development and are created only
if there exists variable "g:voom_create_devel_commands". (any buffer)
VoomReloadVim       Reload ../autoload/voom.vim . Outlines are preserved.
VoomReloadAll       Wipe out all outlines (same as :VoomQuitAll), wipe out
                    PyLog buffer, reload VOoM code: delete Python voom_*
                    modules from sys.modules, reload ../autoload/voom.vim ,
                    re-import ../autoload/voom/voom_vim.py .
 

==============================================================================
Options   [[[1~
                                                 *voom-options*
This section describes VOoM options and other means of VOoM customization.

VOoM options are Vim global variables that can be defined by users in their
.vimrc files. Example: >
    let g:voom_tree_placement = "top"
    let g:voom_tree_height = 14

Note that changing some options requires Vim restart.

==============================================================================
Window positioning [[[2~

g:voom_tree_placement   ~
    Where Tree window is created: "left", "right", "top", "bottom"
    This is relative to the current window.
    Default: "left"
    Example: >
        let g:voom_tree_placement = "right"

g:voom_tree_width   ~
    Initial Tree window width.
    Default: 30
    Example: >
        let g:voom_tree_width = 40

g:voom_tree_height   ~
    Initial Tree window height.
    Default: 12
    Example: >
        let g:voom_tree_height = 15

g:voom_log_placement   ~
    Where __PyLog__ window is created: "left", "right", "top", "bottom"
    This is far left/right/top/bottom.
    Default: "bottom"
    Example: >
        let g:voom_log_placement = "top"

g:voom_log_width   ~
    Initial __PyLog__ window width.
    Default: 30
    Example: >
        let g:voom_log_width = 40

g:voom_log_height   ~
    Initial __PyLog__ window height.
    Default: 12
    Example: >
        let g:voom_log_height = 15

==============================================================================
Tree/Body shuttle keys   [[[2~
                                                 *voom-shuttle-keys*
Since VOoM emulates a two-pane outliner, it's important to have keys that
shuttle the cursor between the two panes. By default, such keys are <Return>
and <Tab>. These keys are used in buffer-local mappings in Trees (Normal and
Visual modes) and in Bodies (Normal mode). Note that these are the only keys
that get mapped in Body buffer when an outline is created by the command :Voom.

The following two options allow to use keys or key combinations other than
<Return> and <Tab>:

g:voom_return_key   ~
    A key that selects the node under the cursor and, if the node is already
    selected, moves the cursor between the Tree and Body windows.
    Default: "<Return>"

g:voom_tab_key   ~
    A key that simply moves the cursor between the Tree and Body windows.
    Default: "<Tab>"

Example, use Ctrl-Return and Ctrl-Tab: >
    let g:voom_return_key = "<C-Return>"
    let g:voom_tab_key = "<C-Tab>"


Note that Normal mode <Return> and <Tab> have default meaning in Vim. <Return>
moves the cursor down. This is not very useful since "j" does almost the same
thing. <Tab>/CTRL-I in Normal mode by default goes to a newer position in the
jump list (opposite of CTRL-O, see |CTRL-I|). Thus, although tempting, mapping
<Tab> is usually a bad idea. It seems that Ctrl-Tab still works like default
<Tab>/CTRL-I, at least in GUI Vim, when <Tab> is mapped.

==============================================================================
g:voom_ft_modes, g:voom_default_mode   [[[2~
                                       *g:voom_ft_modes* *g:voom_default_mode*
By default, the :Voom command without an argument creates an outline from lines
with start fold markers with level numbers (the default mode). To outline
another format, an argument specifying the desired markup mode must be
provided. E.g., for a Markdown (MultiMarkdown) file: >
    :Voom markdown

User options "g:voom_ft_modes" and "g:voom_default_mode" change which markup
mode the command :Voom will use when it is invoked without an argument. These
variables do not exist by default, they must be created by the user in .vimrc.
Vim restart is required after these options are changed.


g:voom_ft_modes   ~
"g:voom_ft_modes" is a Vim dictionary: keys are filetypes (|ft|), values are
corresponding markup modes (|voom-markup-modes|). Example: >
    let g:voom_ft_modes = {'markdown': 'markdown', 'tex': 'latex'}
This option allows automatic selection of markup mode according to the filetype
of the source buffer. If "g:voom_ft_modes" is defined as above, and 'filetype'
of the current buffer is "tex", then the command >
    :Voom
is identical to the command >
    :Voom latex


g:voom_default_mode   ~
"g:voom_default_mode" is a string with the name of the default markup mode.
Example, if there is this in .vimrc: >
    let g:voom_default_mode = 'asciidoc'
then, the command >
    :Voom
is equivalent to >
    :Voom asciidoc
unless "g:voom_ft_modes" is also defined and has an entry for the current
filetype.


NOTE: To overide these two options, that is to force the original default mode,
specify the "fmr" mode (|voom-mode-fmr|): >
    :Voom fmr

NOTE: The name of the current markup mode, if any, is noted on the first line
of the Tree buffer. You can also run the command :Voominfo [all] to see
detailed information.

==============================================================================
g:voom_clipboard_register   [[[2~
                                                 *g:voom_clipboard_register*
By default, VOoM's copy/cut/paste operations use the "+ register (system
clipboard) to store the contents of nodes. This means outlines can be
copied/cut/pasted between different Vim instances and in other applications.
If the "+ register is not available because Vim was compiled without clipboard
support (|+clipboard|), the "o register is used instead (mnemonic: outline).

To make VOoM always use the register of your choice, add the following to
.vimrc and restart Vim: >
    let g:voom_clipboard_register = "o"
where "o" can be any a-z letter, that is one of the 26 lowercase registers, see
|registers| and |quote_alpha|.

==============================================================================
g:voom_always_allow_move_left   [[[2~
                                               *g:voom_always_allow_move_left*
By default, outline operation Move Left (<<, Ctrl-Left, <localleader>l) is
allowed only when the nodes being moved are at the end of their subtree, that
is when there are no siblings below. Suppose there is an outline: >
          |AAA
          . |BBB
          . |CCC
          . |DDD
          |EEE

Node DDD can be moved left, but individual nodes BBB and CCC cannot. To move
BBB left: 1) select nodes BBB, CCC, DDD  2) move them left 3) select CCC and
DDD and move them right. In one motion: put the cursor on BBB and press VD<<j>>
("D" extends selection to the Downmost sibling).

To always allow Move Left, add the following to .vimrc and restart Vim: >
    let g:voom_always_allow_move_left = 1

==============================================================================
Various options   [[[2~

g:voom_verify_oop   ~
    Verify outline after every outline operation (doesn't apply to :VoomSort).
    Default is 1 (enabled).
    Set to 0 to disable (NOT RECOMMENDED!!!, especially with markup modes).

    This option turns on outline verification after most outline operations.
    It will alert to outline corruption, which is very likely if there is a bug
    in outline operation. The downside is that there is a performance hit,
    usually noticeable only with large outlines (>1000 headlines).
    NOTE: Do not disable this option when using complex outlining modes like
    "rest", "latex", "python" -- these markups have intrinsic problems.


g:voom_rstrip_chars_{filetype}   ~
    NOTE: Not applicable when a non-default markup mode is used
    (|voom-markup-modes|).
    This variable must be created for each 'filetype' of interest.
    The value is a string of characters to be stripped from the right side of
    Tree headlines (from before start fold marker) when the default Tree
    headline construction procedure is used and Body has 'filetype' {filetype}.
    Usually, the chars to be stripped are comment chars, space and tab. For
    details, see node >
        OUTLINING (:Voom [markup]) -> Create Outline -> Tree Headline Text
<
    Defaults exist for filetypes "vim", "text", "help": >
        let g:voom_rstrip_chars_vim = "\"# \t"
        let g:voom_rstrip_chars_text = " \t"
        let g:voom_rstrip_chars_help = " \t"


g:voom_user_command   ~
    This option allows to execute an arbitrary user-defined command when
    autoload/voom.vim is sourced. It is a string to be executed via |execute|
    at the very end of autoload/voom.vim. It does not exist by default. This
    option is intended for loading user add-ons, see |voom-addons|.


g:voom_create_devel_commands   ~
    If this variable exists, several commands are created to help during VOoM
    development. See section "Commands" in ../autoload/voom.vim for details.


g:voom_did_load_plugin   ~
    Loading guard for ../plugin/voom.vim .

==============================================================================
Tree 'filetype'   [[[2~

When a Tree buffer is created, its 'filetype' is set to "voomtree"
When the __PyLog__ buffer is created, its 'filetype' is set to "voomlog".
Thus, users can customize these buffers (foldlevel, syntax, wrap/norwap,
list/nolist, bufhidden, etc.) via standard Vim configuration files:
    ~/.vim/ftplugin/voomtree.vim
    ~/.vim/syntax/voomtree.vim
    ~/.vim/after/ftplugin/voomtree.vim

    ~/.vim/ftplugin/voomlog.vim
    ~/.vim/syntax/voomlog.vim
    etc.

NOTE: VOoM itself does not have any of these files.
NOTE: Be careful not to break VOoM by messing with critical settings.

For example, to always set initial Tree 'foldlevel' to 1, create file
    ~/.vim/ftplugin/voomtree.vim
with line
    setl fdl=1


To modify default Tree buffer-local mappings or create new ones:
    1. Create file ftplugin/voomtree.vim .
    2. Copy relevant mappings from voom.vim function voom#TreeMap().
    3. Change {lhs} and/or {rhs}.


To customize Tree buffers differently for different markup modes and Body
filetypes, the following prototype code can be used in voomtree.vim: >

    let s:bnr = bufnr('')
    let [s:mmode, s:MTYPE, s:body, s:tree] = voom#GetModeBodyTree(s:bnr)
    if s:bnr != s:tree | finish | endif
    let s:FT = getbufvar(s:body, '&ft')
    " No markup mode (default mode) or an fmr mode.
    if s:MTYPE == 0
        " do nothing
    " 'filetype' of Body buffer.
    elseif s:FT ==# 'python'
        setl fdl=0
    " Name of markup mode.
    elseif s:mmode ==# 'wiki'
        setl fdl=3
        " Create Tree buffer-local mappings.
        nnoremap <buffer><silent> <Leader>1 :setl fdl=1<CR>
    endif
    unlet s:bnr s:FT s:mmode s:MTYPE s:body s:tree

See also |voom-addons|.

==============================================================================
Misc customization tips   [[[2~

Most VOoM commands can be mapped to key shortcuts or alias commands in .vimrc: >
    nnoremap <LocalLeader><LocalLeader> :Voom<CR>
    nnoremap <LocalLeader>n :Voomunl<CR>
    com! VM Voom markdown
    com! VMT VoomToggle markdown


To make Body headlines stand out, lines with fold markers can be highlighted.
Since I use .txt files for notes, I have the following line in .vimrc  >
    au BufWinEnter *.txt if &ft==#'text' | exe 'syn match ModeMsg /\V\.\*' . split(&fmr, ',')[0] . '\.\*/' | endif
This method is better than using syntax/text.vim because it also works when a
nonstandard foldmarker is specified on file's modeline.

==============================================================================
Relevant Vim settings   [[[2~

When working with numbered start fold markers (default markup mode and "fmr"
modes), the following Vim options determine how the outline is constructed:
    - 'foldmarker' is used to obtain the start fold marker string. There is
      rarely a reason to change this option from default, which is {{{,}}} .
    - 'commentstring' and 'filetype' affect how Tree headline text is
      constructed. For details, see node
        OUTLINING (:Voom [markup]) -> Create Outline -> Tree Headline Text

'foldmethod' for the buffer for which the command :Voom is executed should be
"marker" (:set fdm=marker). This, however, is not required to create an outline
or to use it. Outline operations do not rely on Vim folds, they use start fold
markers with levels. Other folding options (|fold-options|), such as
'foldtext', can be set according to personal preferences and are usually
'filetype'-specific.


<LocalLeader> is used to start many outline operations while in a Tree buffer.
By default, it's backslash. For example, "\d" moves nodes down. To change
<LocalLeader> to another character, assign maplocalleader in .vimrc: >
     let maplocalleader=','


'scrolloff' should be set to 0 (default) or a small number (1 or 2). This
global Vim option affects how the headline is positioned in Body window after
selecting a node in Tree window. For example, after ":set scrolloff=1", the
headline will be on the 2nd window line in Body window. A very large value can
be confusing when switching between Tree and Body windows.


Vim commands for creating and deleting folds are not very useful and are
potentially dangerous when typed accidentally. They can be disabled in .vimrc
as follows: >
     " Disable commands for creating and deleting folds.
     noremap zf <Nop>
     noremap zF <Nop>
     noremap zd <Nop>
     noremap zD <Nop>
     noremap zE <Nop>


Some color schemes (including default) use the same or similar background
colors for selected text (Visual), folded lines (Folded), and current line
(CursorLine) highlight groups. These highlight groups are used in Tree buffers
and it's better if they are easily distinguished from each other.


==============================================================================
OUTLINING (:Voom [markup])   [[[1o~

==============================================================================
Create Outline   [[[2o~
                                                 *voom-Voom*
:Voom [MarkupMode]
            Scan the current buffer for headlines, construct an indent-based
            outline from them, and display it in a specially configured,
            non-modifiable buffer called Tree buffer. The current buffer
            becomes a Body buffer.
            An optional argument specifies the format of headlines. If an
            argument is given, the markup mode defined in module
            "voom_mode_{MarkupName}.py" is used, see |voom-markup-modes|.
            There is argument completion: type ":Voom " and press <Tab> or <C-d>.
            See |g:voom_ft_modes| and |g:voom_default_mode| on how to select
            the markup mode automatically and to change the default mode.

:Voom       By default, headlines are lines a start fold marker (specified by
            option 'foldmarker') followed by a level numbers: {{{3, {{{1, etc.
            The level of each headline is set to the number after the fold
            marker. The headline text is the part before the fold marker (this
            can be customized).

            NOTE: End fold markers with levels, }}}1, }}}3, etc., are ignored
            and should not be used.

            Matching fold markers without level numbers, {{{ and }}}, are
            ignored. They are handy for folding small areas inside numbered
            folds, e.g. parts of functions. The region between {{{ and }}}
            should not contain fold markers with levels.

            For best results, Body 'foldmethod' should be "marker"
            (|fold-marker|). If this is the case, Body nodes are also folds.
            This is not required. Body buffer folding has no effect on the
            outline construction or outline operations.

NOTE: A TREE BUFFER IS NOT MODIFIABLE AND SHOULD NEVER BE EDITED DIRECTLY.
A Tree buffer has many buffer-local mappings for navigating the outline and for
performing outline operations. Most of Vim standard Normal and Visual text
change commands are either disabled or remapped.

Tree buffers are named {bufname}_VOOM{bufnr} where {bufname} and {bufnr} are
the name and number of the corresponding source buffer (Body). The 'filetype'
of Tree buffers is set to "voomtree".

A Tree buffer is displayed in a separate window which is configured to behave
as the tree pane of a two-pane outliner. Every line in a Tree buffer is
associated with a node of the corresponding Body buffer.

Each "node" is a range of Body buffer lines beginning with a headline and
ending before the next headline (or end-of-buffer). The first Tree line
(outline title) is treated as a special node number 1: it is associated with
the region from start of Body buffer to its first headline (or end-of-file); it
has zero lines if the first Body line is a headline.

When a headline is selected in a Tree window (<Return>, <Up>, <Down>, <Left>,
<Right>), the corresponding node is displayed in the Body window. A Tree buffer
has many commands for changing the outline structure of the corresponding Body
buffer: nodes can be deleted, moved, promoted, demoted, marked, etc. Obviously,
a Body buffer can be edited directly as a regular Vim buffer.

The outline data and the Tree buffer are updated automatically on entering the
Tree buffer (on |BufEnter|). The actual update happens if the Body has been
modified since the last update (when Body's |b:changedtick-variable| is
different). This update is the bottleneck that limits the size of outlines that
can be edited comfortably.

A Body buffer is not configured in any substantial way by the command :Voom.
It has only two VOoM-specific mappings: <Return> and <Tab> in Normal mode
(local to buffer). These mappings select the node under the cursor and cycle
between Body and Tree windows. These two mappings can be changed by the user
(|voom-shuttle-keys|). The user is responsible for setting all other Body
settings to his liking: folding, indenting, syntax highlighting and so on
(these are usually determined by Body 'filetype').

==============================================================================
About Fold Markers   [[[3~

(This section applies only to the default markup mode and "fmr" modes.)
The command :Voom does not create an outline of folds. It creates an outline of
start fold markers with level numbers. When Body has option 'foldmethod' set to
"marker", lines in Tree buffer also represent Body folds.

The start fold marker string is obtained from window-local option 'foldmarker'
when the outline is created by the command :Voom. For example, after >
    :set fmr=<<<,>>>
    :Voom
the outline will be created from lines with <<<1, <<<2, <<<3, etc.

Option 'foldmarker' should not be changed while working with an outline. If you
change it, make sure to recreate the outline: delete the Tree buffer and
execute the command :Voom again.

VOoM scans only for _start_ fold markers with level numbers. End fold markers
with levels and fold markers without levels are ignored. This assumes that the
user follows certain rules of using fold markers. These rules make a lot of
sense and are similar to recommendations given in Vim help (|fold-marker|).

1) Use start fold markers with levels, <<<1, <<<2, etc. to start new
   fold/node. These should correspond to important structures: parts and
   chapters in a book, functions and classes in a code.

2) DO NOT USE END FOLD MARKERS WITH LEVELS: >>>1, >>>2, etc. They are
   redundant and are hard to keep track of in a large outline.

3) Do use pairs of matching fold markers without level, <<< and >>>, to fold
   small areas of text (a screenful), such as parts of functions. Make sure
   the area doesn't contain any numbered fold markers.

Files that do have end fold markers with levels are ok for browsing with VOoM,
but outline operations will most definitely produce unintended results.
Consider the following structure: >
    node 0
        node 1   <<<1
            node 1.1 <<<2
        >>>1
    ? ? ? ?
    ? ? ? ?
        node 2   <<<1
        node 3   <<<1
Lines with ? are not part of any fold. But VOoM considers them part of node
1.1 and will move them accordingly when node 1.1 is moved. When node's level
is changed, only number after the start fold marker is updated.

==============================================================================
Special Node Marks   [[[3~
                                                 *voom-special-marks*
NOTE: Special node marks are available only when outlining start fold markers
with levels, that is in the default markup mode or an "fmr" mode (|voom-mode-fmr|).

The following characters in a Body headline immediately after the start fold
marker level number have special meaning. They are used by VOoM to indicate
node properties:
    "x"     - Node is marked. This is like a checked checkbox. "x" is also
              displayed in the second column of Tree buffer.
    "o"     - Node is opened (expanded). The corresponding Tree buffer fold
              will be opened when the outline is created by the command :Voom.
              Obviously, this applies only to nodes with children.
    "="     - Startup node. This node will be selected when the outline is
              created by the command :Voom.

Various VOoM mappings and commands read and write these special marks.

Each mark is optional, but the order must be xo= . Examples, assuming that
foldmarker is set to <<<,>>> : >
    headline <<<1xo=  --node is marked, opened, startup node
    headline <<<1xo   --node is marked, opened
    headline <<<1o    --node is opened
    headline <<<1x=   --node is marked, startup node

    headline <<<1=xo  --node is startup node, "x" and "o" are ignored
    headline <<<1 xo= --all marks are ignored

==============================================================================
~~~===--- Tree Headline Text ---===~~~   [[[3~

NOTE: This section applies only to the default markup mode (|voom-markup-modes|).

Tree headline text is constructed from the corresponding Body buffer headline.
The default procedure is to take the part before the matching fold marker and
to strip whitespace and other distracting characters. The exact procedure
depends on Body's 'filetype' and can be customized by the user. For most
filetypes, the following happens:
    - Part of the Body line before the first start fold marker with level
      number is taken.
    - Whitespace is stripped from the left side.
    - Spaces, tabs, and comment characters are stripped from the right side.
      Which chars are comment chars is determined by option 'commentstring',
      or by user option "g:voom_rstrip_chars_{filetype}", see below.
    - Leading and trailing filler chars -=~ are removed. These chars can be
      used as decorators to make headlines stand out.
    - Whitespace is stripped again on both ends.

In step 3, characters that are stripped from the right side of headline (from
before the fold marker) are determined as follows:
    - If variable "g:voom_rstrip_chars_{filetype}" exists, it's value is used.
      {filetype} here is Body's 'filetype'. Value is a string of characters to
      be stripped from the right side (Space and Tab must be included).
    - If "g:voom_rstrip_chars_{filetype}" does not exist, comment characters
      are obtained from option 'commentstring'. They, Spaces, and Tabs are
      stripped from the right side.

By default, "g:voom_rstrip_chars_{filetype}" are defined for filetypes "vim",
"text" and "help". For most source code filetypes 'commentstring' is set
correctly by the corresponding ftplugin. If not defined, 'commentstring'
defaults to /*%s*/, which makes no sense for filetypes like text and help.

So, to change what characters are stripped from the right side of Tree
headlines for particular Body filetypes, you can either set 'commentstring' or
you can define "g:voom_rstrip_chars_{filetype}" in vimrc (or in an add-on).
Example for "autohotkey" filetype, ';' is line comment char: >
        let g:voom_rstrip_chars_autohotkey = "; \t"

The above procedure can be replaced completely by a custom Python function
which returns Tree headline text. The function must be registered in Python
dictionary voom_vim.MAKE_HEAD: key is Body filetype, value is the function to
be used with this filetype. By default, this is done for "html" files (we can't
just strip <!-- characters from the right side). For other filetypes, this
should be done via an add-on. Sample add-on "custom_headlines.vim" shows how,
see comments there.

NOTE: Tree headlines are constructed by function makeOutline() or
makeOutlineH() in voom_vim.py. Markup modes use function hook_makeOutline().
You can also customize how Tree headline text is constructed by invoking an
"fmr" markup mode, see |voom-mode-fmr|. 

==============================================================================
Selected Node   [[[3~

At any moment, one node is designated as selected. It is marked by the "="
character in the Tree buffer. This is sort of like "current position" in a true
two-pane outliner.

In contrast, "current node" here means the node under the cursor. The current
node may or may not be selected.

A node is selected by pressing <Return> (Tree or Body, Normal mode), or by
selecting a new node in the Tree with arrow keys or mouse left button click.

It is possible to automatically select a node on startup. (This feature is
available only when using the default on an "fmr" markup mode.) A startup node
has character "=" in the Body headline after the level number and after
optional "x" and "o" marks (|voom-special-marks|). Tree mapping  <LocalLeader>=
inserts "=" in the current node's Body headline and removes "=" from all other
headlines. Next time, when the outline is created by the command :Voom, the
node marked with "=" will be automatically selected.

Related Tree mappings (Normal mode):
=           Put cursor on the currently selected node.
+           Put cursor on the startup node, that is the node marked with "=" in
            Body headline, if any. This will also warn if there are several
            such nodes. Mnemonic: + is Shift-=


Note: it would be nice to have current headline highlighted in the Tree buffer
(as Leo does). Sadly, Vim does not allow to apply syntax highlighting to
folded lines -- the Folded hi group overrides all other highlighting. The
current headline is easy to highlight, but it doesn't work for contracted
nodes: >
    :syn match Pmenu /^=.\{-}|\zs.*/

==============================================================================
Delete Outline   [[[2~
                                                 *voom-quit*
To delete (quit) a VOoM outline for a particular Body buffer:
unload, delete, or wipe out the corresponding Tree buffer (:bun, :bd, :bw).

You can also delete an outline by closing all corresponding Tree windows via
|CTRL-W_c|, |CTRL-W_o|, etc. This happens because Tree buffers have 'bufhidden'
set to "wipe". (If this is inconvenient, change 'bufhidden' to "hide". To do
this by default for all Tree buffers, configure filetype "voomtree": add
"setl bufhidden=hide" in file  ~/.vim/after/ftplugin/voomtree.vim or similar.)

NOTE: the outline is deleted automatically whenever the Tree buffer is unloaded.

When a VOoM outline is deleted:
    - The Tree buffer is wiped out, which obviously closes all Tree windows.
    - VOoM-specific mappings (|voom-shuttle-keys|) and autocommands are removed
      from the Body buffer. (Mappings may remain at first. They will silently
      unmap themselves the next time they are invoked.)

There are also the following convenience commands:

q                   Delete outline (Tree buffer Normal mode mapping).

:Voomquit           Delete outline if the current buffer is a Tree or Body buffer.

:VoomQuitAll        Delete all VOoM outlines. Can be executed from any buffer.

:VoomToggle [MarkupMode]
                    Create outline if the current buffer is a non-VOoM buffer.
                    (Same as the :Voom command except that cursor stays in the
                    current buffer.)
                    Delete outline if the current buffer is a Tree or Body buffer.

:Voomtoggle         Minimize/Restore Tree buffer window in the current tabpage.
                    (Tree or Body)

==============================================================================
Unloaded Body buffers   [[[3~

A buffer cannot be outlined if it is not loaded in memory. A Body buffer is
unloaded after commands :bun :bd :bw . It can also become unloaded after it is
no longer displayed in any window (this depends on Vim options 'hidden' and
'bufhidden').

If the Body buffer is not loaded, the outline is locked. The following actions
in the corresponding Tree buffer are blocked:
    - Automatic outline update on Tree BufEnter.
    - Selecting nodes.
    - All outline operations.
    - Commands :Voomgrep, :Voomunl, etc.

Everything should be back to normal once the Body buffer is loaded again.

If a Body buffer has been wiped out (:bw) it can not be loaded again. The
corresponding Tree buffer is useless and you should delete it.

One way to load an unloaded Body buffer is to execute the command :Voom in the
Tree buffer: it will create a new window, load Body there, and update the
outline. If the Body buffer no longer exists, the outline will be deleted.

==============================================================================
Custom commands for deleting outline   [[[3~

It would be convenient if the VOoM outline was automatically deleted and the
Tree buffer wiped out when the Body buffer is unloaded, deleted, or wiped out.
This is how VOoM worked prior to version 3.0. Such design turned out to be
unsafe and had to be abandoned.

The workaround is function voom#DeleteOutline([ex_command]). It can be used to
create custom commands and mappings that automatically delete the outline. This
function does the following:
    - If the current buffer is a Tree, it deletes outline (Tree is wiped out).
    - If the current buffer is a Body, it deletes outline, and then executes
      argument as an Ex command via |:execute|.
    - If the current buffer is not a VOoM buffer, it executes the argument as
      an Ex command.

The argument (a string) should be an Ex command you use most often to get rid
of buffers: "q", "bun", "bd", "bw", etc.

Example >
    nnoremap <silent> <M-w> :call voom#DeleteOutline('bw')<CR>
    com! BW call voom#DeleteOutline('bw')
Mapping ALT-w and command :BW are identical to the command :bw (wipe out the
current buffer), except that if the current buffer is a Body they also delete
the corresponding VOoM outline.

==============================================================================
Outline Navigation   [[[2o~

See |voom-map| for a list of all mappings. This section explains the basics.

------------------------------------------------------------------------------
If the mouse is enabled (GUI Vim, :set mouse=a), outline can be browsed with
the mouse alone thanks to the following Tree buffer local mappings:
<LeftRelease>
            Mouse left button click. Select the node under mouse.
            Toggle node's expanded/contracted state if the click is outside of
            headline text. (N)
<2-LeftMouse>
            Mouse left button double-click. Disabled.

------------------------------------------------------------------------------
The most essential keyboard mappings for outline navigation are:
    <Return>  -- Tree (Normal, Visual), Body (Normal)
    <Tab>     -- Tree (Normal, Visual), Body (Normal)
    <Space>   -- Tree (Normal)

<Return> and <Tab> shuttle the cursor between the corresponding Tree and Body
windows. They are the only keys mapped by the command :Voom in Body buffers.
Other keys can be used instead by defining custom "g:voom_return_key" and
"g:voom_tab_key", see |voom-shuttle-keys|.

<Return>    - In Body buffer: select the current node and show it in Tree window.
              If the current node is already selected, move the cursor to Tree window.
            - In Tree buffer: select the current node and show it in Body window.
              If Body 'foldmethod' is marker, Body folds are closed so that
              only the selected node is visible (zMzvzt).
              If the current node is already selected, move the cursor to Body window.

              If the current tabpage has no windows with the required Body or
              Tree buffer, a new window is created. Thus, hitting <Return>
              after ":tab split" will create a tabpage with a new outline view.

<Tab>       - In Body buffer: move the cursor to window with the corresponding
              Tree buffer.
            - In Tree buffer: move the cursor to window with the corresponding
              Body buffer.

The command :Voom also cycles between Tree and Body. This is like <Return> but
without selecting a new node. Commands "i" and "I" in the Tree buffer can also
be handy for jumping to the first or last line of the corresponding node in the
Body buffer.

All other mappings are for Tree buffers only.

<Space>     Toggle node's expanded/contracted state without selecting it. (N)
            If the current line is hidden in a fold (after zc or zC), it is
            made visible first.

Nodes in the Tree buffer window can be navigated with just <Return>, <Tab>,
<Space>, and standard Vim commands:
            cursor motion: j, k, H, M, L, ...
            |fold-commands|: zc, zo, zM, zR, zv, zj, zk, ...
            (note: zf, zF, zd, zD, zE are disabled in Trees)
Examples:
    - To select the first child of the current node when it's contracted:
      <Space>j<Return>
    - To recursively contract subtree of the current node: contract it with
      <Space> if it's expanded, hit VzC to close folds, hit <Space> again if
      it's become hidden.
    - To go to the parent of the current node: zckj , zcjk .
      
------------------------------------------------------------------------------
There are about 19 other mappings for easy Tree navigation, see |voom-map|.
Most of them use keys that otherwise would have been wasted because they change
text and thus have to be disabled in Tree buffers. For example, "c" and "P"
move the cursor to the parent of the current node.

Most Tree mappings are defined only for Normal mode and do not accept a count.
The exceptions are:
    - K, J, U, D in Visual mode extend Visual selection. To select all siblings
      of the current node: UVD . To expand all sibling: UVDzo .
    - K, J accept a count:  5J moves the cursor 5 siblings down.
    - O, C can operate on nodes in Visual region.

------------------------------------------------------------------------------
In addition to <Return>, the following Tree keys also select a node:
<Up> <Down> <Right> <Left> x X . All other keys just position the cursor.

Every time a node is selected, the cursor has to jump between the corresponing
Tree and Body windows in the current tabpage. Other tabpages are ignored. If
there is no window with the target buffer, a new window is created. If there
are multiple windows, previous window (^Wp) is re-used if possible.

==============================================================================
:Voomunl   [[[3~
                                                 *voom-Voomunl*
:Voomunl    This commands displays UNL (Uniform Node Locator) of node under
            the cursor. The UNL string is also copied into the "n register.

The current buffer must be a Tree or a Body. If the current buffer is a Body,
the outline data and the Tree will be updated if needed.

The term UNL is from Leo's unl.py plugin:
    http://leoeditor.com/plugins.html#unl-py
An UNL is like a path to the node. It lists headlines of all ancestor nodes.
Example: >
    Part 2 -> Chapter 4 -> Section 3 -> subsection 5

Related Tree mappings:
s           Show Tree headline text. (N)
S           Show UNL. Same as :Voomunl. (N)

==============================================================================
:Voomgrep   [[[3~
                                                 *voom-Voomgrep*
:Voomgrep {pattern}
            Search Body buffer for {pattern} and display results in the
            quickfix window (|quickfix|, |copen|) as a list of UNLs (Uniform
            Node Locators) of nodes with matches.

:Voomgrep
            As above, but use the word under the cursor for pattern (like when
            starting Vim search with * or #).

:Voomgrep *{pattern}
            Hierarchical search (tag inheritance): if a node contains {pattern},
            all its subnodes are automatically considered to match the pattern
            as well. In other words, the entire subtree of a matching node is a
            match.

:Voomgrep {pattern1} and {pattern2} and {pattern3} ...
            Boolean AND search. Search Body for each pattern and show nodes
            that match all patterns.

:Voomgrep not {pattern1} not {pattern2} not {pattern3} ...
            Boolean NOT search. Search Body for each pattern and show nodes
            that do not match any of the patterns.

:Voomgrep {pattern1} and *{pattern2} not {pattern3} not *{pattern4} ...
            Boolean AND/NOT, hierarchical searches can be combined in any order.

The current buffer must be a Tree or a Body. If the current buffer is a Body,
the outline data and the Tree are updated if needed. Searches are always
performed in Body buffer. If the current buffer is a Tree buffer, the cursor
moves to a window with the corresponding Body buffer.

For each pattern, function |search()| is called to search the entire Body
buffer, from top to bottom. According to docs, options 'ignorecase',
'smartcase' and 'magic' apply.

The :Voomgrep command terminates after >500000 matches are found while
searching for a pattern. This is to avoid getting stuck after trying something
like ":Voomgrep ." in a 10 MB file. One may also terminate search with CTRL-C .

The results are displayed in the quickfix window (|copen|) as a list of UNLs.
For example, after executing >
    :Voomg Spam and ham not bacon
in "test_outline.txt" the quickfix window will display: >

     test_outline.txt [D:\SCRIPTS\VOoM\VOoM_extras\test_outlines], b1
     :Voomgrep  Spam {34 matches}  AND ham {6 matches}  NOT bacon {5 matches}
    |149| N46:28|tests -> Voomgrep tests -> n46 lunch
    |156| N47:2 |tests -> Voomgrep tests -> n47 dinner

The numbers between || are:
    - Body line number of the first match in this node. <Return> or mouse
      double-click moves the cursor to this line in the Body buffer.
    - Node number, that is the corresponding Tree line number.
    - The total number of matches in this node for all AND patterns.

To do a hierarchical search, add "*" in front of a pattern.
Example: >
    :Voomgrep *Spam not *HAM
Each node in the results is such that
    a) It or some of its ancestor nodes contains "Spam".
    b) Neither it nor any of its ancestor nodes contains "HAM".
Nodes included by inheritance may not contain all AND matches. Such nodes have
"n" instead of "N" before the node's number in the quickfix window.
Hierarchical searhes are handy when working with markups that have tag
inheritance: http://orgmode.org/org.html#Tag-inheritance .


PATTERNS AND BOOLEAN OPERATORS:

    - There is no OR operator. Use \| instead, see |\bar|.

    - Patterns should not span several lines. Multi-line patterns are likely
      to produce meaningless results because they can span several nodes.

    - Operators AND and NOT that separate patterns are not case sensitive:
      they can be "and", "AND", "not", "NOT", "aND", etc.

    - Whitespace around each pattern and around AND and NOT is ignored.
      Use "\s", "\t", "[ ]", "\%x20" to specify leading or trailing
      whitespace.

    - Operators AND/NOT should not be concatenated. The command
        :Voomgrep ham and not bacon
      searches for "ham" AND "not bacon".

    - To include literal words "and" or "not" in a pattern: >
        :Voomgrep Spam and\ ham not\ bacon
        :Voomgrep Spam[ ]and ham[ ]not bacon
<
    - Patterns separated by AND and NOT are treated independently.
      Switches like \c, \v, \m, \zs, etc. affect only one pattern. For
      example, to do case-insensitive search for nodes with ham and spam: >
        :Voomgrep \cham and \cspam
<
If the search was successful, all AND patterns are copied into the search
register "/ and added to the search history so that search highlight and
commands n, N, etc. can be used. NOTE: This does not always work correctly with
multiple AND patterns because they have to be combined into one pattern:
    - A "\c" or "\C" switch in one AND pattern will be applied to all AND
      patterns. If both "\c" and "\C" are present, "\c" wins.
    - Possibly some other complex regexps might be problematic.
You can get the pattern used for search and highlight after :Voomgrep by
pressing /<Up> .

NOTE: The command :Voomgrep slightly modifies the default look of the quickfix
window for better readability -- buffer name is removed, syntax highlighting is
tweaked. These changes are lost when the quickfix list is reloaded (:colder,
:cnewer, etc.)


==============================================================================
Outline Operations   [[[2o~

Outline operations are always performed in a Tree buffer via buffer-local
mappings or commands.

When appropriate, operations are automatically applied to subtrees, that is to
top-level nodes and all their descendant nodes. E.g., moving a node moves the
node and all its descendants, the levels are adjusted for all descendants.

Most operations can be performed on a range of sibling nodes in Visual
selection. The range is checked for being a valid range: levels (indents) of
nodes in the range must not exceed the level of the topmost node in the range.

When nodes are moved after a folded subtree, they are inserted after the fold,
that is after the visible node. This behavior should be intuitive and similar
to the behavior of most outliner programs, as well as of Vim folds.

Most outline operations usually modify the corresponding Body buffer. Thus,
they are disabled if the Body is 'nomodifiable' or 'readonly'. The exceptions
are Copy and some other commands that never modify Body buffers.

An outline operation can be undone with one undo command in the corresponding
Body buffer.

==============================================================================
Edit Headline, Edit Last Line   [[[3~

i                   Edit headline, that is the first Body line of node under
                    the cursor. The cursor is moved into a window with the Body
                    buffer and placed on the first line of the corresponding
                    Body node. Usually, the cursor will be positioned at the
                    start of the headline text and on the first word character
                    (|\<|). Note that in some markups (reST, AsciiDoc) the
                    actual headline can be a few lines down.

I                   Edit the last Body line of node under the cursor.

These Normal mode commands do not modify the Body buffer. They only move the
cursor from the Tree to the corresponding Body line. They can also be used
instead of <Return> or <Tab> (|voom-shuttle-keys|) for browsing an outline.

==============================================================================
Add New Headline   [[[3~

aa  <LocalLeader>a
                    Add a new node after the current node. If the current node
                    is folded, the new node is added after the fold.
AA  <LocalLeader>A
                    Add a new node as the first child of the current node.

                    (Mnemonic: Add Another node.)

These Tree buffer Normal mode mappings add (insert) a new headline in the Body
buffer. The format of new headlines is determined by the current markup mode.
The text is always "NewHeadline". The cursor is moved into the Body window and
placed on "NewHeadline" which then can be edited ("caw", "caW").

It is often easier to create new headline(s) by editing the Body buffer
directly. I wrote a simple plugin that helps with inserting numbered fold
markers: http://www.vim.org/scripts/script.php?script_id=2891

==============================================================================
Select Body Region   [[[3~

R                   Move the cursor from Tree to Body buffer and select the
                    line range corresponding to node under the cursor (Normal
                    mode) or to all nodes in Visual selection (Visual mode).

This Tree buffer mapping is handy when you want to apply :substitute or some
other range-accepting Vim command to a single node or a group of nodes. The
command deals with individual nodes, not subtrees. Mnemonic: Range, Region.

==============================================================================
Move, Copy, Cut, Paste [[[3~

^^  <C-Up>  <LocalLeader>u
                    Move node(s) up. (N,V)

__  <C-Down>  <LocalLeader>d
                    Move node(s) down. (N,V)

<<  <C-Left>  <LocalLeader>l
                    Move node(s) left, that is promote. (N,V)
                    By default, this is allowed only if nodes are at the end of
                    their subtree, see |g:voom_always_allow_move_left|.

>>  <C-Right>  <LocalLeader>r
                    Move node(s) right, that is demote. (N,V)

yy                  Copy node(s) to the "+ register. (N,V)

dd                  Cut node(s) and copy contents to the "+ register. (N,V)

pp                  Paste node(s) from the "+ register after the current node
                    or fold. (N)
                    The clipboard is checked for being a valid VOoM outline:
                    the first line in the clipboard must be a headline
                    according to the current markup mode.

With the exception of Paste, these Tree buffer mappings are available in
Normal and Visual modes. In Visual mode the range is checked for being valid:
top nodes in the range must be siblings.

These commands always apply to subtrees, that is to top-level nodes and all
their descendant nodes, even when only a part of subtree is selected.

By default, commands Cut, Copy, Paste use the "+ register, that is the system
clipboard (|registers|, |quote+|). This means you can move nodes between
outlines in different instances of Vim, or copy/paste in other applications.
If the "+ register is not available because Vim was compiled without clipboard
support, the "o register is used instead.
You can choose another register, see |g:voom_clipboard_register|.

==============================================================================
Sort Outline   [[[3~
                                                 *voom-sort*
The command :VoomSort sorts sibling nodes according to their Tree headline text
(string after character | in Tree buffer). Nodes are siblings if they have the
same level and the same parent. This command must be executed in a Tree buffer.

:VoomSort           Sort siblings of the current node (node under the cursor).
                    Headlines are sorted by byte value, in ascending order.

:[range]VoomSort    Sort siblings in the range. Start and end range lines must
                    be different (|[range]|).
                    Note that if the range is actually one line, all siblings
                    of the node at that line are sorted. E.g.,
                        :57,57VoomSort
                        :57VoomSort
                    sorts siblings of node at Tree line 57.

:VoomSort [options]
:[range]VoomSort [options]
                    Sort according to options. Options are any combination of
                    the following words, separated by whitespace:
                             deep, i, u, r, flip, shuffle.
    OPTIONS:

    deep            Deep (recursive) sort. Sort top-level siblings and siblings
                    of their descendants. When the cursor is on the 2nd Tree
                    line (first headline) and no range is given, entire outline
                    is sorted.

    i               Ignore-case. Case-insensitive sort. Without the "u" option
                    this should affect only A-Za-z letters. To handle other
                    letters, include the "u" option.

    u               Unicode-aware sort. Convert headlines to Python Unicode
                    strings before sorting. This option is probably needed only
                    for case-insensitive sorts.

    r               Reverse-sort, sort in descending order.

    flip            Reverse the order of nodes without sorting anything.

    shuffle         Shuffle nodes randomly.


Example 1, perform deep sort, ignore-case, Unicode-aware: >
    :VoomSort deep i u

Example 2, sort siblings in Visual selection: >
    :'<,'>VoomSort
NOTE: make sure at least 2 lines are selected. Otherwise, the range contains
only one line, which means all siblings of the selected line will be sorted.


Sorting and reverse-sorting do not change the relative order of nodes with
equal headlines.

Options "r", "flip", "shuffle" cannot be combined.


It is easy to create custom commands that perform sorting with a particular set
of options. For example, if you often do case-insensitive, non-recursive sort
you can add the following line to .vimrc: >
    com! VoomSortI call voom#OopSort(line('.'), line('.'), 'i u')
The command :VoomSortI will be identical to ":VoomSort i u".
It does not accept a range. To make it work with a range: >
    com! -range VoomSortI call voom#OopSort(<line1>, <line2>, 'i u')

==============================================================================
Mark or Unmark Nodes   [[[3~

NOTE: These commands are only available when working with numbered start fold
markers, that is in the default markup mode or an "fmr" mode (|voom-mode-fmr|).

Marking a node is like checking a checkbox. A node is marked/unmarked by
adding/removing "x" in the Body headline after the start fold marker level
number (|voom-special-marks|). The "x" is also displayed in the Tree.

<LocalLeader>m      Normal mode: mark node under the cursor.
                    Visual mode: mark all nodes in the range.
                    "x" is inserted in Body headlines. (N,V)

<LocalLeader>M      Normal mode: unmark node under the cursor.
                    Visual mode: unmark all nodes in the range.
                    "x" is removed from Body headlines. (N,V)

The above commands apply to individual nodes only, not to their descendants.

To unmark all: ggVG<LocalLeader>M

Related Tree mappings, Normal mode:
x                   Go to next marked node and select it.
X                   Go to previous marked node and select it.

==============================================================================
Mark Node As Startup Node   [[[3~

NOTE: These commands are only available when working with numbered start fold
markers, that is in the default markup mode or an "fmr" mode (|voom-mode-fmr|).

<LocalLeader>=      Mark the current node as startup node. (N)

This command inserts character "=" in Body headline after the start fold marker
level number and after optional "x" and "o" marks (|voom-special-marks|). The
"=" mark is removed from all other Body headlines.  If current line is the
first Tree line (outline title), "=" are removed from all Body headlines.

The "=" mark affects only Voom startup: last node marked with "=" is selected
when the outline is created for the first time by the command :Voom.

Related Tree mappings, Normal mode:
+                   Put cursor on the startup node, if any. Warn if there are
                    several such nodes. Mnemonic: + is Shift-=

==============================================================================
Save or Restore Tree Folding   [[[3~
                                                 *voom-tree-folding*
NOTE: These commands are only available when working with numbered start fold
markers, that is in the default markup mode or an "fmr" mode (|voom-mode-fmr|).

Opened/closed folds in a Tree buffer are equivalent to expanded/contracted
nodes. VOoM allows to save and restore Tree buffer folding. To do this, it
relies on special marks in Body headlines: character "o" immediately after the
start fold marker level number or after optional "x" (|voom-special-marks|).
The "o" mark indicates that the fold is opened. Such folds are opened
automatically on startup. (This help file uses "o" marks.)

The following commands execute only in a Tree buffer. They read and write "o"
marks in Body headlines.

:[range]VoomFoldingSave
                    Save Tree folding by writing "o" marks in Body headlines.
                    If a range is supplied, this is done for individual nodes
                    in the range. Without a range, this is done for the current
                    node and all descendant nodes.

:[range]VoomFoldingRestore
                    Restore Tree folding according to "o" marks in Body
                    headlines. If a range is supplied, this is done for
                    individual nodes in the range. Without a range, this is
                    done for the current node and all descendant nodes.

:VoomFoldingCleanup
                    Cleanup "o" marks: remove them from nodes without
                    children. Such marks are redundant but harmless, they
                    don't do anything. This is done for the entire outline,
                    even if a range is supplied.

To save or restore folding for the entire outline: >
    :%VoomFoldingSave
    :%VoomFoldingRestore

There as also the following Tree buffer mappings, Normal mode:

<LocalLeader>fs     Save Tree folding for the current node and all descendant
                    nodes. Same as :VoomFoldingSave.

<LocalLeader>fr     Restore Tree folding for the current node and all descendant
                    nodes. Same as :VoomFoldingRestore.

<LocalLeader>fas    Save Tree folding for the entire outline.
                    Same as :%VoomFoldingSave.

<LocalLeader>far    Restore Tree folding for the entire outline.
                    Same as :%VoomFoldingRestore.

Mnemonics for mappings: Foldins Save/Restore, Folding All Save/Restore.

==============================================================================
MARKUP MODES   [[[2o~
                                                 *voom-markup-modes*
By default, the command :Voom creates the outline from lines with start fold
markers with levels: {{{1, {{{2, etc. If a buffer uses a different markup for
headlines, it is necessary to specify the markup mode. For example, command >
    :Voom MySuperDuperWiki
will try to create the outline using MySuperDuperWiki markup mode.

A markup mode is defined in a Python module named "voom_mode_{MarkupName}.py".
Such module is usually located in Vim folder autoload/voom, but it can also be
placed anywhere in the Python search path. The above command will try to import
module "voom_mode_MySuperDuperWiki.py", which should modify VOoM's core code
when handling this particular outline to accommodate the idiosyncrasies of the
MySuperDuperWiki markup language.

One may use argument completion to list all markup modes present in folder
../autoload/voom : type ":Voom " and press <Tab> or <C-d>.

The name of the current markup mode, if any, is noted on the first line of the
Tree buffer. Execute the command ":Voominfo [all]" to see more details.

It is easy to create an alias command or a mapping identical to the above
command (:Voom MySuperDuperWiki)  >
    :com! Voow call voom#Init("MySuperDuperWiki")
or, if you prefer :VoomToggle behavior >
    :com! Voow call voom#Init("MySuperDuperWiki",1)
Users can also customize which markup mode the command :Voom uses when it is
invoked without an argument, see |g:voom_ft_modes| and |g:voom_default_mode|.

A fully functional markup mode will support all major VOoM commands and outline
operations. Not supported are operations that rely on special node marks,
|voom-special-marks|, unless the mode is an "fmr" mode (|voom-mode-fmr|):
    - mark/unmark nodes
    - startup node
    - save/restore Tree folding.

To customize or create a new markup mode: modify one of the existing
voom_mode_{MarkupName}.py files, save it as voom_mode_{YourName}.py, place it
in Vim folder autoload/voom or anywhere in the Python search path.

The following sections describe markup modes available by default. These modes
are fully functional unless stated otherwise.

==============================================================================
'fmr' modes   [[[3~
                                                 *voom-mode-fmr*
"fmr" modes are very similar to the default mode, that is the :Voom command
without an argument. They deal with start fold markers with level numbers and
support special node marks (|voom-special-marks|).
"fmr" modes can be used to customize how Tree headline text is constructed and
to change the format of new headlines (Insert New Node).

:Voom fmr
MODULE: ../autoload/voom/voom_mode_fmr.py
This mode changes absolutely nothing, it is identical to the default mode.
The purpose of this mode is to make possible the original default mode when
|g:voom_ft_modes| or |g:voom_default_mode| have been defined, e.g., for an
AsciiDoc file with fold markers.

:Voom fmr1
MODULE: ../autoload/voom/voom_mode_fmr1.py
Headline text is before the fold marker. This mode is identical to the default
mode except that no chars other than leading and trailing whitespace are
stripped from headlines. >
    headline level 1 {{{1
    headline level 2 {{{2

:Voom fmr2
MODULE: ../autoload/voom/voom_mode_fmr2.py
Headline text is after the fold marker: >
    {{{1 headline level 1
    {{{2 headline level 2
as seen in some Vim plugins: >
    "{{{1 my functions
    "{{{2 s:DoSomething
    func! s:DoSomething()
NOTE: If {{{'s are in the first column and |matchparen| is enabled, outline
navigation is slow. A workaround: >
    :set mps-={:}

==============================================================================
wiki   [[[3~
                                                 *voom-mode-wiki*
:Voom wiki
MODULE: ../autoload/voom/voom_mode_wiki.py
MediaWiki headline markup. This is the most common Wiki format. Should be
suitable for Wikipedia, vim.wikia.com, etc. >

    = headline level 1 =
    some text
    == headline level 2 == 
    more text
    === headline level 3 === <!--comment-->
    ==== headline level 4 ====<!--comment-->
    etc.

First = must be at the start of the line.
Closing = are required.
Trailing whitespace is ok.
Whitespace around the text is not required.

HTML comment tags are ok if they are after the headline: >
    ==== headline level 4 ====   
    ===== headline level 5 =====  


KNOWN PROBLEMS
--------------

1) Headlines are not ignored inside <pre>, <nowiki> and other special blocks.

2) Only trailing HTML comment tags are stripped.
The following valid headline is not recognized: >
    === missed me ===

A comment inside headline is ok, but it will be displayed in Tree buffer: >
    ==  headline level 2 ==


REFERENCES
----------
http://www.mediawiki.org/wiki/Help:Formatting
http://www.mediawiki.org/wiki/Markup_spec
http://meta.wikimedia.org/wiki/Help:Section
http://en.wikipedia.org/wiki/Help:Section
http://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style#Section_headings

==============================================================================
vimwiki   [[[3~
                                                 *voom-mode-vimwiki*
:Voom vimwiki
MODULE: ../autoload/voom/voom_mode_vimwiki.py
Headline markup used by Vimwiki plugin:
    http://www.vim.org/scripts/script.php?script_id=2226
Example: >

    = headline level 1 =
    body text
    == headline level 2 ==
    body text
           ===headline level 3===

Closing = are required.
There can be leading whitespace (centered headline).
Trailing whitespace is ok.
Whitespace around the text is not required.

KNOWN PROBLEMS
--------------
There is a conflict between mappings: VOoM and Vimwiki both create buffer-local
mappings for keys <Return> and <Tab>. When the command ":Voom vimwiki" creates
the outline, it overwrites Vimwiki's mappings for <Return> and <Tab>, and they
are not restored when the outline is deleted. You can restore original
Vimwiki's mappings with ":set ft=vimwiki". You can configure VOoM to use some
other keys, see |voom-shuttle-keys|. You can also change Vimwiki mappings, see
|vimwiki_<CR>| and |vimwiki_<Tab>| in Vimwiki's help.

==============================================================================
dokuwiki   [[[3~
                                                 *voom-mode-dokuwiki*
:Voom dokuwiki
MODULE: ../autoload/voom/voom_mode_dokuwiki.py
Mode for outlining of DokuWiki headlines:
    https://www.dokuwiki.org/
    https://www.dokuwiki.org/wiki:syntax#sectioning

Headlines typically look like this (the first = is at the start of the line): >
    ====== Headline Level 1 ======
    ===== Headline Level 2 =====
    ==== Headline Level 3 ====
    === Headline Level 4 ===
    == Headline Level 5 ==

The following applies and matches DokuWiki behavior:
    - Only 5 headline levels are possible because the format is ass-backward.
      When an outline operation wants to creates a headline with level >5, the
      level is set to 5 and a warning is echoed.
    - Trailing ='s are not important as long as there are at least 2 of them.
      Outline operations will not change trailing ='s if there are more than 6
      of them.
    - More than 6 leading ='s is allowed and means level 1.
    - One leading space is allowed at start of line before the first =, but not
      a tab or 2 or more spaces.
    - The leading space can be followed by a tab, optionally followed by any
      number of spaces/tabs.

NOTE: No attempt is made to exclude regions in which headlines should be
ignored: <code>, <nowiki>, <file>, %%, etc.

Similar mode: inverseAtx, see |voom-mode-various|.

==============================================================================
viki   [[[3~
                                                 *voom-mode-viki*
:Voom viki
MODULE: ../autoload/voom/voom_mode_viki.py
Mode for outlining Viki/Deplate headings:
    http://www.vim.org/scripts/script.php?script_id=861
    http://deplate.sourceforge.net/Markup.html#hd0010004
>
    * headline level 1
    some text
    ** headline level 2
    more text
    *** headline level 3
    **** headline level 4

The first * must be at the start of the line.
There must be a whitespace after the last * .

Headlines are ignored inside special regions other than #Region:
    http://deplate.sourceforge.net/Regions.html
    http://deplate.sourceforge.net/Regions.html#hd00110013
Special regions have the following format: >
    #Type [OPTIONS] <<EndOfRegion
    .......
    EndOfRegion

Except for ignoring special regions, this mode is identical to the org mode.

==============================================================================
org   [[[3~
                                                 *voom-mode-org*
:Voom org
MODULE: ../autoload/voom/voom_mode_org.py
Mode for outlining Emacs Org-mode headlines:
    http://orgmode.org/org.html#Headlines
>
    * headline level 1
    some text
    ** headline level 2
    more text
    *** headline level 3
    **** headline level 4

The first * must be at the start of the line.
There must be a whitespace after the last * .

==============================================================================
rest   [[[3~
                                                 *voom-mode-rest*
:Voom rest
MODULE: ../autoload/voom/voom_mode_rest.py
Mode for outlining reStructuredText (reST) section titles.
    http://docutils.sourceforge.net/rst.html
    http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections
    http://docutils.sourceforge.net/docs/user/rst/quickstart.html#sections
    http://docs.python.org/devguide/documenting.html#restructuredtext-primer

For examples of reST files, click "Show Source" or similar link on the above
pages. Vim has reST syntax highlighting, do ":set ft=rst" to enable.

VOoM's reST mode conforms to the following reST specifications for headlines:
    - An underline/overline character may be any non-alphanumeric printable
      7-bit ASCII character.
    - The underline must begin in column 1 and must extend at least to the
      right edge of the title text.
    - The overline must be identical to the underline.
    - The title text may be inset only if there is an overline.
    - Trailing whitespace is always ignored.
    - The levels are assigned to adornment styles in the order they are
      encountered.

There are 64 different headline adornment styles: 32 underline-and-overline
styles, 32 underline-only styles. To customize the default order in which new
adornment styles are deployed during outline operations, you can modify the
constant AD_STYLES near the top of the module. It is a string containing
adornment styles in the order of preference.

When pasting an outline, adornment styles in the pasted text are changed to
match the styles in the destination text.

To reduce ambiguity, VOoM imposes a couple of its own restrictions on
headlines. These are not necessarily a part of reST specifications.
1) A headline must be preceded by a blank line or another headline: >

    ================
    Headline level 1
    ================
    Headline level 2
    ================
    Lorem ipsum dolor sit amet...
    ~~~~~~~~~~~~
    not headline
    ~~~~~~~~~~~~
    not headline
    ````````````

    headline level 3
    ````````````````

2) A section title cannot look like an underline/overline. Such headlines are
difficult to interpret and they cause errors during outline operations.
There are no headlines in the following example: >

    =====
    -----
    =====

    +++++
    =====

It is still possible to write such headlines by making the underline/overline
longer than the title: >

    =======
    -----
    =======

    +++++
    =======

KNOWN PROBLEMS
--------------

1) Any reST directives before a headline are part of the previous node. Thus,
it is generally not safe to move nodes in the Tree pane. For example, a section
is often preceded by a label: >

    .. _my-reference-label:

    Section to cross-reference
    --------------------------

Such node should not be moved: the label is part of the previous node and will
become separated from its headline. (Let me know if this needs to be fixed.)

2) The VoomSort operation can result in an error if the last section
(end-of-file) is not terminated with a blank line. The headline that ends up
sorted after the last node will not be preceded by a blank line and will not be
detected.
Note that there is no such problem with other outline operations--they insert
missing blank lines before headlines to prevent headline loss.

3) Outline verification can fail after an outline operation if there are
inconsistent levels, that is when node's level is incremented by >1. VOoM will
complain about different Tree lines, different levels, and force outline
update.

Example 1. Errors when moving node D up. >

    A level 1
    ===========

    B level 2
    -----------

    C level 3
    """""""""""

    D level 1
    ===========

    E level 3
    """""""""""

Example 2. Errors when moving node C left. This is because node E is also moved
left, even though it is in a different branch. >

    A level 1
    =========

    B level 2
    ---------

    C level 3
    +++++++++

    D level 1
    =========

    E level 4
    *********

==============================================================================
markdown   [[[3~
                                                 *voom-mode-markdown*
:Voom markdown
MODULE: ../autoload/voom/voom_mode_markdown.py
Mode for outlining of standard Markdown headers.
    http://daringfireball.net/projects/markdown/
    http://daringfireball.net/projects/markdown/syntax#header
    http://daringfireball.net/projects/markdown/dingus  --online demo
    http://babelmark.bobtfish.net/  --derivatives
    Vim folding and other set up for Markdown files:
        https://gist.github.com/1035030  --my version
        https://github.com/plasticboy/vim-markdown
        https://github.com/nelstrom/vim-markdown-folding
        https://github.com/tpope/vim-markdown

Related modes: |voom-mode-pandoc|, |voom-mode-hashes|.
Note: Use |voom-mode-pandoc| for Pandoc Markdown. The Pandoc mode may also be
better suited for MultiMarkdown and GitHub Flavored Markdown (GFM) because they
can have fenced code blocks:
    http://johnmacfarlane.net/pandoc/ --Pandoc
    http://fletcherpenney.net/multimarkdown/ --MultiMarkdown
    https://help.github.com/articles/github-flavored-markdown --GFM

There are two types of header styles. Both can be used in the same outline.

Underline-style, levels 1 and 2 only: >
    header level 1
    ==============

    header level 2
    --------------

Hashes-style, any level is possible: >
    # header level 1
    ## header level 2
    ### header level 3 ###

Headlines are interpreted as follows:
    - A blank line before or after a headline is optional. NOTE: Pandoc version
      of Markdown does require blank lines before headlines, unlike traditional
      Markdown. Use |voom-mode-pandoc| for Pandoc Markdown.
    - One = or - in column 1 is sufficient for underline-style.
    - Spaces after opening #'s and before closing #'s are optional.
    - Closing #'s are optional. Their number is not important.
    - The underline-style overrides hashes-style. The leading #'s are then part
      of the headline text. This matches standard Markdown behavior: >
            #### this is headline level 2, not level 4
            ------------------------------------------
<
    - A line consisting only of hashes is interpreted as a blank headline. For
      example, line "###" is blank headline at level 3. In contrast, Markdown
      interprets it as header "#" at level 2, that is 
#
.

HOW OUTLINE OPERATIONS CHOOSE THE FORMAT OF HEADLINES
-----------------------------------------------------
When an outline operation changes headline level, it has to choose between
several possible headline formats:
    - When changing to level 1 or 2, choose underline-style or hashes-style.
    - When using hashes-style, choose to add or not to add closing hashes.
Outline operations try to keep the format of headlines consistent throughout
the current outline. The above ambiguities are resolved as follows:

    A) If possible, the headline's current style is preserved.
    Demoting headline
                 Headline
                 ========
    changes it to
                 Headline
                 --------
    Demoting "# Headline" changes it to "## Headline".
    Demoting "#Headline#" changes it to "##Headline##". And so on.

    B) When a choice must be made between underline-style and hashes-style
    (changing level from >2 to 1 or 2), the style of the first level 1 or 2
    headline in the document is used. The default (in case there are no
    headlines with level 1 or 2) is to use underline-style.

    C) When a choice must be made to add or not to add closing hashes (changing
    from underline-style to hashes-style), the style of the first hashes-style
    headline in the document is used. If it ends with "#", then closing hashes
    are added. The default (in case there are no headlines in hashes-style) is
    to add closing hashes.

    The headline format is always chosen as in B) and C) above when:
        - Inserting new headline.
        - Pasting nodes (because we may paste from another outline with a
          different style).
          As a side-effect, cutting and pasting all nodes (2GVG dd pp) converts
          all headlines into default format: underlined and with trailing #'s.

OTHER NOTES
------------
    - If a headline is not preceded by a blank line, outline operations may add
      one when headlines are moved or inserted.
    - Trailing #'s in headlines should not be considered significant: they can
      be added and removed during outline operations.

==============================================================================
pandoc   [[[3~
                                                 *voom-mode-pandoc*
:Voom pandoc
MODULE: ../autoload/voom/voom_mode_pandoc.py
Mode for outlining of Pandoc Markdown headers.
    http://johnmacfarlane.net/pandoc/
    https://github.com/jgm/pandoc
    https://github.com/vim-pandoc/vim-pandoc --Vim configuration

This mode is identical to the Markdown mode (|voom-mode-markdown|) except that
it adds several Pandoc-specific restrictions on headers:
    - A blank line is usually required before a header.
        http://johnmacfarlane.net/pandoc/README.html#headers
    - Headers are ignored inside fenced code blocks.
        http://johnmacfarlane.net/pandoc/README.html#fenced-code-blocks
    - Headers that start with "#. " are ignored, they are fancy_lists.
        http://johnmacfarlane.net/pandoc/README.html#ordered-lists

A Pandoc fenced code block starts on a line that begins with a row of 3 or more
"`" or "~". It ends on a line that is a row of "`" or "~" which is at least as
long as the starting row. (This should also be good enough for MultiMarkdown
and GitHub Flavored Markdown which denote fenced code blocks with ``` .)
Examples of fenced code blocks: >

    ~~~
    no headlines here
    ~~~

    ~~~~~~~~ python
    no headlines here
    ~~~~~~~~~~~~~~~

    ``` Any text can be here.
    no headlines here
    ```

A header or start-of-fenced-code-block must be preceded by one of the
following:
    - a blank line
    - another header
    - an end-of-fenced-code-block
This matches Pandoc's behavior: >

    # Header 1
    ## Header 2
    Header 3
    --------
    ```
    code block
    `````````
    ~~~~
    another code block
    ~~~~
    Header 4
    ========

There are no headers or fenced code blocks in the following example: >

    Lorem ipsum dolor sit amet...
    ## not a header
    not a header
    ------------

    Lorem ipsum dolor sit amet...
    ```
    not a fenced code block
    ```

Closing hashes are not adjusted during outline operations if they are followed
by a header identifier: >
    ## My header ##    {#foo}

==============================================================================
hashes   [[[3~
                                                 *voom-mode-hashes*
:Voom hashes
MODULE: ../autoload/voom/voom_mode_hashes.py
Headlines are marked by #'s. This is a subset of Markdown format (Atx-style
headers): >

    # headline level 1
    ##  headline level 2
    text
    ###headline level 3
    ### headline level 3

#'s must be at the start of the line.
A whitespace after #'s is optional.

This mode is much simpler and more efficient than the full Markdown mode
(|voom-mode-markdown|) because it does not have to deal with underlined
headlines and closing #'s.

NOTE: This mode can be easily modified to work with other Atx-style headlines:
    - To use any ASCII character as a marker instead of '#'.
    - To require a whitespace after the marker chars (as in org-mode).
    - To strip optional closing #'s.
See comments in the module file.

==============================================================================
txt2tags   [[[3~
                                                 *voom-mode-txt2tags*
:Voom txt2tags
MODULE: ../autoload/voom/voom_mode_txt2tags.py
Mode for outlining txt2tags titles.
    http://txt2tags.org/
    http://txt2tags.org/userguide/TitleNumberedTitle.html#6_2

Both Titles and Numbered Titles are recognized. Anchors are OK. >
    = title level 1 =
    == title level 2 ==[anchor-A]
    +++ numbered title level 3 +++
    +++ numbered title level 3 +++[anchor-B]

There can be leading spaces, but not tabs.
The number of = or + chars must be the same on both sides.

Titles are ignored inside Verbatim, Raw, Tagged, Comment Areas, that is between
pairs of lines of ```, """, ''', %%%.

Numbered Titles are indicated in the Tree buffer by "+" in the 2nd column to
help distinguish them from non-numbered titles.

The type of the Title (numbered or not) is preserved during outline operations.

==============================================================================
asciidoc   [[[3~
                                                 *voom-mode-asciidoc*
:Voom asciidoc
MODULE: ../autoload/voom/voom_mode_asciidoc.py
Mode for outlining of AsciiDoc Document and Section Titles.
    http://asciidoc.org/userguide.html#X17
    http://asciidoc.org/
    https://github.com/asciidoc/asciidoc
The AsciiDoc Userguide source is an example of a large and complex document:
    http://asciidoc.org/userguide.txt

Both two-line and one-line title styles are recognized and can be used in the
same outline. Document Titles, that is topmost nodes, are not treated
specially. Note that the topmost level in VOoM is level 1, not level 0 as in
AsciiDoc documentation.


Two-line style, levels 1 to 5 only: >
    Level 1
    =======

    Level 2
    -------

    Level 3
    ~~~~~~~

    Level 4
    ^^^^^^^

    Level 5
    +++++++

The underline must be of the same size as the title line +/- 2 chars.
Both the underline and the title line must be at least 2 chars long.
Trailing whitespace is always ignored and is not counted.


One-line style: >
    = Level 1 =

    == Level 2 ==

    === Level 3 ===

Closing ='s are optional: >
    = Level 1

    == Level 2

    === Level 3

There must be a whitespace between headline text and ='s. The number of closing
='s must match the number of opening ='s.
   
One-line style overrides two-line style: >
    ===== Level 5
    -------------
    listing
    -------------

When a style must be chosen during an outline operation (when changing level,
pasting, inserting new node), the style is chosen so that to preserve the
current style of the document. When that's not possible, the default is to use
two-line and to add closing ='s. See |voom-mode-markdown| for details.

In addition to Titles, the VOoM asciidoc mode is also aware of:
    - Standard Delimited Blocks. Titles are ignored inside of them.
    - Lines with [[ BlockID ]] and [ AttributeList ] preceding the title line.
See below for details.

Because AsciiDoc is a complex format, there are various edge cases and gotchas,
see below. See also file voom_samples/asciidoc.asciidoc for examples.

------------------------------------------------------------------------------
Delimited Blocks   [[[4~

Headlines are ignored inside Delimited Blocks:
    http://asciidoc.org/userguide.html#X104
A delimited block is started and ended by a line consisting of 4 or more of the
following characters: >
    ////
    ++++
    ----
    ....
    ****
    ____
    ====

Example: >
    == headline ==
    ------------------------------------
    
    == listing, not headline ==

    ------------------------------------
    == headline ==
   
Confusing cases when the start of a Delimited Block looks like an underline: >
    == headline ==
    --------------
    == listing, not headline ==
    ---------------------------

    headline
    --------
    --------
    listing, not headline
    ---------------------

------------------------------------------------------------------------------
BlockID, AttributeList   [[[4~

Section titles in AsciiDoc are often preceded by lines with attributes. Thus,
in general, it is dangerous to move nodes around--sections can become separated
from their attributes. VOoM accommodates the most common usage pattern, at
least as seen in the "userguide.txt".

A headline may be preceded by any number of [...] lines, that is lines that
start with "[" and end with "]". This allows for any number of BlockID and
AttributeList elements and in any order. Examples: >

    [[appendix_B]] 
    == Appendix B ==

    [appendix]
    == Appendix B ==

    [[appendix_B]] 
    [appendix]
    == Appendix B ==

    [appendix]
    [[appendix_B]] 
    == Appendix B ==

In such cases, the first line of the node is the topmost [[...]] or [...] line,
not the title line. This means that it is usually safe to move such nodes --
lines with the BlockId and AttributeList will stay with the section title.

NOTE: There must be no comment lines or blank lines in between.

NOTE: No attempt is made to detect any other directives, macros, etc. before
the headline. Stuff like Attribute Entries, that is lines >
    :numbered:
    :numbered!:
and other thingies as well as comments in front of the headline are part of the
preceding node.

------------------------------------------------------------------------------
Blank Lines   [[[4~

A blank separator line is usually required before a headline. The VOoM behavior
is mostly in conformance with AsciiDoc specification for Section Titles, but it
is not perfect and false negatives can occur, see Gotchas below.

NOTE: There should be no blank lines or comment lines between preceding [[...]]
and [...] lines and the title line. That is, unless you do not want them to be
treated as part of the headline.

Wrong: >
    == headline ==
    text
    == not headline ==

Correct: >
    == headline ==
    text

    == headline ==

In the following example the second underline starts Delimited Block: >
    headline
    --------
    text
    not headline
    ------------

    not headline
    ------------

Comment lines are OK, the check for a preceding blank line ignores them: >
    == headline 1 ==
    text
    // comment
    == not headline ==

    // comment
    == headline 2 ==
    text

    // comment
    // comment
    == headline 3 ==


A BLANK LINE IS NOT REQUIRED in the following cases (this matches AsciiDoc
behavior):

1) Between adjacent headlines: >
    == headline 1 ==
    == headline 2 ==
    // comment
    == headline 3 ==
    headline 4
    ----------
    [blah]
    headline 5
    ----------

2) If the title line is preceded by [[...]] or [...] lines: >
    == headline 1 ==
    text
    [[X1]]
    [blah]
    == headline 2 ==

3) After the end of a Delimited Block: >
    == headline 1 ==
    ----------------------------
    listing
    ----------------------------
    == headline 2 ==

Outline operations other than Sort will insert blank lines before headlines if
needed. They are thus not sensitive to missing blank separator lines.

Sort does not check for blank lines before headlines and does not insert them.
There will be an error message after :VoomSort if some headlines disappear due
to a missing blank line at the end of some nodes.

------------------------------------------------------------------------------
Disallowed Headlines (2-line style)   [[[4~

Some lines are never treated by VOoM as headlines when underlined because they
resemble certain AsciiDoc elements commonly found in front of Delimited Blocks.
The following are not headlines, the underline starts Delimited Block instead:
("AAA" can be any text or no text at all)
BlockID >
    [[AAA]]
    -------
Attribute List >
    [AAA]
    -----
Comment line (exactly two // at start) >
    //AAA
    -----
Block Title >
    .AAA
    ----

Tab at start of the title line is also not allowed. Leading spaces are OK.

An underlined headline cannot be just one character. These are not recognized
as headlines (they can be in AsciiDoc): >
    A
    --

    B
    ---

An underlined title cannot look like an underline or a Delimited Block line,
that is a line of only =,-,+, etc. There are no headlines here: >
    =====
    -----
    =====

    +++
    +++++
    ^^^^^^^^^^
    ++++++++++

------------------------------------------------------------------------------
Gotchas   [[[4~

1) Do not insert blank lines or comment lines between [[...]] or [...] and the
following headline.

2) There must be a blank line between a Macro or an Attribute Entry and the
following headline. The underline in the example below is mistaken for a
Delimited Block, which kills subsequent headlines. >
    == headline

    :numbered:
    == not headline

    ifdef::something[]
    not headline
    ------------

    == not headline

3) As already mentioned, any comment lines, Macros, Attribute Entries, etc.
before a headline belong to the previous node and can become separated from the
section title when nodes are moved.

------------------------------------------------------------------------------
Customizing   [[[4~

1) AsciiDoc documents that use non-default characters for title underlines or
for delimited blocks may not be outlined correcty. The workaround is to edit
dictionaries ADS_LEVELS and BLOCK_CHARS at the top of the module
../autoload/voom/voom_mode_asciidoc.py .


2) If you do not want VOoM to check for blank lines before AsciiDoc headlines
and to insert them when cutting/pasting/moving nodes, add the following to
your .vimrc: >
    let g:voom_asciidoc_do_blanks = 0

NOTE: This is not recommended because after an outline operation, a section
title can cease to be a title due to a missing blank line. Example document: >
    Title
    =====
    BBBB
    ----
    AAAA
    ----
    some text, end of file, no blank lines after it
When BBBB is moved after AAAA (via Move Down/Up, or Cut/Paste, or :VoomSort)
it is no longer a section title in accordance with AsciiDoc specifications, but
VOoM will not know that (false-positive node) and will not issue any warnings.

==============================================================================
latex   [[[3~
                                                 *voom-mode-latex*
:Voom latex
MODULE: ../autoload/voom/voom_mode_latex.py
Mode for outlining of LaTeX sections and some other markups.
    http://en.wikipedia.org/wiki/LaTeX
    http://en.wikibooks.org/wiki/LaTeX/Document_Structure#Sectioning_Commands

In this mode, VOoM scans for lines containing standard LaTeX commands listed
below. It is possible to customize these lists, see Customizing .
LaTeX commands begin with "\" and may be indented with whitespace. There may be
a whitespace between the command and "{".

Sectioning commands, in order of increasing depth
------------------------------------------------- >
    \part{A Heading}
    \chapter{A Heading}
    \section{A Heading}
    \subsection{A Heading}
    \subsubsection{A Heading}
    \paragraph{A Heading}
    \subparagraph{A Heading}

Documents can use any subset of section types. Level 1 is assigned to the
section that is the highest in the hierarchy. Levels for other section types
are incremented sequentially.

The first "{" can be followed by any text, which allows multi-line titles: >
    \section{Long long
        long long title}

There can be an asterisk before "{". It will appear in the Tree's marks column: >
    \section*{An Unnumbered Section Title}

Optional alternative titles are OK, as long as they do not contain an "{": >
    \section[alternative title]{A Heading}


Fixed level 1 elements
---------------------- >
    \begin{document}
    \begin{abstract}
    \begin{thebibliography}
    \bibliography{...}
    \end{document}

"-" is placed in the Tree's marks column for such nodes.


Verbatim commands, headlines are ignored in between
--------------------------------------------------- >
    \begin{verbatim}
    ...
    \end{verbatim}

    \begin{comment}
    ...
    \end{comment}

------------------------------------------------------------------------------
Gotchas   [[[4~

Obviously, sections should not be moved unless they are self-contained. It's up
to the user to ensure that no TeX commands get broken when a section is moved.

Level changes are disallowed for some nodes:
    - Fixed level elements are always at level 1. They cannot be demoted or
      pasted at another level.
    - There is a maximum possible level that cannot be exceeded.
Any disallowed levels created during an outline operation are corrected
automatically and a warning is printed.

When pasting an outline, especially into another outline, section types can
change to match the structure of the target outline. As an extreme example,
pasting into an empty outline changes all sections to defaults. For example,
when the following LaTeX outline >
    \section{Material and Methods}
    \paragraph{Assorted Lengths of Wire}
is copied or cut and then pasted into an empty LaTeX outline, it becomes >
    \part{Material and Methods}
    \chapter{Assorted Lengths of Wire}
A workaround is to define custom SECTIONS as ["section","paragraph",...].

In general, the relationship between levels and section types is not always
unambiguous and depends on what section types are currently in use.

In some cases, outline operations can trigger verification errors.
Example: when \section is deleted, \subsection unexpectedly becomes level 1 >
    \section{Section Heading}
    \begin{thebibliography}
    \subsection{Subsection Heading}

VOoM does not detect LaTeX commands if they are preceded by text: >
    Lorem ipsum. Lorem ipsum. \section{Section Heading}
VOoM does not detect "begin{}...end{}" form of sectioning commands: >
    \begin{section}{Section Heading}
    \end{section}
Fortunately, nobody writes like that.

------------------------------------------------------------------------------
Customizing   [[[4~

The VOoM LaTeX mode can be customized by modifying Python variables
    SECTIONS, ELEMENTS, VERBATIMS
either directly in voom_mode_latex.py or by defining Vim variables in .vimrc:
    g:voom_latex_sections
    g:voom_latex_elements
    g:voom_latex_verbatims

SECTONS and VERBATIMS are lists of strings.
ELEMENTS is a string that is used as Python regular expression.
ELEMENTS and VERBATIMS can be empty.

The following examples are equivalent to defaults: >

    let g:voom_latex_sections = ['part', 'chapter', 'section', 'subsection', 'subsubsection', 'paragraph', 'subparagraph']

    let g:voom_latex_elements = '^\s*\\(begin\s*\{(document|abstract|thebibliography)\}|end\s*\{document\}|bibliography\s*\{)'

    let g:voom_latex_verbatims = ['verbatim', 'comment']

Examples of large documents that produce many false headlines and a fix:
http://mirrors.ctan.org/macros/latex/contrib/memoir/doc-src/memman.tex
Fix: >
    let g:voom_latex_verbatims = ['verbatim', 'comment', 'lcode', 'egsource', 'egresult']
http://mirrors.ctan.org/macros/latex/contrib/biblatex/doc/biblatex.tex
Fix: >
    let g:voom_latex_verbatims = ['verbatim', 'comment', 'ltxexample', 'lstlisting']

==============================================================================
html   [[[3~
                                                 *voom-mode-html*
:Voom html
MODULE: ../autoload/voom/voom_mode_html.py
HTML heading tags. Single line only. >

    <h1>headline level 1</h1>
    some text
     <h2> headline level 2 </h2>
    more text
     <H3  ALIGN="CENTER"> headline level 3 </H3>
     <  h4 >    headline level 4       </H4    >
      some text <h4> <font color=red> headline 5 </font> </H4> </td></div>
         etc.

Both tags must be on the same line.
Closing tag must start with </h or </H  --no whitespace after < or /
All HTML tags are deleted from Tree headlines.

WARNING: When outlining a real web page, moving nodes around will very likely
screw up HTML.

==============================================================================
thevimoutliner   [[[3~
                                                 *voom-mode-thevimoutliner*
:Voom thevimoutliner
MODULE: ../autoload/voom/voom_mode_thevimoutliner.py
The Vim Outliner (TVO) format:
    http://www.vim.org/scripts/script.php?script_id=517

Headlines and body lines are indented with Tabs. Number of Tabs indicates
level. 0 Tabs means level 1.

Headlines are lines with >=0 Tabs followed by any character except '|'.

Blank lines are not headlines.

KNOWN PROBLEMS
--------------

If TVO is installed, navigating .otl file with arrows in Tree pane is sluggish,
even with relatively small outlines like README.otl . The culprit seems to be a
time-consuming BufEnter autocommand. Function OtlEnterBuffer() is called on
BufEnter. It sets up among other things window-local folding options, which
apparently triggers recalculation of folds, which is expensive.

The following trick seems to speed up things: change the following lines in
function OtlEnterBuffer() >
    setlocal foldtext=OtlFoldText()
    setlocal foldmethod=expr
    setlocal foldexpr=OtlFoldLevel(v:lnum)
To >
    if &foldtext !=# "OtlFoldText()"
        setlocal foldtext=OtlFoldText()
    endif
    if &foldmethod !=# "expr"
        setlocal foldmethod=expr
    endif
    if &foldexpr !=# "OtlFoldLevel(v:lnum)"
        setlocal foldexpr=OtlFoldLevel(v:lnum)
    endif

==============================================================================
vimoutliner   [[[3~
                                                 *voom-mode-vimoutliner*
:Voom vimoutliner
MODULE: ../autoload/voom/voom_mode_vimoutliner.py
VimOutliner format:
    http://www.vimoutliner.org/ 

Headlines are lines with >=0 Tabs followed by any character except:
    : ; | > <
Otherwise this mode is identical to the "thevimoutliner" mode.

==============================================================================
taskpaper   [[[3~
                                                 *voom-mode-taskpaper*
:Voom taskpaper
MODULE: ../autoload/voom/voom_mode_taskpaper.py
TaskPaper format:
    http://www.vim.org/scripts/script.php?script_id=2027
    http://www.hogbaysoftware.com/products/taskpaper

Everything is indented with tabs. The level is determined by the number of
leading tabs.

Outline is constructed from lines that are Projects or Tasks. Task lines start
with "- ". Project lines end with ":" optionally followed tags.

All other lines (Notes) always belong to the Project or Task directly above
them, regardless of the indentation.

The type of headline (Project or Task) is preserved during outline operations.

The leading "- " is stripped from Task headlines.

Projects are marked with "x" in the Tree buffer, so you can jump to the
next/previous project by pressing x/X.

==============================================================================
python   [[[3~
                                                 *voom-mode-python*
:Voom python
MODULE: ../autoload/voom/voom_mode_python.py
Mode for outlining Python code. This is like a class browser except that
regions between "class" and "def" blocks are also nodes.

Headlines are
    - Classes and functions, that is first lines of "class" and "def" code
      blocks.
    - First non-blank line after the end of any "class" or "def" code block.
      This can be a comment line, but not a decorative comment line, see below.
      (NOTE: Such headlines can be killed or created by an outline operation.)
    - Comment lines that start with "###", "#--", "#==": >
        ### comment text
        #-- comment text
        #== comment text

NOTE 1: Comment lines are generally significant and their indent can influence
the level of next headlines. The exception are decorative comment lines that
consist only of "#", "-", "=", spaces and tabs: >
    #
    ########################
    #---------------------
    #==========================
such decorative comments are ignored and have no effect on the outline when
they are stand-alone. However, if such lines are followed by a comment
headline, they are associated with that headline. This allows correct handling
of pretty comment headers like this: >
    def do_something():
        pass
    ##############################
    #                            #
    # Do Nothing                 #
    #                            #
    ##############################
    def do_nothing():
        pass
The Tree buffer will show "Do Nothing" line, but the corresponding node will
start with the overline above it.

NOTE 2: Python decorators (lines starting with "@") before a function or class
are associated with that function or class. Example: >
    @re_load
    @do_not_retreat
    def hold_the_line(): ...
The Tree buffer will display "hold_the_line()", but the first line of the
corresponding node will be the line with "@re_load". It is thus safe to move
decorated function/classes in the Tree buffer--decorators will stay with them. 
Decorated functions/classes are also marked with "d" in the Tree buffer.

Headline level is determined by the line's indent relative to previous
(smaller) indents. One tab equals one space (not eight). If indent is
inconsistent, the headline is marked with '!!!' to indicate a potential indent
error.

This mode's parser uses tokenize.py to identify lines that should be ignored
(multi-line strings and expressions), as well as lines with "class" and "def".
Note that tokenize.py also checks for inconsistent indenting and can raise
exceptions in which case outline update will not be completed.

Since this mode relies on tokenize.py to do the parsing, it can be slow with
large files (>2000 lines, e.g, Tkinter.py).


OUTLINE OPERATIONS
------------------
This mode have several intrinsic problems with outline operations. Do not
disable post-operation outline verification (g:voom_verify_oop).

Outline operations assume that the Body buffer has tab-related options set
correctly to work with the Python code displayed in the buffer:
    - If 'et' is off, indenting is done with Tabs, one Tab for each level.
    - If 'et' is on, indenting is done with Spaces. The number of spaces is set
      to the value of 'ts'.
The above settings must match indentation style used by the Python code being
outlined. If they don't, an outline operation will create wrong indents
whenever a level must be changed. Outline verification after outline operation
will detect that, display error messages, and force outline update.

Outline operations can cause some headlines to disappear. (It's not clear to me
if they can appear.) This happens because regions between "class" and "def"
blocks are also nodes. This is not a bug but a confusing behavior. In the
following code there are four headlines: >
    def func1():    # headline
        pass
    a = 1           # headline (can disappear)
    def func2():    # headline
        pass
    b = 1           # headline (can disappear)
After "func2" is moved Up, line "b = 1" ceases to be a headline.  Outline
verification will detect that and complain about wrong Tree size. To protect
such fragile headline you can insert a special comment headline: >
    def func1():    # headline
        pass
    a = 1           # headline (can disappear)
    def func2():    # headline
        pass
    ### b=1         # headline (persistent)
    b = 1

Weirdly indented comment lines also can cause various confusing problems during
outline operations.

In summary:
    - Errors "wrong Tree size" after outline operations are expected and can be
      ignored. Such errors occur when nodes are moved and blocks of code
      between "class" and "def" are merged.
    - Errors "wrong levels", "wrong bnodes" could indicate serious problems and
      should not be ignored. Undo the operation after such an error. Make sure
      buffer indent settings are set correctly to handle Python code. Pretty
      comment headers should be preceded by a blank line.

==============================================================================
Miscellaneous Modes   [[[3~
                                                 *voom-mode-various*
:Voom cwiki
MODULE: ../autoload/voom/voom_mode_cwiki.py
For Vim cwiki plugin: http://www.vim.org/scripts/script.php?script_id=2176

:Voom inverseAtx
MODULE: ../autoload/voom/voom_mode_inverseAtx.py
For outlining of invese Atx-style headlines: >
    @@@ Headline level 1
    @@ Headline level 2
    @ Headline level 3
See the docstring and comments in the module for details.
Similar mode: dokuwiki, see |voom-mode-dokuwiki|


More markup modes can be found at
        https://github.com/vim-voom/VOoM_extras/tree/master/markup_modes
voom_mode_blocks.py  -- The first line of each block of non-blank lines
                        (paragraph) is headline level 1. Useful for sorting
                        paragraphs with :VoomSort.
voom_mode_dsl.py     -- Any unindented non-blank line is headline level 1.

==============================================================================
Known Issues   [[[2~

1) Memory used by Vim can increase significantly when outline operations Move
Up/Down are applied repetitively to a large node or a block of nodes (>1MB).
These commands delete and then insert lines in Body buffer. If the range being
moved is large, this can cause dramatic increase in memory used by the undo
history. Thus, to move a large node over a long distance it's better to use
Cut/Paste rather than keep pressing Ctrl-Up/Down.
This problem doesn't exist if 'undolevels' is set to -1, 0, 1.
A handy way to clear undo history:
set 'undoreload' to 0, reload the file with :e or :e! .

2) Undoing some outline operations can take a longer than usual time if a large
number of Body folds (>1000) is affected. The workaround is to temporarily set
Body's 'foldmethod' to manual (:set fdm=manual).

3) Outline navigation and outline operations can be sluggish if there are
time-consuming BufEnter, BufLeave, WinEnter, WinLeave autocommands associated
with the Body buffer. This is because most VOoM commands involve entering and
leaving Body buffer window, often temporarily. This is a problem with .otl
files of The Vim Outliner plugin (|voom-mode-thevimoutliner|).
Heavy syntax highlighting can also make outline navigation slow, especially
when selecting a node in a large outline for the first time. This is a problem
with large reST, Markdown, AsciiDoc, LaTeX files. Disabling cursorline or
cursorcolumn or both helps a bit (:set nocul nocuc).

4) Support for Vim Sessions (|:mksession|) is far from perfect. If 'ssop'
contains "blank", the command :mksession will save info about Tree buffers,
that is no-file buffers named {Body_name}_VOOM{Body_bufnr}. When the session is
restored, VOoM tries to recreate the outline for such buffers.
    - Markup modes are not remembered. Outline is always created with the
      command :Voom. You can use |g:voom_ft_modes| or |g:voom_default_mode| to
      select the desired markup mode automatically.
    - The Tree and corresponding Body buffer must be in the same tab page.
    - If 'ssop' contains "options", the command :mksession saves all Tree
      buffer-local mapping (because all voom.vim functions are global).
      This is redundant and increases the size of the Session file for no good
      reason -- about 120 mappings for each Tree buffer.
    - If 'ssop' contains "folds", :mksession doesn't really save Tree folding,
      only some folding options which will be restored anyway.

5) Some markup modes (rest, asciidoc, markdown) depend on 'encoding'. If it is
changed, the outline needs to be recreated for the new value to take effect.

6) When a VOoM outline is deleted, Body's original mappings for <Return> and
<Tab> (or whatever keys are used by |voom-shuttle-keys|) are not restored if
they were buffer-local. Only global mappings get restored. Since buffer-local
mappings are typically created by filetype plugins, you can restore them by
reapplying the filetype, e.g., ":set ft=vimwiki".

7) ID_20131122200944
If the outline is irregular, i.e, levels are skipped, sibling nodes can become
hidden in folds. This means some commands do not expand such nodes properly.
Example outline: >
      |A
    = . . . |B
      . . . |C
      . . . |D
With cursor on B, command "C" leaves only B visible.

8) Commands Copy/Cut fail with a Python error if the text contains null bytes
(^G). The Body is left unchanged when such error occurs.


==============================================================================
EXECUTING NODES (:Voomexec)   [[[1~
                                                 *voom-Voomexec*
:Voomexec [type]        Execute text from the current node and descendant nodes
                        (Tree buffers) or from the current fold and subfolds
                        (Body and non-VOoM buffers) as [type] script. Supported
                        types are: "vim", "python" or "py".
                        In Tree buffers Voomexec is mapped to <LocalLeader>e.

The following happens when the command :Voomexec is executed:

1) The type of script is determined.
-----------------------------------
    :Voomexec           Without an argument, the type of script is set to
                        buffer 'filetype': "python" if filetype is "python",
                        "vim" if filetype is "vim", etc. When executed from a
                        Tree buffer (also with <LocalLeader>e), filetype of
                        the corresponding Body is used.

    :Voomexec vim       Execute as "vim" script.

    :Voomexec python
    :Voomexec py        Execute as "python" script.

    :Voomexec whatever  Execute as "whatever" script.

    If script type is neither "vim" nor "python", the command aborts.
    It should be possible to add support for other script types.

2) The text of script is obtained.
---------------------------------
    a) If the current buffer is a VOoM Tree buffer, the script's text is set to
       that of the current node (including headline) and all descendant nodes,
       that is to Body's text in the current VOoM subtree. Body folding does
       not matter.

    b) If the current buffer is a VOoM Body or a non-VOoM buffer, the script's
       text is set to that of the current fold, including all subfolds. This is
       most useful when 'foldmethod' is "marker". If 'foldmethod' is not
       "marker", the command aborts and the script is not executed.

3) The script is executed according to its type.
-----------------------------------------------
    a) A "vim" script is executed by copying text into a register and executing
       that register (|:@|) in a function inside try/catch/finally/endtry.
       If an error occurs, v:exception is echoed. (v:throwpoint is useless.)

    b) A "python" script is executed as a string via the "exec" statement, see
       http://docs.python.org/reference/simple_stmts.html#exec .
       The following Python names are pre-defined: vim, _VOoM (module voom_vim).

       An extra line is prepended to script lines to specify encoding as per
       http://www.python.org/dev/peps/pep-0263/ , e.g.
                # -*- coding: utf-8 -*-
       Encoding is Vim's internal encoding ('utf-8' for all Unicode &enc).

       The script is executed inside try/except block. If __PyLog__ is enabled
       and an error occurs, Python traceback is printed to the __PyLog__ buffer
       instead of Vim command line.

NOTE: The "end of script" message shows the first and last line number of the
script's text.

==============================================================================
sample Vim scripts   [[[2~

Scripts in the following subnodes can be executed with >
    :Voome vim

------------------------------------------------------------------------------
"---node 1---[[[3o~
echo 'in node 1'
py print _VOoM.VOOMS.keys()

" section [[[
echo 'inside section in node 1'
" ]]]

"----------------------------------------------------------------------------~
"---node 1.1---[[[4o~
echo 'in node 1.1'

"----------------------------------------------------------------------------~
"---node 1.1.1---[[[5~
echo 'in node 1.1.1'

"============================================================================~
sample Python scripts   [[[2~

Scripts in the following subnodes can be executed with >
    :Voome py

------------------------------------------------------------------------------
#---node 1---[[[3o~
print '   in node 1'

print 'current buffer number:', vim.eval('bufnr("")')
print 'VOoM Body buffer numbers:', _VOoM.VOOMS.keys()
print 'voom_vim.makeOutline() docstring:\n   ', _VOoM.makeOutline.__doc__ ,'\n'
import os
print 'current working dir:', os.getcwd()

# section [[[
print '   inside section in node 1'
# ]]]

#----------------------------------------------------------------------------~
#---node 1.1---[[[4o~
print '   in node 1.1'

#----------------------------------------------------------------------------~
#---node 1.1.1---[[[5~
print '   in node 1.1.1'

#============================================================================~
Alternatives to :Voomexec   [[[2~

Other Vim commands and scripts can retrieve the contents of VOoM nodes as a
range of Body lines and do something with it.

1) In a Tree buffer, the "R" command selects the corresponding Body line range,
which can then be passed to a range-accepting command.

2) Function voom#GetExecRange(lnum) is what :Voomexec uses to obtain the
script's text, that is Body's lines from the current subtree (Tree buffers), or
lines from the current fold (Body buffers, non-VOoM buffers).
The following function shows how to use voom#GetExecRange(): >
    func! Voom_WriteExecRange()
        " Write to a file lines that are executed by :Voomexec.
        let filePath = '~/voomscript'
        let [bufType, body, bln1, bln2] = voom#GetExecRange(line('.'))
        if body<1 | return | endif
        let blines = getbufline(body, bln1, bln2)
        call writefile(blines, expand(filePath))
    endfunc

3) Function voom#GetVoomRange(lnum,withSubnodes) can be used by other scripts
to obtain the contents of a VOoM node at line number lnum (withSubnodes==0),
or the contents of node and its subnodes (withSubnodes==1). Unlike
voom#GetExecRange(), it works the same for Tree and Body buffers, and it
doesn't care about folding or non-VOoM buffers. Typical usage: >
    let [bufType, body, bln1, bln2] = voom#GetVoomRange(line('.'), 0)
    " Error: Body not loaded, outline update failed, etc.
    if body < 0
        echo 'ERROR'
    " Current buffer is not a VOoM buffer. Do something with the current line.
    elseif bufType==#'None'
        echo getline('.')
    elseif bufType==#'Tree'
        echo 'in Tree'
        echo getbufline(body,bln1,bln2)
    elseif bufType==#'Body'
        echo 'in Body'
        echo getbufline(body,bln1,bln2)
    endif

4) Function voom#GetBuffRange(ln1,ln2) can be used by other scripts to obtain
the contents of VOoM nodes in Tree line range ln1,ln2 if the current buffer is
a Tree (same as the "R" command). If the current buffer is not a Tree, it
returns the ln1,ln2 range for the current buffer. Example: >
    let [bufType, body, bln1, bln2] = voom#GetBuffRange(line("'<"),line("'>"))
    if body < 0 | return | endif
    let blines = getbufline(body,bln1,bln2)
    ... do something with blines ...

==============================================================================
Known Issues   [[[2~

1) Vim script code executed this way cannot use |line-continuation|.

2) When :Voomexec executes a Vim script with Python code and a Python error
occurs, Python traceback is not printed. However, Python traceback is printed
to the PyLog buffer if it is enabled. Example in the next fold can be executed
with ":Voome vim". >

    " Vim script with Python error [[[
    echo 'start of vim script'
    py print bogus_name
    py print 'py after error'
    echo 'the end'
    " ]]]

3) As the example above illustrates, Vim script is not terminated when an
error occurs in the Python code.

==============================================================================
__PyLog__ BUFFER (:Voomlog)   [[[1~
                                                 *voom-Voomlog*
:Voomlog        This command creates scratch buffer __PyLog__ and redirects
                Python's stdout and stderr to that buffer.

Subsequent Python print statements and error messages are appended to the
__PyLog__ buffer instead of being printed on Vim command line.

Windows with the __PyLog__ buffer are scrolled automatically in all tabpages
when something is printed to the PyLog buffer. If a tabpage has several PyLog
windows, only the first one is scrolled. If the current tabpage has no PyLog
windows, the command :Voomlog will create one.

To restore original stdout and stderr (that is Vim command line): unload,
delete, or wipeout the __PyLog__ buffer (:bun, :bd, :bw).

NOTE: __PyLog__ buffer is configured to be wiped out when unloaded or
deleted. 'bufhidden' is set to "wipe".

The filetype of the PyLog buffer is set to "voomlog". Some syntax highlighting
is added automatically to highlight Python tracebacks, Vim error, and common
VOoM messages.

When Python attempts to print a unicode string, e.g. >
    :py print u'ascii test'
    :py print u'\u042D \u042E \u042F \u2248 \u2260'
the string is encoded using internal Vim encoding at the time of __PyLog__
buffer creation. Internal encoding is determined from Vim option 'encoding':
"utf-8" if &encoding is a Unicode encoding, &encoding otherwise.

==============================================================================
Known Issues    [[[2~

1) All output lines appear in the __PyLog__ buffer simultaneously after the
script is finished, not in real time. Example (executable with :Voome py):

### demo Python code [[[
import time, datetime
print datetime.datetime.now()
time.sleep(5)
print datetime.datetime.now()
### ]]]


2) Printing many lines one by one can take a long time. Instead of doing >
    :py for i in range(1000): print i
It is much faster to do >
    :py print '\n'.join([str(i) for i in range(1000)])
(It's also easier to undo.)


3) Visiting other tabpages during automatic scrolling is slow on Linux in GUI
Vim (GTK). It's better to have PyLog window only in the current tabpage.


4) __PyLog__ is not usable when in the Ex mode, that is after 'Q' or 'gQ'.
The lines in the __PyLog__ buffer will appear after the Ex mode is exited.

    id_20110213225841
5) When __PyLog__ is enabled, a Python error in a Vim script does not result in
Vim error. This is probably because Python's sys.stderr is redirected. This
disrupts Vim error handling when a Python code is executed by Vim inside
try/endtry. Example Vim script, compare the output with PyLog off and on: >
    try
        python assert 1==2
        echo 'AFTER PYTHON ERROR -- should not be here'
    finally
        echo 'AFTER FINALLY'
    endtry
    echo 'AFTER TRY -- should not be here'


6) In versions before 1.7 there was problem with the output of help(), which
apparently uses Lib/pydoc.py, which does something strange to output trailing
\n. Steps to reproduce:
    1. Open new instance of Vim.
    2. Voomlog
    3. :py help(help)
    4. Wipe out __PyLog__ buffer to restore sys.stdout.
    5. :py help(help)
       An error occurs: '\n' is printed to the nonexisting log buffer.
The culprit is in Lib/pydoc.py:
    help = Helper(sys.stdin, sys.stdout)
The current workaround is to delete pydoc from sys.modules when changing
stdout and stderr.

==============================================================================
Add-ons   [[[1~
                                                 *voom-addons*
VOoM add-ons are Vim or Python scripts that use "voom.vim" and "voom_vim.py"
functions and data. Add-ons make it possible to add new functionality or to
customize default features without modifying the core files.


LOADING ADD-ONS
---------------
Some Vim script add-ons can be sourced at any time, which means they can be
placed in $HOME/.vim/plugin/ like any other plugin.

For finer control, user option "g:voom_user_command" should be used to load
add-ons only when file voom.vim is being sourced. This option defines a string
to be executed via |execute|. This is the last thing done in autoload/voom.vim: >
    if exists('g:voom_user_command')
        execute g:voom_user_command
    endif

There is no default "g:voom_user_command", it must be created by the user.

METHOD 1: Add-ons are .vim files located in $HOME/.vim/add-ons/voom/
To load them all via |runtime|, put this in vimrc: >
    let g:voom_user_command = "runtime! add-ons/voom/*.vim"

METHOD 2: Add-ons are in one file, D:/SCRIPTS/VOoM/voom_addons.vim
To source the file, put this in vimrc: >
    let g:voom_user_command = "source D:/SCRIPTS/VOoM/voom_addons.vim"

METHOD 3: Add-ons are in a Python module voom_addons.py, somewhere in the
Python search path (directory ../autoload/voom will do). To import the module,
put this in vimrc: >
    let g:voom_user_command = "python import voom_addons"
The module voom_vim.py can be accessed from within voom_addons.py as follows: >
    import sys
    voom_vim = sys.modules['voom_vim']


WRITING ADD-ONS
---------------
There is no special API. The following applies:

    - Python-side functions and data are available as attributes of module
      "voom_vim.py". Note that this module is imported in "voom.vim" as
      "_VOoM".
    - Python-side outline data for each Body are attributes of an instance of
      class VoomOutline (VO). These class instances are stored in dictionary
      _VOoM.VOOMS, keys are Body buffer numbers: VO=_VOoM.VOOMS[body].

    - All Vim functions in "voom.vim" are global and start with "voom#".

    - Vim-side data are script-local. Several functions in "voom.vim" allow
      external scripts to retrieve various outline information and data:
            voom#GetTypeBodyTree(...)
            voom#GetModeBodyTree(bnr)
            voom#GetBodiesTrees()
            voom#GetVar(var)
      Sample add-on "voom_stats.vim" shows how to use them. Examples: >
            :let [bufType, body, tree] = voom#GetTypeBodyTree()
            :let [mmode, MTYPE, body, tree] = voom#GetModeBodyTree(bufnr(''))
            :let [voom_bodies, voom_trees] = voom#GetBodiesTrees()
<
      Function voom#GetVar(var) allows external scripts to read any "voom.vim"
      script-local variable if it exists. Examples (these always exist) >
          :echo voom#GetVar('s:voom_logbnr')
          :echo voom#GetVar('s:voom_trees')
          :echo voom#GetVar('s:voom_bodies')
<
      Example: move the cursor to Log window in the current tab >
          :let logwnr = bufwinnr(voom#GetVar('s:voom_logbnr'))
          :if logwnr > 0 | exe logwnr.'wincmd w' | endif
<
    - Several functions allow external scripts to retrieve the contents of
      nodes (a range of Body lines), see
            EXECUTING NODES (:Voomexec) -> Alternatives to :Voomexec


USING ADD-ONS TO ADD NEW FUNCTIONALITY
--------------------------------------
Add-ons can create global commands, menus and mappings.

A global command that accesses VOoM outline data must first check that the
current buffer is a VOoM buffer (Tree or Body) and refuse to execute if it's
not. It should update outline if current buffer is a Body. Sample add-on
"voom_stats.vim" shows how to do that.

The filetype of Tree buffers is set to "voomtree". Thus, you can use the
following files in Vim user folder to create Tree-local mappings and commands: >
    ftplugin/voomtree.vim
    after/ftplugin/voomtree.vim
Tree buffer syntax highlighting can be customized via >
    syntax/voomtree.vim


USING ADD-ONS TO MODIFY VOoM
----------------------------
Add-ons can overwrite and modify core code functions and some data. Add-on
"custom_headlines.vim" is an example of this approach. It shows how to
customize construction of Tree headline text for individual filetypes.
Such add-ons must be loaded after "voom.vim" has been sourced completely, that
is via option g:voom_user_command as explained above.


MARKUP MODES
------------
Markup modes are special kinds of add-ons. They change how outline is
constructed and how outline operations are performed (|voom-markup-modes|).

==============================================================================
Implementation notes   [[[1~
                                                 *voom-notes*

==============================================================================
Theory of Operation   [[[2~

==============================================================================
Why Python   [[[3~

The main reason VOoM uses Python is because some of its critical code is much
faster in Python than in Vim script.

Scanning a buffer for fold markers is >10 times faster with Python code than
with a similar Vim script code. A demo code is given below. To test: select
lines, copy into a register, and execute that register while in any buffer with
a large number of fold markers, or in any large buffer.

Results with "calendar_outline.txt": >
    3.2MB, 56527 lines, 4160 headlines
    Vim 7.3.145; Python 2.6.5; Win2k; Intel Pentium 4 Mobile, 1.6 GHz

    Vim method 1: 1.53 sec
    Vim method 2: 0.70 sec
    Vim method 3: 0.14 sec
    Python:       0.084 sec

While Vim method 3 is fast, it is inconvenient because:
    a) It requires the cursor to be in Body buffer, but outline update should
       be run after entering the Tree buffer.
    b) It moves the cursor.

"--------------GET LINES WITH FOLD MARKERS---------------------------[[[
" Get list of headlines: lines with start fold marker followed by number.
" This is the bare minimum that must be done to create an outline.

""""" Vim method 1
func! Voom_VimTest1()
    let headlines = []
    let allLines = getline(1,'$')
    for line in allLines
        if stridx(line, '{{{')==-1        "}}}
            continue
        endif
        if match(line, '{{{\d\+')!=-1     "}}}
            call add(headlines, line)
        endif
    endfor
    return len(headlines)
endfunc

""""" Vim method 2
func! Voom_VimTest2()
    let lnums = filter(range(1,line('$')), 'getline(v:val)=~''{{{\d\+''')
    let headlines = map(lnums, 'getline(v:val)')
    return len(headlines)
endfunc

""""" Vim method 3
func! Voom_VimTest3()
    let headlines = []
    g/{{{\d\+/ call add(headlines, getline('.'))     "}}}
    return len(headlines)
endfunc

""""" Python code, similar to Vim method 1
python << EOF
def Voom_PyTest():
    import vim
    import re
    re_marker = re.compile(r'{{{\d+')   #}}}
    headlines = []
    allLines = vim.current.buffer[:]
    for line in allLines:
        if not '{{{' in line: continue  #}}}
        if re_marker.search(line):
            headlines.append(line)
    vim.command('let bnodes=%s' %len(headlines))
EOF

""""" timing
let start = reltime()
let nodeCount = Voom_VimTest1()
echo 'Vim method 1: ' . reltimestr(reltime(start)) . 'sec; '. nodeCount . ' nodes'

let start = reltime()
let nodeCount = Voom_VimTest2()
echo 'Vim method 2: ' . reltimestr(reltime(start)) . 'sec; '. nodeCount . ' nodes'

let start = reltime()
let nodeCount = Voom_VimTest3()
echo 'Vim method 3: ' . reltimestr(reltime(start)) . 'sec; '. nodeCount . ' nodes'

let start = reltime()
py Voom_PyTest()
echo 'Python:       ' . reltimestr(reltime(start)) . 'sec; '. nodeCount . ' nodes'

unlet nodeCount
"--------------END OF CODE ------------------------------------------]]]


In addition, Python's FOR loop is >30 times faster then Vim's. In the demo
code below the Python function is >60 times faster.

"------ Vim FOR loop versus Python FOR loop -------------------------[[[
func! Time_VimForLoop()
    let aList = range(1000000)
    for i in aList
        " pass
    endfor
endfunc

python << EOF
def Time_PyForLoop():
    aList =     range(1000000)
    for i in aList:
        pass
EOF

""" 9.76 sec """
let start = reltime()
call Time_VimForLoop()
echo 'Vim:    ' . reltimestr(reltime(start))

""" 0.15 sec """
let start = reltime()
py Time_PyForLoop()
echo 'Python: ' . reltimestr(reltime(start))
"-------END OF CODE--------------------------------------------------]]]

Thus, Python code should be much faster when handling large lists.

==============================================================================
Separate Trees or single Tree   [[[3~

A single Tree buffer could be used to display outlines of many files. Tlist
does that. This makes sense when working with several related files. Also,
having a single Tree would be more like Leo.

VOoM creates new Tree buffer for every new outline. This is simpler. It is
more appropriate for text notes, when outline files are likely to be
unrelated. Searching headlines is easier.

==============================================================================
Checking Bodies for ticks   [[[3~

Tree buffer and associated outline data are updated on entering Tree via
BufEnter autocommand. To perform update only when the Body has changed since
the last update, Body's b:changedtick is used as shown in the docs.
Unfortunately, b:changedtick cannot be read with getbufvar(), so it's not
accessible from Tree on BufEnter (see NOTE 1 below). The workaround is to use
Body's BufLeave autocommand to save Body's b:changedtick.
So the entire update scheme is:
    - on Body BufLeave save Body's b:changedtick as "tick"
    - on Tree BufEnter compare "tick_" to "tick"
    - if different, do the outline update and set "tick_" to "tick"

The outline must be up to date when the cursor is in the Tree buffer. If it's
not, the consequences could be unpleasant. Performing outline operations will
cause data corruption.

Outline update can fail when something goes wrong with autocommands, e.g.,
when the user messes with 'eventignore'. Or, the Body file can be modified by
an external application while cursor is in Tree.

Fortunately, most Voom commands involve a visit from Tree to Body or vice
versa, so we can compare "tick_" directly to Body's "b:changedtick". If they
are different: the command is aborted, outline update is forced, error message
is displayed. Such check is performed:
    - during any outline operation (before modifying the Body buffer)
    - when selecting node from Tree or Body
    - during Voomgrep command initiated from Tree
The function that does this check is voom#BodyCheckTicks().

These checks can be tested by modifying Body and then moving to Tree with
":noau wincmd w" or after ":set ei=BufLeave", etc.

Another precaution is that "tick_" is not set to "tick" when an unexpected
error occurs during update.  voom_vim.updateTree()) is always called from Vim
code inside try/finally/endtry. It also sets Vim var l:ok to indicate success,
see #id_20110213212708 .

NOTE 1: This was fixed by Patch 7.3.105 -- b:changedtick can be obtained via
getbufvar(). In VOoM 4.7 and above a few operations assume that this patch is
present and first try to check Body ticks while in Tree in order to avoid an
unneeded trip to Body and back. The code relies on the fact that
    getbufvar(body,"changedtick")
returns "" without the patch. When the value of getbufvar(body,"changedtick")
is wrong, the next step is always to move the cursor into Body (it may no
longer exist, unloaded, etc.) and check for b:changedtick directly. This
automatically takes care of versions before the patch. See code for operations
Insert Node, Copy, Folding Save/Restore/Cleanup.

NOTE 2: Outline operations other than Sort do not rely on the outline update.
They do a targeted adjustment of outline data and then verify the resulting
outline against the outline produced by the wholesale update.

==============================================================================
Unloaded buffer + python == trouble   [[[3~

Bad things happen when attempting to modify an unloaded buffer via Python
vim.buffer object. (This might be considered a Vim bug.) Example:
    - Create two buffers: buf1 and buf2. They can be new, no-file buffers.
    - With cursor in buf2
      :py buf2=vim.current.buffer
    - Buffer 2 can now be modified via Python:
      :py buf2[0]="xxxxxxxxx"
    - Unload buffer 2
      :bun!
      Buffer 1 is the current buffer.
    - Try writing to buffer 2, which is not loaded
      :py buf2[0]="yyyyy"
    - Buffer 1 is modified instead of buffer 2, and the change cannot be undone!
      Buffer 2 is no longer unloaded, so subsequent writes to it via buf2
      happen correctly.

P.S. (2013-11-18) This behavior is changed in Vim 7.4.52. The unloaded buffer
is automatically loaded and is written to, that is it becomes hidden. This is
better, but is not really helpful: buffer's content was lost when the buffer
was unloaded.

VOoM uses Python vim.buffer methods to modify Tree, Body, and PyLog buffers.
It is essential that these buffers are loaded (bufloaded())before being written
to. Writing to a non-existing (wiped out) buffer is not as dangerous because it
produces an error.

Tree and PyLog BufUnload autocommands make it unlikely that a Tree or PyLog
buffer is unloaded -- they are wiped out on BufUnload.
These buffers can still become unloaded when they are closed improperly with
"noa bun" or "noa bd" or when something goes wrong with autocommands.

Body buffers can be unloaded since VOoM v3.0.

There are checks that ensure that the buffer is loaded (bufloaded()) before it
is modified via Python vim.buffer object.

==============================================================================
Wipe out Tree on BufUnload   [[[3~

A Tree buffer should be wiped out and the corresponding VOoM data deleted
after:

1) Tree is unloaded. All contents is lost, Tree reverts to blank buffer.
2) Tree is deleted. As above, plus buffer-local mappings are lost.
2) Tree is wiped out. VOoM data need to be cleaned up.

This is accomplished via BufUnload autocmd for Tree, which is also triggered on
BufDelete and BufWipeout.

Unloaded, deleted, and wiped out Body buffers are obviously also a problem, see
next node. Prior to v3.0 there was Body BufUnload au that wiped out Tree. That
was found to be too risky.

There are several fail-safe measures that ensure that nothing damaging will
happen if Tree BufUnload autocommand is not triggered, as after "noa bun", "noa
bd", "noa bw".

Most Voom commands check that: Tree is loaded, Body exists, Body is loaded (see
next). This relies on bufloaded() and bufexists().

Functions voom#ToBody() and voom#ToTree(), which are called when selecting
nodes and before almost every outline operation, perform all of the above
checks and will do cleanup if checks fail.


The PyLog buffer should also be wiped out when unloaded or deleted. There is a
check that ensures that PyLog is loaded before printing to it.

==============================================================================
Unloaded, deleted, wiped out Bodies   [[[3~

Unloaded Body buffers are a problem:

It is not possible to outline a buffer if it is unloaded.
Python vim.buffer object is useless for unloaded buffer, it's [""].

When unloaded Body is loaded again the following events are hard to detect:
    - buffer changes were abandoned after q!, bun!, bd!
    - file was modified by external process

Thus, a global outline update must be done after loading Body. This means we
should abort outline command if Body is found unloaded, even if we can load it
and force outline update.

PERFECT: Body b:changedtick is incremented by 2 after unloading/loading.
Outline update is guarantied on Tree BufEnter or when updating from Body.

We deal with unloaded Bodies by disabling Tree buffer commands -- as soon as
Body bufnr is computed, check if it's loaded and abort the command if it's not.
Helper function is voom#BufLoaded(body). It will also detect if Body does not
exist. This must be done for:
    outline update on BufEnter
    all outline operations
    node selection (always done by voom#TreeSelect())
    Voomgrep, Voomunl, Body text getters (Voomexec)
    any other command that requires up-to-date outline, or reads/writes Body

The next line of defense is voom#ToBody(), which is called by almost all Tree
commands. When it detects Body is unloaded it loads it in new window as usual,
runs outline update, returns -1. If Body does not exist it performs clean up.

The b:changedtick check (see "Checking Bodies for ticks") also should prevent
potential troubles after Body unload/reload. This is because b:changedtick
changes after unloading a buffer and loading it again.


When Body buffer is deleted (:bd) it is unloaded. In addition, buffer-local
mappings are lost. The loss of Body-local mappings (shuttle keys) is detected
by Body BufEnter au. It checks for hasmapto('voom#ToTreeOrBodyWin') and
restores mappings if needed.

The command :Voom checks hasmapto('voom#ToTreeOrBodyWin') when executed in Tree
or Body. If not found, it reconfigures Tree/Body. In theory, this can be used
to restore Tree and Body configurations after some perverted unloads/reloads
with ":noa bd", "noa b", etc.


Wiped out Bodies are also unloaded. Tree has no reason to exist after Body has
been wiped out. Sadly, wiping out Tree from Body BufWipeout au is too risky,
see v3.0 notes.


==============================================================================
TODO   [[[2~

Outline operations could use try/finally/endtry for maximum resilience.
Harden against interrupts: slow computer, huge outline, user presses <C-c> in
the middle of an outline operation.
Vim 7.4: vim.error in Python code completely stops Vim script execution.
Vim bug: foldtext is messed up in all windows if uncaught error in try/entry.
Seems to be fixed as of 7.4.052

Write FAQ.
Write implementation notes: data model, markup modes, outline operations.

The most sensible and the least confusing initial behavior for the command
:Voom is to _require_ an argument when creating an outline.
Setting g:voom_default_mode to "fmr" will restore original behavior.
Move relevant code to voom_mode_fmr.py and may be similar .vim file.

Change Tree buffer names so that they contain markup mode:
    source.txt_VOOM99()          --default mode
    source.txt_VOOM99(markdown)  --markdown mode
This is the only way to choose original markup mode when restoring a Session.

Should g:voom_verify_oop be removed?

Do something about Python 3.

Voomgrep enhancements:
    Show results by folding non-matching lines and nodes. (:VoomGrep)
        ?  Need command to restore previous folding settings.
    ~ "foo and not bar" seems better than "foo not bar" and easier to parse.

Add command to Mark/Unmark only visible nodes (not hidden in folds).
Could be add-on.

Tree mapping to move to next/previous sibling with a child. There are no more
letters left to map.

Insert New Node: make new headline text an argument of function to make
programmatic creation of outlines more convenient, especially when there are
underlines/overlines (markdown, reST). Example code at #ID_20111006013436 .
Also need args for mark and level.

Set jump mark when selecting node from Tree with <Enter> or other actions.
This could be used as outline browsing history.
Currently no jump marks are created in Tree or Body during node navigation or
manipulation (:keepj when G, gg, etc).
It is difficult to decide which commands should set a mark.

Outline navigation functions should probably also check that the current buffer
is Tree (voom#BufNotTree) in case external script makes a mistake.

Read-only modes with VimScript parsers: Vim regexp, folds.
This should be handled by setting MTYPE.
Similarly, need a method to disable Move Right: markup modes "dsl", "blocks".

Do something about duplicate Python code, especially among markup modules.
In many cases "from voom_mode_... import ..." should be sufficient.

Fix expanding of sibling nodes in irregular outlines: #ID_20131122200944 .
Hard to fix. Not a big deal because it's rare. Should be handled by TreeZV().

==============================================================================
CHANGELOG   [[[2o~

v5.1, 2014-06-22   [[[3x~

New markup mode: dokuwiki.

Python markup mode: better handling of decorative comment lines (separators and
pretty headers). https://github.com/vim-voom/vim-voom.github.com/issues/13

:Voomgrep improvements.
Maximum number of matches was increased to 500000.
The command now aborts with an error message when maximum number of matches is
exceeded while searching for a pattern.
Changed how results are displaed in quickfix buffer: "N" is shown before the
node's number if the node contains all AND matches, "n" otherwise.

PROBLEM: Copy/Cut fails with a Python error if text contains null bytes (^G).
SOLUTION: Do nothing, let it fail, but make sure there are no consequences and
Body is left unchanged. Copy fails without any consequences. Cut was tweaked to
tolerate such errors: set l:blnShow last to signal that Python code succeeded,
same as with other operations.

PROBLEM: Outline verification is not performed after an outline operation if
Body's b:changedtick is unchanged. This was introduced in previous version to
avoid unneeded verifications after operations that change nothing: marking an
already marked node, moving a child node right, etc. This is wrong: an internal
defect or a badly designed markup mode may leave the Body unchanged but still
modify Tree/bnodes/levels. 
SOLUTION: Do not check if Body's b:changedtick changed before calling outline
verification. Disable unneeded verifications on a case by case bases via
l:doverif. 


v5.0, 2013-11-26   [[[3~

The code and directory structure have been reorganized:
    - The Vim script part of the plugin was rewritten to use |autoload| instead
      of FuncUndefined au. This mostly involved renaming functions Voom_... to
      voom#...
    - The main Python module "voom.py" was renamed "voom_vim.py". It is
      imported in Vim as _VOoM.
    - The VOoM package now contains only the essential (standard) directories
      and files. The extra stuff can be found in github repo VOoM_extras.
    - Helptags were changed: separator is "-" instead of "_".

:Voomgrep can now perform hierarchical searches (tag inheritance).

New option: |g:voom_clipboard_register|. Copy/Cut/Paste by default use the "o
register if Vim does not have clipboard support.

New option: |g:voom_always_allow_move_left|. Allows Move Left if nodes are not
at the end of their subtree.

New markup modes: pandoc (Pandoc Markdown), inverseAtx.

Improved Python markup mode: decorators are no longer headlines and are not
displayed in the Tree buffer. They belong to the corresponding function/class
node, so it is safe to move decorated functions/classes.

Improved Markdown mode. It now handles headlines in ambiguous format correctly:
underline overrides hashes. The parser is slightly faster.

Fixed a bug in Markdown, AsciiDoc modes. During some outline operations an
underline was not removed or changed when it was the last line in the buffer.
That was caused by off-by-one error when checking if the line is the last one.

reST mode:
- The reST parser was optimized for large paragraphs: only check lines 2 and 3
  from the top for an underline and skip the rest. The parser is up to 30%
  faster with large paragraphs.
- The reST parser is now more strict. A headline must be preceded by a blank
  lines or another headline. Previously, headlines with an overline did not
  always need to be preceded by a blank line or another headline.
- Headline text is not allowed to look like an underline/overline unless it is
  shorter than the underline. This is to avoid ambiguities and errors during
  outline operations.

Problem introduced by Vim 7.4: Calling vim.command("echoerr ...") in Python
code triggers Python exception vim.error, breaks the Python code, completely
stops execution of containing Vim script code.
Solution: always use voom#ErrorMsg() to put up error messages from Python.

Problem: Changing fdl in plugin/voomtree.vim has no effect when there is a
markup mode because fdl is set when Tree is drawn.
Solution: Set Tree filetype _after_ the Tree is drawn, in TreeConfigFt().
Related: don't create Tree syntax if b:current_syntax exists.

Changed &ul to &l:ul in voom.vim just in case. "setl" is already used
everywhere to set ul to -1. Vim Patch 7.4.073 makes &ul global-local.

Tree mappings:
Don't disable "o" in Visual, it's useful.
Map <Space> in Visual to <Esc>.
Tweaked how D J U K extend selection in Visual.
Tweaked <Right> and "o": try to handed correctly folded lines with irregular
levels, e.g., outline has only level 3 nodes. Such nodes can be folded, yet
have no children.
There are still problems with irregular outlines: the subtree can be contracted
so that only the first sibling is visible. See  #ID_20131122200944 .


v4.7, 2013-01-28   [[[3~

New markup mode: taskpaper (|voom-mode-taskpaper|).
https://github.com/vim-voom/vim-voom.github.com/issues/6

PROBLEM: https://github.com/vim-voom/vim-voom.github.com/issues/7
The issue can be observed after adding the following au
    :autocmd BufLeave,FocusLost * silent wall
Error in Voom_OopFromBody(). Outline operations fail because b:changedtick is
incremented when Body is saved on BufLeave, which triggers outline update on
Tree BufEnter, which prematurely resets Tree to noma and also renders outline
verification useless.
SOLUTION: Block outline update when Tree is &ma. All outline operations that
rely on verification set Tree ma for the duration of operation to suppress
update. Force outline verification when Body's tick changes unexpectedly
(s:verify overrides g:voom_verify_oop). Other small changes to make outline
operations more resilient.

License changed to CC0.

Code tweaks:
- Another foolproofing measure: Voom_BufNotTree(tree) checks if Tree is &ma.
- Outline verification is now run after Folding Save/Restore.
- Better use of getbufvar(body,"changedtick"). No need to check Vim version, it
  returns "" if Vim < 7.3.105. Use it during Copy.
- New function Voom_GetModeBodyTree() -- external scripts can use it to
  determine the current markup mode.
- Renamed several functions used by external scripts:
      Voom_GetData() > Voom_GetBodiesTrees()
      Voom_GetBufInfo() > Voom_GetTypeBodyTree()


v4.6, 2012-12-03   [[[3~

Warning message is no longer displayed when a markup mode is invoked.

New command :Voominfo [all] prints information about the current outline and
VOoM internals.

Sample add-on voom_info.vim was renamed to voom_stats.vim.

Got rid of s:voom_bodies[body].blnr. It was used only during outline creation.
Renamed some voom.vim functions.


v4.5, 2012-11-13   [[[3~

New Tree mapping: "I" jumps to the last line of the current node.

Improved txt2tags mode.
 - Ignore headlines in Comment Areas, that is between %%% .
 - Display "+" for numbered titles in the Tree marks column instead of
   prepending "+" to headline text.

Fixed a bug in :Voomgrep search. Results were correct only for the first 2 AND
patterns. False results were produced when searching with >2 AND patterns
because intersection was computed incorrectly.

Improved display of :Voomgrep results.
 - Buffer name is removed from lines in the quickfix buffer to save space.
 - Syntax highlighting is adjusted automatically -- it is no longer necessary
   to customize syntax/qf.vim.
 - All AND patterns are added to the "/ register, not only the first one as
   before. This does not always work correctly with multiple AND patterns --
   "\c" and "\C" are problematic.

Rewrote :Voomgrep input parser function.

Added check that the current buffer is Tree to top-level functions for outline
operations (Voom_BufNotTree). This is in case an external script or command
makes a mistake and executes in wrong buffer.


v4.4, 2012-06-03   [[[3~

Added LaTeX mode: |voom-mode-latex|.

Better mappings for Insert New Headline: "aa", "AA". <LocalLeader>i/I were
changed to <LocalLeader>a/A.

Improved Edit Headline ("i", "I"). It now correctly positions the cursor on the
headline text for most markups most of the time.

Improved "C", "O": window layout was not always restored properly.

Don't block commands Edit Headline, Select Body Range if Body is not editable.
They don't modify Body. Edit Headline is useful as an alternative to Return.

ID_20120520092604
Significant change in voom.py in order to accommodate LaTeX mode. Levels of
Tree lines during Paste/Up/Down/Left/Right are now set according to VO.levels,
not levDelta as before. setLevTreeLines() replaced changeLevTreeHead(). This is
done after VO.levels is adjusted and after hook_doBodyAfterOop() is done. Thus,
hook_doBodyAfterOop() can correct disallowed levels by modifying items in
VO.levels: fixed elements at level >1, maximum level exceeded. The Tree is then
constructed with correct levels and will pass verification.


v4.3, 2012-05-06   [[[3~

PROBLEM: The Voom command cannot handle buffer names containing %, #, etc.
Session restore is also affected.
Whitespace in names is also a problem on some systems (Jonathan Reeve).
SOLUTION: Do fnameescape() when :edit, :file, :tabnew, etc.

Added |voom-mode-hashes|.


v4.2, 2012-04-04   [[[3~

New commands for quitting and toggling outline window (|voom-quit|):
"q", VoomToggle, Voomtoggle, Voomquit, VoomQuitAll.
    https://github.com/vim-voom/vim-voom.github.com/issues/2

New Tree mappings ^^ (Move Up) and __ (Move Down) for symmetry with << and >>.

Added support for "fmr" modes (|voom-mode-fmr|). Modes fmr, fmr1, fmr2.

New options |g:voom_ft_modes|, |g:voom_default_mode| allow automatic selection
of markup mode according to filetype of the source buffer.

Improved asciidoc mode: there can be any number of preceding [] or [[]] lines
and in any order; blank line is not required before the topmost [] or [[]].

:Voomexec now executes Python scripts via "exec" instead of execfile(). Temp
file plugin/voom/_voomScript_.py is no longer created and should be deleted.
Python traceback's lnums match buffer lnums.
The "end of script" message shows script's start/end lnums.


Vim code
--------
Replaced Voom_GetBodyLines1() with more useful functions.

Voomexec fix: execute Vim scripts in a separate function Voom_ExecVim() to
avoid potential interference with Voom_Exec() local vars.
Python scripts still have access to Voom_Exec() vars. No big deal, unlikely to
cause any problems. Demo:
### :Voomexec py [[[
vim.command("echo [bufType,body,bln1,bln2]")
print vim.eval("[bufType,body,bln1,bln2]")
### ]]]


Python code
-----------
Mode-specific functions, such as makeOutline(), are now VO methods set during
outline init. Thus got rid of incessant getattr(VO.mmode,...) during outline
updates and outline operations. It's now easier to control what modes can do.

Split makeOutline() into makeOutline() and makeOutlineH() for efficiency sake.
(If needed, the old makeOutline() function can be in a fmr mode.)

Added check for clipboard size in setClipboard() to guard against failures with
very large clipboards.

Get &enc during outline init (VO.enc) instead of during markup mode imports.
Otherwise, it's impossible to change &enc without reloading everything.


v4.1, 2011-11-27   [[[3~

PROBLEM: Tree mappings J/K are supposed to accept a count, but they don't.
This is with Vim 7.3.145. No problem with Vim 7.2.
SOLUTION: Save original v:count1 before
    exe 'normal...
in Voom_Tree_KJUD().

Better argument completion for the :Voom command. The list of modes is
constructed from file names voom_mode_{whatever}.py in ../plugin/voom .


v4.0, 2011-11-06   [[[3~

New markup modes: asciidoc, org (same as old viki), cwiki.
Viki mode now ignores special regions.

New Tree mapping: "R" selects corresponding Body range.

Tweaked Markdown mode.

Fix in viki/org mode: level changing outline operations converted any
whitespace after * into space.

Fixed Tree syntax hi to avoid false hi after "|" inside of headline text.
Example: part after # is not comment >
    = . . |<<test link||#test>>

ID_20111006013436
Improved function Insert Node: use getbufvar(body,"changedtick") if
has("patch105"). This saves one trip to Body and back when checking for ticks.
Code for timing, execute from Tree, the Body is empty: >
    let tree = bufnr('')
    let start = reltime()
    for i in range(1,100)
        call Voom_OopInsert('')
        call Voom_ToTree(tree)
    endfor
    echo reltimestr(reltime(start))
    unlet tree start
0.71 sec vs 1.10-1.13 sec with the old code or if there is no patch.
It seems there are no other functions that would benefit from this.
Note: when check for ticks via getbufvar() fails, the next step should be to
move cursor into Body buffer--it may no longer exist, unloaded, etc.


v4.0b5, 2011-03-24   [[[3~

New markup mode: txt2tags.

Added support for Vim Sessions (:mksession) via BufFilePost autocmd for VOOM
Tree buffers and __PyLog__ buffers.

Fixed bug in :Voomexec -- Python script file encoding was set incorrectly.
Source code encoding of the temp script file should be Vim internal encoding,
not &fenc or &enc.

Fixed command Edit Headline (iIaA): cursor was not positioned on the first word
char in Body headline when there are was no foldmarker (markup modes).

Dealing with Python errors during outline update.
-------------------------------------------------
Working in the python mode revealed a flaw in safeguards against Python errors
during outline update. Such errors are expected while in python mode --
tokenize.py raises exception when indentation is wrong or a quote is missing.

    id_20110213212708 , also see #id_20110213225841
Calling voom.updateTree() via try/python.../finally/endtry in the Vim code
(|try-finally|) does not guard against Python errors when PyLog is on. It looks
like Vim error is not triggered when Python's sys.stderr is redirected. The
result is that changedtick (tick_) is updated despite a failed update.
SOLUTION: always set Vim var l:ok in voom.updateTree() before returning to
indicate a successful update.

Python mode: catch exceptions raised by tokenize.py, echo the error, set Tree
lines to make it clear that update has failed and outline is invalid.

Refactoring
-----------
Insert New Headline -- don't need Body column, just search for "NewHeadline".
voom.newHeadline(), hook_newHeadline() no longer return column.

Voom_LogScroll() -- several optimizations. PyLog is usually only in the current
tabpage. Thus, check tabpagenr() before tabnext--faster than redundant tabnext.


v4.0b4, 2011-01-30   [[[3~
New Tree mappings for navigating outline:
    P (go to parent node),
    c (go to parent and contract it),
    C (contract siblings or everything in Visual selection),
    o (go to first child),
    O (expand siblings or everything in Visual selection),
    K/J/U/D (go to previous/next/uppermost/downmost sibling),
    s (show headline text), S (show UNL).

    id_20110121201243
PROBLEM: Longstanding annoyance with some Tree mappings. Example: hit "d"
(disabled by mapping to <Nop>), wait a few seconds, hit "dd" (cut node) --
there is no response. Can be very confusing.
SOLUTION: disable "d" and similar by mapping them to <Esc> instead of <Nop>.
Another option is to map them to 0f| .

Disabled more text changing keys in Tree: < > <Ctrl-x> etc.

PROBLEM: User placed VOoM package in ~/.vim/plugin. Everything gets loaded on
Vim startup (|load-plugins|). Add-on custom_headlines.vim causes error because
it must  be loaded only after voom.vim has been sourced completely.
SOLUTION: finish loading custom_headlines.vim if !exists('*Voom_Exec').

PROBLEM: Command :Voomhelp does not reuse existing voom.txt windows if current
buffer is not voom.txt or its Tree.
SOLUTION: Start by searching all tabs for voom.txt window.

    id_20110120011733
PROBLEM: Outline has only level 1 headlines and there is a stray "o" mark.
vim.error in voom.foldingCreate() on startup after :Voom.
E490: No fold found, triggered by initial :foldopen, because Tree has no folds.
SOLUTION: Catch E490 when doing :foldopen in foldingCreate().
Note1: must execute :foldopen even when cFolds list is empty.
Note2: cFolds (lnums of closed folds) never contains nodes without children.
This means "zc" will not trigger E490 error. Unless Tree folding is messed up
or lost, e.g., because fdm was reset.

    id_20110125210844
Fixed glitches with initial cursor positioning in Tree when markup mode is
used. snLn can be >1 when markup mode is used or when there is no startup node
(Body cursor on >1 node).
Create jumps marks when outline is created: line 1 and selected node.
Initial gg restores view after jumping around when creating folds.

Added "keepj" when jumping around Tree and Body via G or gg.
No jump marks are created in Tree or Body during node navigation or manipulation.


Vim code for outline navigation   id_20110116213809
---------------------------------------------------
Made Voom_TreeLeft() much faster with large outlines.
The final step (go to parent) used this inefficient code: >
    let ind = stridx(getline('.'),'|')
    let indp = ind
    while indp>=ind
        normal! k
        let indp = stridx(getline('.'),'|')
    endwhile
It is much faster to call search() to find line with required indent of |.
Multibyte chars should not be a problem because there are never any before |.
Timing: 5876 childless siblings, cursor on the last.
Old code: 0.28 sec.  New code: 0.01 sec.

Voom_TreeToSiblings(), etc: also use search() to locate parents/siblings.
virtcol() ensures multibyte chars before | will never be a problem.

Simplified Voom_TreeSelect(lnum, focus) signature. No need for lnum, it's
always current line. focus is 1 (stay in Tree) or 0.

Got rid of Voom_TreePlaceCursor(), just do
    call cursor(0,stridx(getline('.'),'|')+1)
        or
    normal! 0f|


v4.0b3, 2011-01-04   [[[3~

New markup mode: markdown.

Fixed severe bug in reST mode. Paste and level-changing outline operations were
affected. One manifestation: when pasting into an empty outline all headlines
become level 1.

The command :VoomSort now accepts a line range in front of it. If a range is
not a single line, siblings in the range are sorted.

Changed how some outline operations handle the first Tree line (outline title):
    - VoomSort now aborts if the first Tree line is selected. This is to be
      consistent with other outline operations (Cut, Copy, Move) which also
      require a valid range.
    - Print error message when an operation is aborted because the first Tree
      line is selected (Cut, Copy, Move, Sort).
    - Mark Node as Startup is allowed: remove "=" marks from all headlines.

Mode viki: allow any whitespace after last leading *, not just space.

Outline operation Copy: do not display error message complaining about Body
buffer being nomodifiable or readonly.

Code refactoring
----------------

s:voom_logbnr now always exists. It is 0 if there is no Log buffer.

New helper function Voom_GetVar(var) -- allows external scripts to read any
"voom.vim" script-local variable such as s:voom_logbnr.

:Voomexec -- improved printing of errors. When PyLog is not enabled,
Python traceback is echoed as Vim error message. See
    ../autoload/voom/voom.py#id_20101214100357

Assign VO.marker and VO.marker_re to MARKER and MARKER_RE instead of 0 when
foldmarker is default.  MARKER_RE object is reused, so this is still efficient.
This eliminated the need for silly code
    marker = VO.marker or MARKER
    marker_re = VO.marker_re or MARKER_RE
    
------------------------------------------------------------------------------
v4.0b2, 2010-10-24   [[[3~

New markup modes: rest (reStructuredText), python, thevimoutliner, vimoutliner.

Changed default for g:voom_verify_oop to 1 (enabled). We need this to detect
inherent problems with "python" and "rest" modes, to debug other modes. Outline
verification is performed by new function Voom_OopVerify(). It forces outline
update if verification fails.

Option g:voom_rstrip_chars (dictionary) has been removed. Instead, there are
options g:voom_rstrip_chars_{filetype} (strings) for each Body filetype of
interest. REASON: it's easier to define a string for one filetype than to mess
with a dictionary that has settings for a bunch of other filetypes.

Command VoomSort now checks that the number of headlines is not changed after
sorting (after Tree update on BufEnter). When using modes "rest" or "python"
sorting can make some headlines cease to be headlines.

Added argument completion for command :Voom.

Added special syntax hi in Tree when Body's filetype is vim or python.
See Voom_TreeSyntax().

Python code refactoring:
    - Name VOOMS is no longer defined in Vim module namespace. It is available
      only as voom.VOOMS.
    - Changed argument "body" in many functions like makeOutline() to "VO".
      This makes more sense since "VO" is what we need. Makes it easier to
      write markup modes and add-ons -- no need to look up VO in voom.VOOMS.
    - Refactored oops Cut, Paste, Up, Down, Left, Right to accomodate modes
      like "python" and "rest".  The new sequence of actions is:
        - modify Body lines (move);
        - update VO.bnodes; update VO.levels;
        - call hook_doBodyAfterOop() to finish updating Body lines -- change
          indentation, headline adornment styles, etc;
        - go back to Tree; update Tree lines.


'noautocmd' troubles   [[[4~
Testing thevimoutliner mode with TVO plugin installed revealed serious flaw in
node selection functions -- they screw up TVO's BufEnter and BufLeave autocmds
that disable/enable TVO's menu. There are errors about missing menu, etc.

The culprit is "noautocmd" in Voom_TreeSelect() and Voom_BodySelect().

Same problem with VoomSort.

All outline operations use "noautocmd" when cycling between Body and Tree. This
can also cause problems -- if outline operation fails the cursor stuck in Body.

SOLUTION: do not use "noautocmd".

The original reason for "noautocmds" was to increase performance by disabling
autocmds when temporarily visiting Tree or Body window -- a frequent action,
e.g., when selecting nodes. The performance gain is usually minuscule and is
not worth the risk of screwing up autocommands created by other plugins.

There is also problem with Tree BufUnload au -- it must be "nested" to trigger
BufEnter, etc. after Tree is wiped out, and we cannot use "noautocmd" when
wiping out Tree. But without "noautocmd" we get recursive call. 
SOLUTION: first delete Tree autocommands, then wipe out Tree without using
"noautocmd".
This change was made in Voom_TreeBufUnload() and Voom_UnVoom()
Same change was made in Log BufUnload au: made it nested, delete Log au before
wiping out Log.

"noautocmds" is now used only in Voom_LogScroll() for performance sake.
It's very unlikely that something will go wrong there.

------------------------------------------------------------------------------
v4.0b1, 2010-09-21   [[[3~

Added support for headline markups other than start fold markers with levels:
|voom-markup-modes|. Available markup modes: wiki, vimwiki, viki, html.

Changed plugin directory structure: all Python files are now located in folder
plugin/voom.

Changed how global outline data are stored.
Old scheme: class VOOM has a bunch of dictionaries as attribs. Keys are Body
bufnr. Data for one outline:
    bnodes, levels = VOOM.bnodes[body], VOOM.levels[body]
New scheme: there is instance of class VoomOutline for each Body, attribs are
outline properties. These instances are stored in global dict VOOMS, keys are
Body bufnr.
	VO = VOOMS[body]
    bnodes, levels = VO.bnodes, VO.levels

PROBLEM introduced since setting Tree's "bufhidden" to "wipe".
Tabpage has two windows, Tree and Body. Load another buffer in Body window and
create outline.  What is left is one window with new Tree.
FIX: Voom_ToTreeWin(), when re-using another Tree window: split it if current
tabpage has no other windows with this Tree buffer. This actually makes sense
regardless of Tree "bufhidden".

------------------------------------------------------------------------------
v3.0, 2010-08-01   [[[3~

New command :VoomSort [options] for sorting outline, |voom-sort|.

Tree buffer is no longer automatically wiped out when its Body buffer is
unloaded, deleted, or wiped out. Instead, outline is locked until Body is
loaded again. This change was needed to eliminate crashes after :q, :q! and
related problems. This can also make working with outlines easier when buffers
routinely get unloaded, as when 'hidden' and 'bufhidden' are not set.

Option 'bufhidden' for Tree buffers is set to "wipe" instead of "hide".
This should make it less likely that an orphan Tree is hanging around long
after its Body is gone.

PyLog buffer has 'bufhidden' set to "wipe" instead of "hide".
PyLog filetype is set to "voomlog" instead of "log".
PyLog syntax: better highlighting of Python tracebacks.

In several places in voom.py a new list of Body lines was created for no good
reason: VOOM.buffers[body][:]. These were changed to VOOM.buffers[body], which
is Vim buffer object. This substantially reduces memory usage, especially when
working with large buffers. This affects outline update. Timing tests with
calendar_outline.txt: makeOutline() is slower (0.15 vs 0.11 sec). But the
overall time to run update on Tree BufEnter is about the same (0.16 sec if no
outline change), so it's definitely worth it.
Similarly, there is no need to create a new list of current Tree lines in
updateTree() (tlines_ = Tree[:]) since we compare Tree lines one by one.

PROBLEM: Tree window-local settings can be wrong if new window is created
manually.  Example: cursor is in Body, :split, :b[Tree bufnr].
FIX: On Tree BufEnter check if w:voom_tree exists. If not, call
Voom_TreeConfigWin()--it sets window-local options and creates w:voom_tree.

Added "vim" filetype to default g:voom_rstrip_chars: # is stripped in addition
to " because it's comment char in Python etc. sections of .vim files.

    Various code changes

Renamed VOOM.nodes to VOOM.bnodes to make clearer it is list of Body lnums.

voom.py functions no longer access voom.vim script-local variables directly.
This means all voom.py functions can be called from add-ons.
Some functions used to compute tree from body like this
    tree = int(vim.eval('s:voom_bodies[%s].tree' %body))
These now  require both body and tree as arguments. (updateTree, verifyTree,
nodeUNL)
In several places snLn was set:
    vim.command('let s:voom_bodies[%s].snLn=%s' %(body, snLn))
These now call Voom_SetSnLn(body,snLn) instead.

When converting buffer lines to/from Python Unicode objects encoding is set to
"utf-8" if &encoding is any Unicode encoding. It turns out Vim uses utf-8
internally in such cases. See voom.getVimEnc()

Vim code changes due to new scheme of dealing with unloaded and deleted Body
buffers. Body BufUnload au is gone. New Body BufEnter au detects loss of
buffer-local mappings.

Tree autocmds are now buffer-local. This seems more robust than relying on Tree
name pattern, easier to disable for individual Trees should we need to do so.
s:voom_TreeBufEnter is not needed anymore.

Got rid of b:voom_tree and b:voom_body. Use hasmapto('Voom_ToTreeOrBodyWin') to
detect loss of buffer-local mappings.


crash after :q, :q!   [[[4  ~

(reported by William Fugy)
Current tabpage has two windows: Body and corresponding Tree.
There are no other windows with Body or Tree.
'hidden' is off, Body 'bufhidden' is "".
With cursor in Body, :q or :q! produce spectacular crash--sometimes gvim.exe
crashes, sometimes stream of E315 errors.
-------------------------------------------------
The culprit is Body BufUnload autocmd: it wipes out Tree buffer and thus can
close windows and tabs. This confuses :q but not :bun :bd :bw.

Setting hidden or bufhidden doesn't help because :q! always unloads buffer.

Kludge attempt in Body BufUnload, before Tree wipeout: 
    if winnr('$')==2 && bufwinnr(body)>0 && bufwinnr(tree)>0
        new
    endif
No crashes after :q or q!. New crash after :bd, :bw in Body.
Creating new window on BufUnload is as dangerous as closing one.

Not wiping out Tree on Body BufUnload is the only solution.
-------------------------------------------------
Got rid of Body BufUnload au.
Try Body BufWipeout au -- wipe out Tree when Body is wiped out.

Crash after :q still happens if Body 'bufhidden' is "wipe" -- obviously same
situation as with BufUnload. Such setting seems unlikely. :Voom can refuse to
create outline if current buffer has such setting.

ANOTHER NASTY GLITCH:
gvim.exe test_outline.txt
:Voom
:bw1
Tree is gone, window still shows test_outline.txt -- this is horribly wrong.
:Voom
Both Body and Tree are empty.

**CONCLUSION: DON'T DO IT**
The workaround is function Voom_Delete('ex_command') to be used in custom
mappings.
Also, set Tree 'bufhidden' to wipe instead of hide.

-------------------------
Possible Body BufWipeout au, should be safe:
if Tree is shown in a window: set Tree bufhidden to wipe
if not: wipe out Tree
This is too convoluted.


Tree folds are wrong in split windows after outline operation   [[[4~

gvim.exe test_outline.txt
:Voom
:set fdc=6
:split
:split
Copy node "5", Paste after "5.2"
Folds are wrong in 2nd and 3rd window.

Also affects Tree windows in other tabs.
Folds in the current window are fixed after :setl fdm=expr
--------------------------
Sorting is not afflicted with this bug.
Sorting is different from other Oops--Tree is drawn while in Tree, on BufEnter.
Change 
    call Voom_OopFromBody(body,tree,l:blnShow,'')
to 
    if Voom_BodyUpdateTree()==-1 | let &lz=lz_ | return | endif
    call Voom_OopFromBody(body,tree,l:blnShow,'noa')
and folds are wrong in split windows
--------------------------
Thus, the fix is to draw Tree lines while in Tree.

Current Oop scheme for most Oops, start in Tree, Vim code:
    perform checks, get data
    go to Body
    check ticks
    run Python code:
        change Body lines; change Tree lines; adjust bnodes and levels
    call Voom_OopFromBody() -- adjust Body view and go back to Tree
    adjust Tree view

New Oop scheme, start in Tree, Vim code:
    perform checks, get data
    go to Body
    check ticks
    run Python code:
        change Body lines; (adjust bnodes and levels)
        call Voom_OopFromBody() -- adjust Body view and go back to Tree
        change Tree lines; (adjust bnodes and levels)
    adjust Tree view

Changed the following Oops: Paste, Cut, Up, Down, Right, Left.

These Oops do not change Tree folds: Mark/Unmark, Mark as selected
No change is needed for: Insert new node (done from Tree), Copy.
Save/Restore/Cleanup Folding do not modify Tree, they are done from Tree.
--------------------------
Folds can also be wrong in split Tree windows after outline update was forced
from Body after :Voomgrep, :Voomunl, etc. This is rare and no big deal.


v2.1, 2010-06-01   [[[3~

The procedure for constructing Tree headline text was modifed to permit
customization for individual filetypes:
    - Comment chars that are stripped from the right side of Tree headlines
      are by default obtained from Body's 'commentstring' option.
    - User dictionary g:voom_rstrip_chars can be used to control exactly which
      characters are stripped from the right side of Tree headlines. This is
      done for individual filetypes and will overide 'commentstring' option.
    - Finally, an arbitrary headline constructing function can be defined for
      individual filetypes in an add-on. Add-on "custom_headlines.vim" shows
      how.
For details, see node
    OUTLINING (:Voom) -> Create Outline -> Tree Headline Text

New user option "g:voom_create_devel_commands" controls if development helper
commands are created. They are commented out in previous versions.

Removed <F1> Tree-local mapping (same as :Voomhelp).

Bug in PyLog buffer creation/destruction: Python original sys.stdout and
sys.stderr can be lost after some actions, e.g. after command :VoomReloadAll.
FIX: changed how original sys.stdout and sys.stderr are saved.


v2.0, 2010-04-01   [[[3~

The name of this plugin was changed from VOOF (Vim Outliner Of Folds) to VOoM
(Vim Outliner of Markers):
    - The new name is more accurate. It deemphasizes the role of folds. Body
      buffer folding has no effect on outline construction or on outline
      operations. Markers are determined by option "foldmarker", but only
      start fold markers with levels are used.
    - Voom sounds better than Voof, more energetic -- vroom-zoom-boom.
      (Look matey, this parrot wouldn't "voom" if I put four thousand volts
      through it.)

Corresponding changes were made in file names, commands, user options, help
tags, names of functions and variables. All occurrences of VOOF/Voof/voof were
changed to VOOM/Voom/voom: the command "Voof" became "Voom",
"g:voof_tree_placement" became "g:voom_tree_placement", and so on.

If you are upgrading from previous versions, please delete old "voof" files
(voof.vim, voof.py, voof.pyc, voof.txt), delete file "voofScript.py" if any,
edit user options in .vimrc if you have any, run :helptags.

Added rudimentary support for add-ons, sample add-on "voom_info.vim". See node
    Implementation notes -> Extending VOoM with add-ons
for details.

Added instructions for Windows users on how to get Python-enabled Vim.

Renamed some functions. Other minor code style changes.

There is an elusive bug in mouse left click Tree mapping. It seems it's
possible for <LeftRelease> to be triggered in a wrong buffer. Cannot
reproduce, has something to do with resizing windows.
FIX: added check that current buffer is Tree in Voom_TreeMouseClick().


v1.92, 2010-03-03   [[[3~

PROBLEM: outline operations Mark/Unmark, Move Right/Left can be slow when they
involve a large number of folds.
EXAMPLE: mark/unmark all nodes in calendar_outline.txt takes about 3 seconds.
But set Body foldmethod to "manual" and the time is reduced to 0.85 seconds.
Set Tree foldmethod to "manual" and the time is reduced further to 0.16 sec.
FIX: Set Tree and Body foldmethod to "manual" during Mark/Unmark. Set Body
foldmethod to manual during Move Right/Left. Other operations are not
susceptible.

Command :VoofFoldingSave is now much faster when applied to huge and deeply
nested branches with lots of closed folds. The problem was recursive function
foldingGet(). Got rid of recursion -- unnecessary and inefficient.
foldingGet() and foldingGetAll() were merged into foldingGet().

If Body "foldmethod" is not "marker", Body node could be hidden in fold after
selecting node.
FIX: do "zv" in Body after: selecting node in Tree, outline operations, on
startup. In other words, if foldmethod is marker, do "zMzvzt" to show selected
Body node. Otherwise do "zvzt".

Fixed stupid code in Voof_ToTreeOrBodyWin(), which is the <Tab> command -- no
need to visit all windows to find the target. It was causing confusion when
working with split windows.

Code tweaks to save precious microseconds:
voof.vim
    - Use stridx(line,'|') instead of match(line,'|') in various Tree
      functions, including foldexpr.
    - Compacted and simplified Tree foldexpr function.
voof.py
    - xrange() is now used in many places instead of other iteration methods.
    - Cleaned up some code, especially for outline operations.


v1.91, 2010-02-06   [[[3~
Command :Voofgrep can now perform boolean AND and NOT searches.

Increased maximum number of matches when doing Voofgrep to 10000 from 1000.

Annoyance: when outline is created, there can be unnecessary scrolling down in
the Tree window.
Fix: Voof_TreeCreate() code that puts cursor on startup node. Do "gg" before
jumping to startup node to counteract scrolling caused by fiddling with folds.
Don't do "zz" if the first or the last Tree line is in the window.

There were some "normal" in voof.vim. Changed all to "normal!".


v1.9, 2009-12-19   [[[3~
It's now possible to save and restore Tree buffer folding. This feature uses
special node marks "o" in Body headlines. See |voof_VoofFoldingSave|.

New Tree mapping: + (Shift-=) finds startup node, if any, that is  node marked
with "=" in Body headline. Warns if there are several such nodes.

Command "Voofrun" was renamed "Voofexec".

Tree mapping for Execute Script was changed to "<LocalLeader>e" from
"<LocalLeader>r", which was in conflict with mapping for "Move Right".

Executing Python code via Voofexec: source code encoding is now specified on
the first line of script file as per http://www.python.org/dev/peps/pep-0263/.
Encoding is obtained from Body's 'fenc' or, if it's empty, from 'enc'.

Fixed bug in Voofexec: unsupported script type argument was ignored if
buffer's filetype was a supported script type. More informative message if
script type is unsupported.

Improved how the command Edit Headline (iIaA) positions cursor in Body
headline: "\<" is used instead of "\w" to find the first word char. This works
better with unicode.

"g:voof_tree_hight" and "g:voof_log_hight" were renamed "g:voof_tree_height"
and "g:voof_log_height" respectively.


v1.8, 2009-09-18   [[[3~
Bug in Normal mode mappings: nasty errors when attempting to use mapping with
a count, which is not supported, e.g., 3<Return>.
Fix: made all mappings start with ":<C-u>" to clear command line before
calling a function.

Added highlighting of warning and error messages.

Added fancy highlighting of Voofunl output: different highlights for headlines
and separators.

Correction in docs: <Tab>/CTRL-I is Vim default key for going forward in the
jumps list.

Distribution now follows Vim directory structure: there are /plugin and /doc
folders. Simplified Voofhelp accordingly: if voof.vim is in dir a/b, voof.txt
is assumed to be in a/doc.

Changed license to WTFPL, version 2.

v1.7, 2009-08-31   [[[3~
Checks that previously checked that Body or Tree buffer exists now check if
the buffer is loaded (bufloaded()). This is needed because bad things happen
when writing to an unloaded buffer via Python's vim.buffer.
See "Implementation notes -> unloaded buffer + python == trouble"

When killing Trees and PyLog do "bwipeout" instead of "bwipeout!" -- it's
sufficient and safer.

Adjusted how new Tree window is opened: previous window (^wp) is used if it
shows a Tree buffer.

PyLog:
Added fail-safe check that ensures PyLog buffer is loaded before being written
to. This can be tested by unloading PyLog with "noa bun" or "noa bd" and then
printing to it: py print "something".
Added workaround for a glitch with the output of help().
Made voof_logbnr variable script-local.

v1.6, 2009-08-23   [[[3~
Added checks to prevent data corruption when outline update fails for any
reason. When these checks fail, the Tree buffer is wiped out and outline data
are cleaned up. These checks can be tested as follows:
    - Create outline with the Voof command.
    - Delete some lines in Body buffer.
    - Move to Tree buffer with
      :noa wincmd w
    - Tree update did not happen and outline data are out of sync with the
      Body. In previous versions, performing outline operation at this stage
      would cause data corruption.
    - Select new node or try outline operation. Voof will issue error message,
      wipe out Tree buffer, and perform clean up.
Another way to test these checks is to modify Body file with an external
application while cursor is in the Tree window.
There is more details in "Implementation notes -> Checking Bodies for ticks".

Added some other foolproofing measures.

Improved automatic scrolling of PyLog buffer. Both previous (^wp) and current
window numbers are preserved in tabpages where PyLog is scrolled. Previously,
only current window number was preserved.

Fixed some bugs. Streamlined some code.

v1.5, 2009-08-15   [[[3~
New commands: Voofgrep, Voofunl.

Fixed blunder in "Move Down" outline operation that could cause outline
corruption. To find node after which to move, the cursor must be put on the
last node of the branch. That was done in Visual mode, but not in Normal mode.

<Return> and <Tab> in Tree buffers now also work in Visual mode.

Changed behavior of <Tab>: move cursor to Body window if current window is
Tree and vice versa. Previous behavior (cycle through all Body and Tree
windows) was less useful and inconsistent with <Return> behavior.

Added checks for Body foldmethod. If it's not "marker":
 - folds in Body are not collapsed (zMzv) after node selection in Tree and
   after outline operations;
 - Voofrun will refuse to run when executed while in Body buffer.

Made Tree buffers and PyLog buffer unlisted.

If possible, :Voofhelp command will open voof.txt via "tab help voof.txt"
command, so that tags will be active.

Made help tags start with "voof_".

Edited "Why VOoF uses Python": it turns out there is a fast, pure Vim method
to scan for headlines, but it's much less convenient than the Python way: >
    let headlines=[]
    g/{{{\d\+/ call add(headlines, getline('.'))       "}}}

code improvements [[[4~
The way "eventignore" was used to temporarily disable autocommands was unsafe.
"eventignore" is no longer set anywhere. "noautocmd" is used instead:
|autocmd-disable|.

Modified voof.voofUpdate() (formally treeUpdate) to work from any buffer as
long as the Tree is "ma". Voof_TreeBufEnter() now calls voof.voofUpdate()
directly.  Voof_BodyUpdateTree() updates Tree while in Body without moving to
Tree. This is extremely useful--can now use outline data while in Body.

Optimization in voof.voofOutline() parser function: >
    if not marker in line: continue
This makes sense because search with marker regexp is 3-4 times slower than
the above membership test, and in a typical outline most lines don't have
markers. Timing voof.voofUpdate() in Voof_TreeBufEnter(),
"calendar_outline.txt" update when headlines unchanged:
0.17 sec instead of 0.24 sec.

Changed Vim data variables voof_bodies, voof_trees, etc. from global to
script-local. Command VoofPrintData prints these for debugging purposes.
Should external scripts need to read these, a function that returns these
could be provided.

voof.computeSnLn() uses bisect--should be faster than previous naive code.

Changed <f-args> in Voofrun to <q-args> -- simpler.

PyLog code is, hopefully, near the state of perfection: when something goes
wrong, the exception info is displayed no matter what.

voof.oopMarkSelected() -- don't remove just one =, strip all consecutive

Voof_GetLines() uses winsaveview()/winrestview() to prevent scrolling after
zc/zo.

Use setreg() to restore registers exactly as shown in help.
Doing "let @z=z_old" is not reliable enough--register mode can change.


v1.4, 2009-07-12   [[[3~
New Tree navigation commands (Normal mode):
 x   Go to next marked node (mnemonic: find headline marked with "x").
 X   Go to previous marked node.

"Unmark Node" operation now removes all consecutive "x" chars from Body
headline instead of just one. This eliminates confusion when a bunch of "x" is
present after start fold marker level number. For the same reason, "Mark Node
as Selected" (<LocalLeader>=) now strips "x" chars after removed "=" char.

Bug: When Body starts with a headline, click on the first line in Tree (path
info line) doesn't select first node.
Fix: in Python code of Voof_TreeSelect() replaced
 nodeEnd =  VOOF.nodes[body][lnum]-1
   with
 nodeEnd =  VOOF.nodes[body][lnum]-1 or 1

Fixed errors in LogBufferClass write() method, printing messages when log
buffer doesn't exist.

Bug: Select more than one lines in Tree and press i/I/A/a. An error in
Voof_OopEdit() occurs.
Fix: Mapped i/I/A/a keys only for Normal mode with nnoremap. They were
mistakenly mapped with noremap.

A message is now printed when an outline operation is aborted because Body
buffer is readonly or nomodifiable.

Replaced most Python regions in voof.vim with voof.py functions.

Renamed some Python functions:
voof_WhatEver() means it's Python code for Voof_WhatEver() Vim function.

Voof_FoldLines() renamed Voof_GetLines().
Voof_FoldRun() renamed Voof_Run().

Various edits and additions in voof.txt.


v1.3, 2009-06-06   [[[3~
New: start fold marker string is obtained from Vim option 'foldmarker' when
the Voof command is run. Each Body buffer can have its own start fold marker.

Replaced Body's BufDelete autocommand with BufUnload autocommand. Tree buffer
is now wiped out when its Body is unloaded, deleted or wiped out. Corrected
Body and Tree BufUnload au functions: use "nested" and "noautocmd".

Added * to chars being stripped during headline construction to allow /**/
around fold markers. Better syntax highlight for commented headlines in Tree.

Changed how Tree buffer name is constructed: {bufname}_VOOF{bufnr} instead of
VOOF_{bufname}_{bufnr}.

When checking if current buffer is a Tree, instead of checking buffer name, do
has_key(g:voof_trees, bufnr('')).

When eventignore is set, save and restore original eventignore instead of
doing "set eventignore=" .

Annoyance: Moving Tree window to top/bottom (^W K/J) maximizes window height.
Fix: Don't set "winfixheight" when creating Tree window. I don't understand why
this happens. There is no such problem with "winfixwidth".

Got rid of Voof_ErrorMsg() and Voof_InfoMsg().

Expanded help file.

v1.2, 2009-05-30   [[[3~
Bug: after outline operation cursor may be on the last line of range instead
of first (if Visual and there is only one root node).
Fix: tweaked Voof_OopShowTree().

Re-wrote Voof_TreeToggleFold() to handle: no fold at cursor; cursor hidden in
fold.

Allow outline operation Copy when Body is noma or ro.

v1.1, 2009-05-26   [[[3~
Bug fix involving nomodifiable and readonly buffers.
Outline operations now silently abort if Body is noma or ro.

v1.0, 2009-05-25   [[[3~
Initial release.

==============================================================================
modelines   [[[1~
 vim:fdm=marker:fmr=[[[,]]]:ft=help:ai:et:noma:ro:
 vim:foldtext=getline(v\:foldstart).'...'.(v\:foldend-v\:foldstart):
