*voom.txt* VOoM -- two-pane outliner plugin for Python-enabled Vim Last Modified: 2017-03-05 Version: 5.3 Description: VOoM -- two-pane outliner plugin for Python-enabled Vim 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 [MarkupMode]) ..............|voom-Voom| Markup Modes ............................|voom-markup-modes| fmr (Default Markup Mode) ...........|voom-mode-fmr| fmr1, fmr2, fmr3 ....................|voom-mode-fmr1| wiki ................................|voom-mode-wiki| vimwiki .............................|voom-mode-vimwiki| viki ................................|voom-mode-viki| cwiki................................|voom-mode-cwiki| 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| latexDtx ............................|voom-mode-latexDtx| dokuwiki ............................|voom-mode-dokuwiki| inverseAtx ..........................|voom-mode-inverseAtx| html ................................|voom-mode-html| thevimoutliner ......................|voom-mode-thevimoutliner| vimoutliner .........................|voom-mode-vimoutliner| taskpaper ...........................|voom-mode-taskpaper| python ..............................|voom-mode-python| paragraphBlank ......................|voom-mode-paragraphBlank| paragraphIndent .....................|voom-mode-paragraphIndent| paragraphNoIndent ...................|voom-mode-paragraphNoIndent| EXECUTING NODES (:Voomexec) .................|voom-Voomexec| __PyLog__ BUFFER (:Voomlog) .................|voom-Voomlog| Add-ons .....................................|voom-addons| Known Issues ................................|voom-issues| Changelog ...................................|voom-changelog| ============================================================================== 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 GitHub mirror: https://github.com/vim-voom/VOoM Screenshots and an animation: https://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 For a quick introduction to VOoM outlining, see |voom-quickstart|. For a concise list of all VOoM commands (cheat sheet), see |voom-map|. VOoM was originally written to work with start fold markers with level numbers, such as in this help file (|fold-marker|). This is the most versatile outline markup -- it is suitable for organizing all kinds of files, including the source code, and it allows features not possible with other markups. (Markers are specified by option 'foldmarker'. End fold markers with levels are not supported.) VOoM can currently handle >20 markup formats that have headlines and support an outline structure, including popular lightweight markup languages such as reST, Markdown, Pandoc, AsciiDoc, Org-mode, Wiki, LaTeX, etc. (Headlines are also called headings, headers, section headers, titles.) See TOC at the start of this file for available markup modes. 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). + 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} Create outline of the current buffer. The current buffer is scanned for headlines. Headlines are displayed in the outline pane (Tree buffer). The format of headlines is specified by {MarkupMode}. See TOC above for available markup modes. There is argument completion: type ":Voom " and press or to see all installed markup modes. 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, randomized, etc. See OUTLINING (|voom-Voom|) for details. :Voom Use the default markup mode, which by default is "fmr" mode: headlines are lines with a start fold marker (specified by Vim option 'foldmarker') followed by a level number, that is {{{1, {{{2, {{{3, etc. Headline's level is the number after the marker. Headline's text is the part before the marker. See |voom-mode-fmr|. *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 NODES (|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. ============================================================================== Requirements [[[1~ *voom-requirements* VOoM needs Vim or gVim version >=7.2 compiled with "Normal" or bigger feature set and the Python interface. Both Python 2 and Python 3 are supported. To check if Vim has Python 2 support: > :py print 2**0.5 :py import sys; print sys.version To check if Vim has Python 3 support: > :py3 print(2**0.5) :py3 import sys; print(sys.version) By default VOoM will use the first available Python version: Python 2 is tried first, Python 3 is tried next. To always use Python 2, add to .vimrc: > let g:voom_python_versions = [2] To always use Python 3, add to .vimrc: > let g:voom_python_versions = [3] To first try Python 3, then Python 2, add to .vimrc: > let g:voom_python_versions = [3,2] To see which Python version is currently in use, run command ":Voominfo [all]". ============================================================================== 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) To uninstall: all VOoM file and directory names start with "voom", so search for "voom" and delete, then update help tags. Alternatively, use Pathogen ( https://github.com/tpope/vim-pathogen ) and install VOoM as a bundle, or use a Vim plugin manager. NOTE: VOoM Python modules are in directory ../autoload/voom/voom_vimplugin2657/ which is a Python package. Python 2 will create *.pyc files there. Python 3 will create *.pyc files in subfolder __pycache__. It is advisable to delete .pyc files when installing another VOoM version. NOTE: VOoM has almost zero impact on Vim startup time because it uses the autoload mechanism (|autoload|). The bulk of its Vim script code is in ../autoload/voom.vim . It is sourced, and Python modules in ../autoload/voom/voom_vimplugin2657/ are imported only after a Voom command is executed for the first time. ============================================================================== Quick Start [[[1~ *voom-quickstart* This Quick Start guide demonstrates the most essential commands and principles of VOoM usage. For a concise list of all VOoM commands (cheat sheet) see |voom-map|. 1) CREATE OUTLINE (:Voom [markup]) ---------------------------------- To have something to practice with, create a new tab page (:tabnew) and paste the following lines: > Headline A {{{1 some text Headline B {{{2= more text Headline C {{{3 Headline D {{{1o Headline E {{{2x With cursor in the practice buffer, execute the command > :Voom It will scan the current buffer for headlines, create an outline from them, and display it in the 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 directly. Switch to Body buffer (CTRL-W w) and edit some headlines. Switch back to Tree buffer -- outline will be updated automatically. The outline is always updated automatically on entering the Tree buffer (via BufEnter autocmd). 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 all 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 headlines, the Tree buffer will contain only the title line. Delete the wrong outline by pressing "q". Create the correct outline again with the command ":Voom". By default, the command ":Voom" is identical to ":Voom fmr". It invokes the "fmr" mode (|voom-mode-fmr|): headlines are lines with {{{1, {{{2, etc. The actual start fold marker string is obtained from Vim option 'fmr' (window-local). Headline text is text before the marker. To work with 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 argument completion: type "Voom a" and press or . 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://github.com/jgm/pandoc/blob/master/MANUAL.txt Open it Vim and execute :Voom pandoc Download LaTeX source for "Think Python" by Allen Downey from https://github.com/AllenDowney/ThinkPython2/blob/master/book/book.tex Open it in Vim and execute :Voom latex 2) SWITCHING BETWEEN TREE AND BODY BUFFERS ( and ) --------------------------------------------------------------- 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 and keys. (To assign other keys, see |voom-shuttle-keys|.) (also known as or ) 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. simply cycles between Tree and Body windows without selecting new nodes. Exercise: - Make sure you are in Normal mode. Press a few times. Stop when you are in the Tree window. - Jump to the last line/node by pressing "G". - Press once. The corresponding (last) node will be shown in the Body window, but the cursor will stay in the Tree window. - Press again. The cursor will move to Body window. Subsequent presses of will shuttle the cursor between the Tree and Body. - See what happens after you move to different regions of the Body buffer and press a few times. and 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 commands, etc. Example: to duplicate the current outline in another tabpage, execute ":tab split" while in a Tree or Body buffer and then press . 3) OUTLINE NAVIGATION (, Arrow Keys, Mouse) -------------------------------------------------- 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. Outline can be navigated with only , and : - Move between Tree lines with j, k, H, M, L, etc. - Press to expand or contract a branch. - Press or to select nodes and to switch between Tree and Body buffers. , , , arrow keys move around the Tree and select nodes (Normal mode). Mouse is also supported. Outline can be navigated by clicking on headlines in the Tree window with the mouse left button (assuming that Vim has mouse support, do ":set mouse=a" when in terminal): - To select a node, click on its headline text with Left Mouse Click. - To expand/contract a node, click on it outside of the headline text. 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 ("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. 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) ADD (INSERT) NEW HEADLINE ---------------------------- "aa" adds new headline. "AA" adds new headline as child. 6) OUTLINE OPERATIONS --------------------- To rearrange the outline structure, the cursor must be in the Tree buffer (press Tab or Return to get there). 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. , move nodes Up/Down. , move nodes Left/Right, that is promote/demote. (These CTRL mapping may not be recognized in a terminal.) Nodes can also be moved Up/Down/Left/Right via two-key mappings: ^^ __ << >> or via LocalLeader mappings: u d l 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. To move nodes over a long distance: cut them with "dd", move the cursor to a new position, paste nodes 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). 7) :Voomlog ----------- The command :Voomlog creates the __PyLog__ buffer and redirects Python's stdout and stderr to it. Examples for Python 2: > :Voomlog :py assert 2==3 :py print u"\u042D \u042E \u042F" :py import this Examples for Python 3: > :Voomlog :py3 assert 2==3 :py3 print(u"\u042D \u042E \u042F") :py3 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 outline of 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|. 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. Move the cursor to Tree or Body window. ------------------------------------------------------------------------------ OUTLINE NAVIGATION (TREE BUFFER) ~ ------------------------------------------------------------------------------ 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. Move the cursor Up and select new node. (N) Move the cursor Down and select new node. (N) Move the cursor to the first child and select it. (N) If the current node is contracted, it is expanded first. Move the cursor to the parent and select it. (N) If the current node is expanded, it is contracted first. ------------------------------------------------------------------------------ EXPAND/CONTRACT NODES ------------------------------------------------------------------------------ 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). Warn 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 a Add a new node after the current node or fold. (N) AA 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) ^^ u Move node(s) Up. (N,V) __ d Move node(s) Down. (N,V) << 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|. >> 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 all siblings of node under the cursor. Options are: "i" (ignore-case), "r" (reverse-sort), "deep" (also sort all descendant nodes), "flip" (reverse), "shuffle" (randomize), "bytes" (sort as bytes strings instead of Unicode strings). :'<,'>VoomSort [options] :[range]VoomSort [options] Sort sibling nodes in Visual area or in some other range. The range must contain 2 or more siblings, otherwise all siblings are sorted. ------------------------------------------------------------------------------ MARK/UNMARK |voom-special-marks| ------------------------------------------------------------------------------ m Mark node(s): add "x" to Body headlines. (N,V) M Unmark node(s): remove "x" from Body headlines. (N,V) = 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. fs Save Tree folding for the current node and all descendant nodes. Same as :VoomFoldingSave. (N) fr Restore Tree folding for the current node and all descendant nodes. Same as :VoomFoldingRestore. (N) fas Save Tree folding for entire outline. Same as :%VoomFoldingSave. (N) 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) 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 while preserving outlines and VOoM internal data. VoomReloadAll Wipe out all outlines (same as :VoomQuitAll), wipe out PyLog buffer, reload VOoM's Vim and Python code, re-initialize VOoM internal data to clean state. (Python voom_* modules from sys.modules are deleted, data guard is unlet, ../autoload/voom.vim is reloaded which re-imports voom_vim.py and re-creates data.) ============================================================================== 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. ============================================================================== g:voom_python_versions [[[2~ *g:voom_python_versions* VOoM can use either Python 2 or Python 3. When "g:voom_python_versions" does not exist, which is default, VOoM will use the first available Python version: Python 2 is tried first, Python 3 is tried next. Variable "g:voom_python_versions" is a list of Python versions (2 or 3) given in order in which VOoM shoud try them. It must be defined in .vimrc and Vim must be restarted for changes to apply. Always use Python 2: > let g:voom_python_versions = [2] Always use Python 3: > let g:voom_python_versions = [3] Use Python 3 if available. If Python 3 is not available, use Python 2: > let g:voom_python_versions = [3,2] Use Python 2 if available. If Python 2 is not available, use Python 3: > let g:voom_python_versions = [2,3] (This is the behavior when "g:voom_python_versions" is not defined.) ============================================================================== 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 and . 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 and : 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: "" g:voom_tab_key ~ A key that simply moves the cursor between the Tree and Body windows. Default: "" Example, use Ctrl-Return and Ctrl-Tab: > let g:voom_return_key = "" let g:voom_tab_key = "" Note that Normal mode and have default meaning in Vim. moves the cursor down. This is not very useful since "j" does almost the same thing. /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 is usually a bad idea. It seems that Ctrl-Tab still works like default /CTRL-I, at least in GUI Vim, when is mapped. ============================================================================== g:voom_ft_modes, g:voom_default_mode [[[2~ *g:voom_ft_modes* *g:voom_default_mode* By default, the command ":Voom" without an argument is identical to command "Voom fmr". It invokes the "fmr" mode (|voom-mode-fmr|): headlines are lines with start fold markers {{{1, {{{2, etc. To work with headlines in 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 given 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. For example, if there is this in .vimrc: > let g:voom_default_mode = 'asciidoc' then, the command > :Voom is identical to > :Voom asciidoc unless "g:voom_ft_modes" is also defined and has an entry for the current filetype. NOTE: The name of the current markup mode is noted on the first line of the Tree buffer. Command ":Voominfo [all]" will show more 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|. To see which Vim register is currently used by VOoM during copy/cut/paste, run ":Voominfo all" and look at the value of _VOoM2657.CLIPBOARD . ============================================================================== g:voom_always_allow_move_left [[[2~ *g:voom_always_allow_move_left* By default, outline operation Move Left (<<, , 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 this outline: > |AAA . |BBB . |CCC . |DDD |EEE Node DDD can be moved left, but individual nodes BBB and CCC cannot. To always allow Move Left, add the following to .vimrc and restart Vim: > let g:voom_always_allow_move_left = 1 When enabled as above, Move Left applied to node CCC will result in: > |AAA . |BBB |CCC . |DDD |EEE In some other outliners the result of moving CCC left is > |AAA . |BBB . |DDD |CCC |EEE It is always possible to produce either result by combining several commands. To produce the first result, put the cursor on CCC and do V D << j >> To produce the second result, put the cursor on CCC and do dd c pp "g:voom_always_allow_move_left" does not exist by default, which is the same as setting it to 0. To see if Move Left is currently always allowed or not, run ":Voominfo all" and look at the value of _VOoM2657.ALWAYS_ALLOW_MOVE_LEFT . ============================================================================== 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!!! This option turns on outline verification after most outline operations. It will alert to outline corruption, which is likely to occur if there is a bug in outline operation. The downside is that there is a performance hit, usually noticeable only with very large outlines (>1 MB, >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: Only applies to the default "fmr" mode (|voom-mode-fmr|). 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]) -> MARKUP MODES -> fmr (Default Markup Mode) -> Tree Headline Text in "fmr" mode < 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. It is intended for loading user add-ons, see |voom-addons| for examples. 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 . To disable VOoM plugin without uninstalling it, add to .vimrc: > let g:voom_did_load_plugin = 1 ============================================================================== Filetypes "voomtree" and "voomlog" [[[2~ When a VOoM Tree buffer is created, its 'filetype' is set to "voomtree". When a VOoM __PyLog__ buffer is created, its 'filetype' is set to "voomlog". This is done to allow users to customize the look of these buffers via standard Vim configuration files: > ~/.vim/after/ftplugin/voomtree.vim ~/.vim/after/syntax/voomtree.vim ~/.vim/after/ftplugin/voomlog.vim ~/.vim/after/syntax/voomlog.vim For example, for a fancier foldtext in Tree buffers, create file > ~/.vim/after/ftplugin/voomtree.vim with line > setl foldtext=getline(v:foldstart).'\ \ '.repeat('\ ',winwidth(0)-strchars(getline(v:foldstart))-8).'('.(v:foldend-v:foldstart).')' NOTE: Be careful not to break VOoM by messing with critical settings! With a few exceptions, settings should be limited only to window-local Vim options: foldtext, foldlevel, statusline, wrap/norwap, list/nolist, number/nonumber. When setting Tree options that are not window-local, or are meant to be set only initially, a load guard should be used to load such code only once: > if exists('b:voomtree_customization_done') | finish | endif " Default bufhidden=wipe. May be changed (not recommended). setl bufhidden=hide " Tree mappings for quick change of foldlevel. nnoremap 1 :setl fdl=1 nnoremap 2 :setl fdl=2 nnoremap 3 :setl fdl=3 let b:voomtree_customization_done = 1 To modify default Tree buffer-local mappings or create new ones: 1. Create file ~/.vim/after/ftplugin/voomtree.vim . 2. Copy relevant mappings from ../autoload/voom.vim function voom#TreeMap(). 3. Change {lhs} and/or {rhs}. 4. Use a buffer-local variable guard to load the code only once (as above). To customize Tree buffers differently for different markup modes and Body filetypes, the following prototype code can be used in voomtree.vim: > if exists('b:voomtree_customization_done') | finish | endif 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') " An fmr mode. Folds are initially opened according to marks o=. 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 endif unlet s:bnr s:FT s:mmode s:MTYPE s:body s:tree let b:voomtree_customization_done = 1 Syntax highlighting can be customized similarly. VOoM adds some default syntax highlighting to Tree and PyLog buffers. For details, see functions in ../autoload/voom.vim : voom#TreeConfigFT(body), voom#LogConfigFT() . See also |voom-addons|. ============================================================================== Misc customization tips [[[2~ Most VOoM commands can be mapped to key shortcuts or alias commands in .vimrc: > nnoremap :Voom nnoremap n :Voomunl com! VM Voom markdown com! VMT VoomToggle markdown Instead of invoking commands :Voom and :VoomToggle, one can call the underlying function voom#Init(). The command ":Voom markdown" is equvalent to > :call voom#Init('markdown') :call voom#Init('markdown', 0, 0) The command ":VoomToggle markdown" is equvalent to > :call voom#Init('markdown', 1, 1) Function voom#Init() is used as follows: :call voom#Init( {markup} [, {toggleOutline} [, {keepCursor}]]) Optional boolean arguments {toggleOutline} and {keepCursor} default to 0. If {keepCursor} is 1, the cursor is kept in the original window if possible. So the command > :call voom#Init('markdown', 0, 1) is like ":Voom markdown" except that the cursor will stay in the Body buffer. 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 in an "fmr" mode (numbered start fold markers), 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]) -> MARKUP MODES -> fmr (Default Markup Mode) -> Tree Headline Text in "fmr" mode '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. 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 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 noremap zF noremap zd noremap zD noremap zE Some color schemes (including default) use the same or similar background colors for selected text (Visual), folded lines (Folded), and the 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 [[[2~ *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. Argument {MarkupMode} specifies the format of headlines. The corresponding markup mode is defined in Python module "voom_mode_{MarkupMode}.py". See |voom-markup-modes|. There is argument completion: type ":Voom " and press or to see all available markup modes. :Voom Use the default markup mode, which by default is "fmr" mode: headlines are lines with a start fold marker (specified by Vim option 'fmr') followed by level number, that is {{{1, {{{2, {{{3, etc. Headline's level is the number after the marker. Headline's text is the part before the marker. See |voom-mode-fmr|. Options |g:voom_default_mode| and |g:voom_ft_modes| can be used to change the default markup mode and to select markup mode automatically according to the filetype of Body buffer. 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 like 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 starting with the headline and ending before the next headline (or end-of-buffer). The first Tree line (title line) 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 (, , , , ), 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|). This update is the bottleneck that can limit the size of outlines that can be edited comfortably. The actual update happens only if the Body has been modified since the last update (when Body's b:changedtick has changed). Thus, browsing an outline is always fast regardless of the size of the Body buffer. A Body buffer is not configured in any substantial way by the command :Voom. It has only two VOoM-specific mappings: and 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'). ============================================================================== ~~~===--- Tree Headline Text ---===~~~ [[[3~ Tree headline text is constructed from the corresponding Body buffer headline. Leading and trailing whitespace is stripped. When working with fold markers ("fmr" mode), other characters such as comment and decorative characters are also stripped from the ends to reduce clutter, see |voom-mode-fmr| for details. The headline text is usually derived from the first line of the corresponding node in the Body buffer. With some markups, this is not necessarily true. In reStructuredText (reST) markup mode headlines can have an overline: > ------------- Headline Text ------------- The Tree buffer will show "Headline Text", but the first line of the corresponding node in the Body buffer is the overline. Tree headlines are constructed by function hook_makeOutline() in the corresponding markup mode file. The default "fmr" mode uses function makeOutline() or makeOutlineH() in voom_vim.py. ============================================================================== Selected Node [[[3~ At any moment, one node in the outline 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 (Tree or Body, Normal mode), or by selecting a new node in the Tree with arrow keys or mouse left button click. When using an "fmr" markup mode, it is possible to automatically select a node on startup. A startup node has character "=" in the Body headline after the level number and after optional "x" and "o" marks (|voom-special-marks|). When an outline is created by the command ":Voom fmr", the node marked with "=" is selected and shown automatically. Relevant Tree mappings (Normal mode): = Mark node under the cursor as startup node. This command inserts "=" after the fold marker in the node's Body headline and removes "=" from all other headlines. ("fmr" modes only) = 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-= ("fmr" modes only) 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. For example, the following can be added to .vimrc: > nnoremap :call voom#DeleteOutline('bw') 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 [[[2~ 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: 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: -- Tree (Normal, Visual), Body (Normal) -- Tree (Normal, Visual), Body (Normal) -- Tree (Normal) and 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|. - 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 after ":tab split" will create a tabpage with a new outline view. - 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 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. Toggle node's expanded/contracted state without selecting it. (N) If the 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 , , , 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: j - To recursively contract subtree of the current node: contract it with if it's expanded, hit VzC to close folds, hit 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 , the following Tree keys also select a node: 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. 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 / . 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 [[[2~ 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 or (|voom-shuttle-keys|) for browsing an outline. ============================================================================== Add New Headline [[[3~ aa a Add a new node after the current node. If the current node is folded, the new node is added after the fold. AA 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~ ^^ u Move node(s) up. (N,V) __ d Move node(s) down. (N,V) << 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|. >> 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 in ascending order as Python unicode strings. :'<,'>VoomSort :[range]VoomSort Sort siblings in Visual selection or in a range (|[range]|). The cursor line must be within the range. IMPORTANT: The range must contain more than one line. If the range is actually one line, all siblings of the node at that line are sorted. :VoomSort [options] :'<,'>VoomSort [options] :[range]VoomSort [options] Sort according to options. Options are any combination of the following words separated by whitespace: deep, i, r, flip, shuffle, bytes. deep Deep (recursive) sort. Sort top-level siblings and siblings of their descendants. When the cursor is on the top-most headline (line 2 in Tree buffer) and no range is given, the entire outline is sorted. i Ignore-case, case-insensitive sort. r Reverse-sort, that is sort in descending order. flip Reverse the order of nodes without sorting anything. shuffle Shuffle nodes randomly, that is randomize. bytes Sort headlines as Python bytes strings instead of unicode strings. This option is not useful. It will cause incorrect results when doing case-insensitive sort of non-ASCII headlines. Example 1. Perform deep sort, ignore-case, sort in reverse order: > :VoomSort deep i r 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. Options "i" and "bytes" have no effect when doing "flip" or "shuffle". It is easy to create custom commands that perform sorting with a particular set of options. For example, if you often do case-insensitive deep sort you can add the following line to .vimrc: > com! VoomSortI call voom#OopSort(line('.'), line('.'), 'i deep') The command :VoomSortI will be identical to command ":VoomSort i deep". It does not accept a range. To make it work with a range: > com! -range VoomSortI call voom#OopSort(, , 'i deep') KNOWN PROBLEMS -------------- VoomSort never inserts or deletes lines in the Body buffer. This means VoomSort may produce errors due to missing blank lines when dealing with markups which require blank lines before headlines: rest, asciidoc, pandoc, paragraphBlank. The simplest example is a Pandoc text with 3 lines: > # BBB # AAA sometext Create outline by command ":Voom pandoc". Execute :VoomSort. Node BBB is moved after node AAA. If there is no blank line aftet the last line "sometext", line BBB will no longer be a headline. VoomSort detects such events _after_ the sorting is finished and displays error messages: > VOoM (sort): ERROR OCCURRED DURING SORTING! YOU **MUST UNDO** THIS SORT!!! ... You will have to make sure that each node ends with a blank line, including a blank line at the end of file, when performing VoomSort with such markups. (This is not a problem with other outline operations: they insert missing blank lines before headlines when needed.) ============================================================================== Special Node Marks [[[3o~ *voom-special-marks* NOTE: Special node marks are available only when working with numbered start fold markers, that is in "fmr" modes (|voom-mode-fmr|, |voom-mode-fmr1|). 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. Each mark is optional, but the ordering must be "xo=". All valid combinations: > headline {{{1x --node is marked headline {{{1o --node is opened headline {{{1= --node is startup node headline {{{1xo --node is marked, opened headline {{{1x= --node is marked, startup node headline {{{1o= --node is opened, startup node headline {{{1xo= --node is marked, opened, startup node Wrong: > headline {{{1=ox --node is startup node, "o" and "x" are ignored headline {{{1 xo= --all marks are ignored VOoM has mappings and commands for reading and writing these special marks. They are described in next subsections. ============================================================================== Mark or Unmark Nodes [[[4~ NOTE: These commands are only available when working with numbered start fold markers, that is in "fmr" modes (|voom-mode-fmr|, |voom-mode-fmr1|). 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. m Normal mode: mark node under the cursor. Visual mode: mark all nodes in the range. "x" is inserted in Body headlines. M Normal mode: unmark node under the cursor. Visual mode: unmark all nodes in the range. "x" is removed from Body headlines. The above commands apply to individual nodes only, not to their descendants. To unmark all: ggVGM Related Tree mappings, Normal mode: x Go to next marked node and select it. X Go to previous marked node and select it. ============================================================================== Save or Restore Tree Folding [[[4~ *voom-tree-folding* NOTE: These commands are only available when working with numbered start fold markers, that is in "fmr" modes (|voom-mode-fmr|, |voom-mode-fmr1|). 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: fs Save Tree folding for the current node and all descendant nodes. Same as :VoomFoldingSave. fr Restore Tree folding for the current node and all descendant nodes. Same as :VoomFoldingRestore. fas Save Tree folding for the entire outline. Same as :%VoomFoldingSave. far Restore Tree folding for the entire outline. Same as :%VoomFoldingRestore. Mnemonics for mappings: Foldins Save/Restore, Folding All Save/Restore. ============================================================================== Mark Node As Startup Node [[[4~ NOTE: These commands are only available when working with numbered start fold markers, that is in "fmr" modes (|voom-mode-fmr|, |voom-mode-fmr1|). = Mark the current node as startup node. (Normal mode) 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 the 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-= ============================================================================== Issues with Removal of Special Marks [[[4~ VOoM commands that remove special node marks "x", "o", "=" have to take into account the possibility that these characters may be present in any combination, not necessarily correct one. To compensate for errors, these commands may remove more than one character. When an "x" mark is removed, all subsequent "x" chars are removed also, so > headline {{{1xxxxxo= becomes > headline {{{1o= Obviously, removing just the first "x" is not enough: the headline will still be marked. Note that the headline has acquired marks "o" and "=". When an "o" mark is removed, all subsequent "x" and "o" chars are removed also. This ensures that a headline will not acquire an "x" mark after "o" has been removed. For example > headline {{{1oooxoxoxxx= becomes > headline {{{1= When an "=" mark is removed, all subsequent "x", "o", and "=" chars are removed also. This ensures that a headline will not acquire an "x" mark after "=" is removed. For example > headline {{{1xo=xxxooo== becomes > headline {{{1xo To sum up, any string of characters "x", "o", "=" immediately after the fold marker level number is not guaranteed to be preserved. If you have a weird string after a fold marker and you want to preserve it, separate it by space: > headline {{{1 xxxooo== ============================================================================== MARKUP MODES [[[2o~ *voom-markup-modes* By default, the command > :Voom creates outline from lines with start fold markers with levels: {{{1, {{{2, {{{3, etc. This default markup mode is called "fmr" mode (|voom-mode-fmr|). If a buffer uses a different markup for headlines, it is necessary to specify the desired markup mode with an argument. For example, command > :Voom MySuperDuperWiki will try to create outline using MySuperDuperWiki markup mode. A markup mode is defined in Python module "voom_mode_{MarkupName}.py" in folder "../autoload/voom/voom_vimplugin2657/". 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. There is argument completion for all markup modes present in folder ../autoload/voom/voom_vimplugin2657/: type ":Voom " and press or . 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,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-fmr1|): - mark/unmark nodes - startup node - save/restore Tree folding. To create a new markup mode or customize existing one: modify one of the files voom_mode_{MarkupName}.py in folder ../autoload/voom/voom_vimplugin2657/ , save it as voom_mode_{NewMarkupName}.py, invoke it with ":Voom NewMarkupName". The following sections describe markup modes available by default. ============================================================================== fmr (Default Markup Mode) [[[3~ *voom-mode-fmr* COMMAND: :Voom :Voom fmr MODULE: None ../autoload/voom/voom_vimplugin2657/voom_mode_fmr.py The "fmr" mode is the default markup mode -- command ":Voom" without an argument is identical to ":Voom fmr". This can be changed by user options |g:voom_default_mode| and |g:voom_ft_modes|. The "fmr" mode outlines start fold markers with levels. It also supports special node marks after the fold marker, see |voom-special-marks|. Fold markers are specified by window-local Vim option 'fmr'. Example outline: > Headline A (level 1) {{{1 more lines of text Headline B (level 2) {{{2 more line of text Headline C (level 3) {{{3 Headline D (level 1) {{{1 Headline's level is the number after the fold marker. Headline's text is the part before the first fold marker. To reduce clutter, whitespace and comment characters are stripped from the right side of headlines. Leading and trailing characters -=~ are also stripped. They can be used to decorate headlines like this: > --- Headline A --- {{{1 more lines of text --- Headline B --- {{{2 more line of text This can be customized in many ways. See the next subsection for details. End fold markers with levels, }}}1, }}}2, }}}3, etc., are ignored and should not be used. Matching fold markers without level numbers, {{{ and }}}, are ignored, but can be useful: they are handy for folding small areas inside numbered folds, e.g., parts of functions. The region between {{{ and }}} should not contain numbered fold markers. Ideally, Body's 'foldmethod' should be set to "marker" (|fold-marker|). If this is the case, Body's nodes are also folds. When browsing such outline, VOoM folds non-current nodes, thus showing only the current node in the Body buffer. However, this is not required: folding in the Body buffer has no effect on the outline construction or outline operations. Fold markers with levels are perfect for adding structure to any plain text files, including the source code. Examples of real-life files in "fmr" markup: - This help file voom.txt. Non-default "foldmarker" option is set from modeline at the end of file. - VOoM source files: ../autoload/voom.vim ../autoload/voom/voom_vimplugin2657/voom_vim.py - Netrw help file and source files: $VIMRUNTIME/doc/pi_netrw.txt $VIMRUNTIME/autoload/netrw.vim Similar markup modes: |voom-mode-fmr1|, |voom-mode-fmr2|, |voom-mode-fmr3|. ============================================================================== ~~~===--- Tree Headline Text in "fmr" mode ---===~~~ [[[4~ This section describes how Tree headlines are constructed in the "fmr" mode (default markup mode), that is when outlining start fold markers with levels. 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 ==== headline level 4 ==== 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
,  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
----------
https://www.mediawiki.org/wiki/Help:Formatting
https://meta.wikimedia.org/wiki/Help:Section
https://en.wikipedia.org/wiki/Help:Section
https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style#Section_headings

==============================================================================
vimwiki   [[[3~
                                                 *voom-mode-vimwiki*
COMMAND:
    :Voom vimwiki
MODULE:
    ../autoload/voom/voom_vimplugin2657/voom_mode_vimwiki.py

Headline markup used by Vimwiki plugin:
    https://github.com/vimwiki/vimwiki
    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  and . When the command ":Voom vimwiki" creates
the outline, it overwrites Vimwiki's mappings for  and , 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_| and |vimwiki_| in Vimwiki's help.

==============================================================================
viki   [[[3~
                                                 *voom-mode-viki*
COMMAND:
    :Voom viki
MODULE:
    ../autoload/voom/voom_vimplugin2657/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] <
    +++ headline level 1
    some text
    ++++ headline level 2
    more text
    +++++ headline level 3
    ++++++ headline level 4
    etc.

First + must be at start of line. Whitespace after the last + is optional.

==============================================================================
org   [[[3~
                                                 *voom-mode-org*
COMMAND:
    :Voom org
MODULE:
    ../autoload/voom/voom_vimplugin2657/voom_mode_org.py

Mode for outlining Emacs Org-mode headlines:
    http://orgmode.org/
    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*
COMMAND:
    :Voom rest
MODULE:
    ../autoload/voom/voom_vimplugin2657/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
    https://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.

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*
COMMAND:
    :Voom markdown
MODULE:
    ../autoload/voom/voom_vimplugin2657/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

Vim folding and helpers 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 is also
better suited for MultiMarkdown and GitHub Flavored Markdown (GFM) because of
fenced code blocks:
    http://pandoc.org/ --Pandoc
    http://fletcherpenney.net/multimarkdown/ --MultiMarkdown
    https://help.github.com/categories/writing-on-github/ --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* COMMAND: :Voom pandoc MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_pandoc.py Mode for outlining of Pandoc Markdown headers. http://pandoc.org/ https://github.com/jgm/pandoc https://github.com/jgm/pandoc/blob/master/MANUAL.txt --Pandoc user guide 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://pandoc.org/MANUAL.html#headers - Headers are ignored inside fenced code blocks. http://pandoc.org/MANUAL.html#fenced-code-blocks - Headers that start with "#. " are ignored, they are fancy_lists. http://pandoc.org/MANUAL.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* COMMAND: :Voom hashes MODULE: ../autoload/voom/voom_vimplugin2657/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 Markdown or Pandoc mode because it does not have to deal with underlined headlines and closing #'s. 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* COMMAND: :Voom txt2tags MODULE: ../autoload/voom/voom_vimplugin2657/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* COMMAND: :Voom asciidoc MODULE: ../autoload/voom/voom_vimplugin2657/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 source for AsciiDoc Userguide is an example of AsciiDoc 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 the title line and preceding [[...]] and [...] lines. 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_vimplugin2657/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* COMMAND: :Voom latex MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_latex.py Mode for outlining of LaTeX sections and some other markups. https://en.wikipedia.org/wiki/LaTeX https://en.wikibooks.org/wiki/LaTeX/Document_Structure#Sectioning_Commands Example LaTeX file: https://github.com/AllenDowney/ThinkPython2/blob/master/book/book.tex 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'] ============================================================================== latexDtx [[[3~ *voom-mode-latexDtx* COMMAND: :Voom latexDtx MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_latexDtx.py Mode for .dtx files (Documented LaTeX sources): http://www.tex.ac.uk/FAQ-dtx.html Example .dtx file: https://github.com/maieul/ledmac/blob/master/reledmac.dtx The latexDtx mode is almost identical to the latex mode (|voom-mode-latex|). The main difference is that only commented lines are considered for headlines. Commented lines start with: optional leading whitespace, at least one "%" character, optionally followed by any combination of "%" and whitespace. The following lines are examples of headlines: > %\section{Introduction} % \section{Introduction} %% \section{Introduction} %%% % % \section{Introduction} The leading string of % and whitespace is preserved during outline operations. The following user-defined variables can be used to customize sectioning commands, level 1 elements, verbatim blocks: > g:voom_latexdtx_sections g:voom_latexdtx_elements g:voom_latexdtx_verbatims These are equivalent to the corresponding "g:voom_latex_..." options, see Customizing for LaTeX mode. By default, when g:voom_latexdtx_verbatims is not defined, headlines are ignored inside the following blocks: > % \begin{verbatim} % ... % \end{verbatim} % \begin{comment} % ... % \end{comment} % \begin{macrocode} % ... % \end{macrocode} TODO: It would be good to also ignore \iffalse...\fi blocks. This is hard to implement because such blocks can contain many more \fi lines. It seems false headlines are unlikely in real files. ============================================================================== dokuwiki [[[3~ *voom-mode-dokuwiki* COMMAND: :Voom dokuwiki MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_dokuwiki.py Mode for outlining of DokuWiki headlines: https://www.dokuwiki.org/ https://www.dokuwiki.org/wiki:syntax#sectioning Headlines 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: , , , %%, etc. Similar mode: inverseAtx (|voom-mode-inverseAtx|). ============================================================================== inverseAtx [[[3~ *voom-mode-inverseAtx* COMMAND: :Voom inverseAtx MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_inverseAtx.py For outlining of inverse ATX-style headlines. Headlines start with "@". There is a maximum of 3 levels: > @@@ Headline level 1 @@ Headline level 2 @ Headline level 3 To change the headline character and maximum level, change constants CHAR and MAX in the module, see comments in the module for details. You can also change them by adding options to .vimrc: > let g:voom_inverseAtx_char = '^' let g:voom_inverseAtx_max = 5 Similar mode: dokuwiki (|voom-mode-dokuwiki|). ============================================================================== html [[[3~ *voom-mode-html* COMMAND: :Voom html MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_html.py HTML heading tags. Single line only. >

headline level 1

some text

headline level 2

more text

headline level 3

< h4 > headline level 4 some text

headline 5

etc. Both tags must be on the same line. Closing tag must start 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 Similar modes (indent-based): |voom-mode-vimoutliner|, |voom-mode-taskpaper|. ============================================================================== vimoutliner [[[3~ *voom-mode-vimoutliner* COMMAND: :Voom vimoutliner MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_vimoutliner.py VimOutliner format: https://github.com/vimoutliner/vimoutliner http://www.vim.org/scripts/script.php?script_id=3515 Headlines are lines with >=0 Tabs followed by any character except: : ; | > < Otherwise this mode is identical to the "thevimoutliner" mode. Similar modes (indent-based): |voom-mode-thevimoutliner|, |voom-mode-taskpaper|. ============================================================================== taskpaper [[[3~ *voom-mode-taskpaper* COMMAND: :Voom taskpaper MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_taskpaper.py TaskPaper format: http://www.vim.org/scripts/script.php?script_id=2027 https://www.taskpaper.com/ 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. Similar modes (indent-based): |voom-mode-thevimoutliner|, |voom-mode-vimoutliner|. ============================================================================== python [[[3~ *voom-mode-python* COMMAND: :Voom python MODULE: ../autoload/voom/voom_vimplugin2657/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. ============================================================================== Paragraph Modes [[[3o~ Paragraph modes are for working with paragraphs, that is blocks of lines. The first line of each paragraph is a level 1 headline. Everything is always at level 1. Levels >1 are not possible. There are three paragraph modes differing in how paragraphs are defined: paragraphBlank --paragraphs are separated by blank lines paragraphIndent --paragraphs are started by an indented line paragraphNoIndent --paragraphs are started by a non-indented line Paragraph modes are handy for sorting paragraphs of text with VoomSort. ============================================================================== paragraphBlank [[[4~ *voom-mode-paragraphBlank* COMMAND: :Voom paragraphBlank MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_paragraphBlank.py This mode is for working with paragraphs, that is blocks of lines. The first line of each paragraph is a level 1 headline. Levels >1 are not possible. Paragraphs are separated by blank lines. Any non-blank line preceded by a blank line is headline. The first non-blank line is obviously also a headline. Blank lines may contain whitespace characters. Example: > Headline A more lines of text more lines of text Headline B more lines of text more lines of text NOTE: Make sure there is a blank line after the last paragraph, that is before end-of-file. Without it :VoomSort will produce an error when the last paragraph is moved during sorting. Similar modes: |voom-mode-paragraphIndent|, |voom-mode-paragraphNoIndent|. ============================================================================== paragraphIndent [[[4~ *voom-mode-paragraphIndent* COMMAND: :Voom paragraphIndent MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_paragraphIndent.py This mode is for working with paragraphs, that is blocks of lines. The first line of each paragraph is a level 1 headline. Levels >1 are not possible. Paragraphs are started by an indented line. Any non-blank line that starts with a space or tab is a headline. Example: > Headline A more lines of text more lines of text Headline B more lines of text more lines of text < Similar modes: |voom-mode-paragraphBlank|, |voom-mode-paragraphNoIndent|. ============================================================================== paragraphNoIndent [[[4~ *voom-mode-paragraphNoIndent* COMMAND: :Voom paragraphNoIndent MODULE: ../autoload/voom/voom_vimplugin2657/voom_mode_paragraphNoIndent.py This mode is for working with paragraphs, that is blocks of lines. The first line of each paragraph is a level 1 headline. Levels >1 are not possible. Paragraphs are started by a non-indented line. Any non-blank line that starts with a character other than a space or tab is a headline. Example: > Headline A more lines of text more lines of text Headline B more lines of text more lines of text An example of this format are .dsl files used by GoldenDict (plain text dictionary sources), see https://github.com/goldendict/goldendict . Similar modes: |voom-mode-paragraphBlank|, |voom-mode-paragraphIndent|. ============================================================================== 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 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 the buffer's 'filetype': "python" if filetype is "python", "vim" if filetype is "vim", etc. When executed from a Tree buffer (also with e), filetype of the corresponding Body is used. :Voomexec vim Execute as "vim" script. :Voomexec python :Voomexec py Execute as "python" script. This invokes the same Python version (2 or 3) as used by VOoM. :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 its 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 "exec", see https://docs.python.org/2/reference/simple_stmts.html#exec (Python 2) and https://docs.python.org/3/library/functions.html#exec (Python 3). The following Python names are pre-defined: vim, _VOoM2657 (main module voom_vimplugin2657.voom_vim). An extra line is prepended to script lines to specify encoding as per https://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. The "---end of script---" message includes the first and the 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' " Use Python to print list of VOoM Body buffer numbers. " The problem is that we don't known which Python version to use: " python print(_VOoM2657.VOOMS.keys()) " python3 print(_VOoM2657.VOOMS.keys()) " So we do it like this instead: exec voom#GetVar('s:PYCMD') 'print(_VOoM2657.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: %s' % vim.eval('bufnr("")')) print('VOoM Body buffer numbers: %s' % _VOoM2657.VOOMS.keys()) print('docstring of voom_vim.makeOutline():\n %s' % _VOoM2657.makeOutline.__doc__) import os print('current working dir: %s' % 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#GetBufRange(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#GetBufRange(line("'<"),line("'>")) if body < 0 | return | endif let blines = getbufline(body,bln1,bln2) ... do something with blines ... ============================================================================== __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 2 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. ============================================================================== 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 Python module voom_addons.py, and it is somewhere in your Python search path. To import this module when VOoM is initialized, add one of the following to .vimrc: (Python 2) > let g:voom_user_command = "python import voom_addons" (Python 3) > let g:voom_user_command = "python3 import voom_addons" (Python 2 or Python 3 selected automatically) > let g:voom_user_command = "exe s:PYCMD 'import voom_addons'" To access the main module voom_vim.py from within voom_addons.py, do this: > import sys voom_vim = sys.modules['voom_vimplugin2657.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". This module is imported in "voom.vim" as "_VOoM2657". - Python-side outline data for each Body are attributes of an instance of class VoomOutline (VO). These class instances are stored in dictionary _VOoM2657.VOOMS, keys are Body buffer numbers: VO=_VOoM2657.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 __PyLog__ 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|). ============================================================================== Known Issues [[[1o~ *voom-issues* See subnodes for lists of known issues with outlining, executing nodes, and __PyLog__ buffer. ============================================================================== Issues with Outlining (:Voom [markup]) [[[2~ * Command :VoomSort may end with an error > VOoM (sort): ERROR OCCURRED DURING SORTING! YOU **MUST UNDO** THIS SORT!!! This is normally caused by missing blank lines when working with markups that require blank lines before headlines (rest, asciidoc, pandoc, paragraphBlank). When you encounter such an error, you must undo the command (pressing "u" once should be enough), add missing blank lines, and repeat the sort. Make sure a blank line at the end of file is also present. See |voom-sort| for details. * The Body buffer text must not contain invalid byte sequences. This is especially important when using Python 3 due to this Vim issue: https://github.com/vim/vim/issues/1053 -- Impossible to pass non-UTF-8 strings from vim to Python 3. To illustrate the problem, create a buffer with an invalid Unicode string (encoding should be utf-8): > :tabnew :1put ='aaa {{{1' :2put =printf('%c', 0xFF) :3put ='bbb {{{1' Then create outline with ":Voom fmr". When using Python 3, Move Down on node aaa will fail with Python error: > UnicodeEncodeError: 'utf-8' codec can't encode character '\udcff' in position 0: surrogates not allowed If an invalid string is part the of the headline text, outline creation with the command :Voom will be impossible. If outline is created successfully, and an invalid string is introduced into a headline later, subsequent outline update will become impossible. Any changes made by an outline operation to the Body buffer must be undone after such an error: the changes are likely to be partial. (Pressing "u" once should be enough.) VOoM displays the following error message when it detects that Body buffer has been modified during a failed outline operation: > VOoM: Body buffer WAS CHANGED during failed outline operation! You **MUST UNDO** this change!!! When using Python 2, only operations Copy/Cut seem to be affected (and only when register "+ is used for copying). They will fail with error message > VOoM: error setting clipboard but no changes will be made to the Body buffer. * When Body buffer text contains null bytes (^@), commands Copy/Cut will fail with Python 2 error: > TypeError: expected string without null bytes or Python 3 error: > ValueError: embedded null byte The Body buffer is left unchanged after such error. Other outline operations seem to be OK. * When a VOoM outline is deleted, Body's original mappings for and (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". * 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. * 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. (This does not apply to Python 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). * 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! . * Undoing some outline operations can take a long 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). * 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. ============================================================================== Issues with Executing Nodes (:Voomexec) [[[2~ * Vim script code executed this way cannot use |line-continuation|. * 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. Examples in the next folds can be executed with ":Voome vim". > " Vim script with Python 2 error [[[ echo 'start of vim script' py print bogus_name py print 'py after error' echo 'the end' " ]]] " Vim script with Python 3 error [[[ echo 'start of vim script' py3 print(bogus_name) py3 print('py3 after error') echo 'the end' " ]]] < * As the example above illustrates, Vim script is not terminated when an error occurs in the Python code. * When executing Vim scripts via ":Voomexec vim", and when Vim supports both Python 2 and Python 3, it is best to stick to the Python version used by VOoM. That is use either command :python or :python3 in Vim scripts. ============================================================================== Issues with __PyLog__ Buffer (:Voomlog) [[[2~ * 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()) ### ]]] * Printing many lines one by one can take a very 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 in __PyLog__.) * __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 * 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' < * 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. * 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. (This seems to have been fixed.) * It is better not to mix :python and :python3 commands in Vim when __PyLog__ is active. There may be some bad interactions so that the output for one of the Pythons will be missing or misformed in the __PyLog__ buffer. ============================================================================== Changelog [[[1x~ *voom-changelog* Changelog for VOoM v5.3, released 2017-03-05 -------------------------------------------- PROBLEM: When an existing Tree buffer is loaded in another window, user's window-local Vim options set in ftplugin/voomtree.vim (e.g., foldtext) are replaced by VOoM defaults or can change. SOLUTION: Do "setl ft=voomtree" (and reapply syntax), when checking for w:voom_tree in voom#TreeBufEnter(). PROBLEM with fmr modes: lines with {{{0, {{{00, ... are shown in Tree as headlines at level 1. Internally they have level 0. SOLUTION: Change regexp for level number from "\d+" to "\d*[1-9]\d*". The result matches Vim behavior when foldmethod is marker: {{{0, {{{00, ... are now ignored. Same in Vim: no effect on folding. {{{01, {{{0002, ... are level 1, 2, ... as before. Same in Vim. Allow Move Left on 2nd Tree line. Useful when 1st headline has level >1. Improved default syntax hi in Tree. A few minor code changes. Changelog for VOoM v5.2, released 2017-01-22 -------------------------------------------- Python 3 is now supported. New option g:voom_python_versions. New markup modes: latexDtx, fmr3, paragraphBlank, paragraphIndent, paragraphNoIndent. VOoM Python modules are now in directory ../autoload/voom/voom_vimplugin2657/ and are imported as a package. Custom markup modes must be placed there. Because directory structure has changed, previous VOoM version should be removed before installing this one. Main module voom_vim.py is imported in Vim as _VOoM2657 instead of _VOoM. VoomSort: Option "u" was removed. Option "bytes" was added. Headlines are now always sorted as Python Unicode strings unless option "bytes" is given. VoomSort: if a range is given, the current line must be within the range. Otherwise error check "current line is hidden in fold" makes no sense. Also, the range is meant to be Visual selection. Copy/Cut: if clipboard check fails after copying to clipboard, empty clipboard to prevent subsequent Paste with erroneous data. Cut: abort if copying to clipboard failed. Added second optional boolean argument to function voom#Init(): :call voom#Init( {markup} [, {toggleOutline} [, {keepCursor}]]) The optional {toggleOutline} and {keepCursor} boolean arguments default to 0. If {keepCursor} is 1, the cursor is kept in the original window if possible. This is useful in scripts that create outlines automatically when a file is loaded and we don't want the cursor to jump between windows. PROBLEM: Vim issue #1053 or similar Python error can break outline operation in the middle of making modifications to the Body buffer. SOLUTION: Detect such events and show error message alerting the user that bad changes have been made to the Body buffer and must be undone. Command ":Voom" is now by default identical to ":Voom fmr", that is voom_mode_fmr.py is always imported when using the default mode. Help file was reorganized to treat default "fmr" mode more like other modes. Help file was cleaned up of superfluous stuff. ============================================================================== modelines [[[1~ vim:fdm=marker:fmr=[[[,]]]:ft=help:ai:et:noma:ro: vim:foldtext=getline(v\:foldstart).'...'.(v\:foldend-v\:foldstart):