[
  {
    "path": ".gitignore",
    "content": "*.pyc\n*.swp\ntags\n.ropeproject\n.cover*\ncover*\n"
  },
  {
    "path": ".pylintrc",
    "content": "[MASTER]\n\n# Specify a configuration file.\n#rcfile=\n\n# Python code to execute, usually for sys.path manipulation such as\n# pygtk.require().\ninit-hook=sys.path.append(os.path.abspath('ftplugin'))\n\n# Profiled execution.\nprofile=no\n\n# Add files or directories to the blacklist. They should be base names, not\n# paths.\nignore=.git\n\n# Pickle collected data for later comparisons.\npersistent=yes\n\n# List of plugins (as comma separated values of python modules names) to load,\n# usually to register additional checkers.\nload-plugins=\n\n\n[MESSAGES CONTROL]\n\n# Enable the message, report, category or checker with the given id(s). You can\n# either give multiple identifier separated by comma (,) or put this option\n# multiple time.\n#enable=\n\n# Disable the message, report, category or checker with the given id(s). You\n# can either give multiple identifier separated by comma (,) or put this option\n# multiple time (only on the command line, not in the configuration file where\n# it should appear only once).\n#disable=\n\n[REPORTS]\n\n# Set the output format. Available formats are text, parseable, colorized, msvs\n# (visual studio) and html\noutput-format=parseable\n\n# Include message's id in output\ninclude-ids=no\n\n# Put messages in a separate file for each module / package specified on the\n# command line instead of printing them on stdout. Reports (if any) will be\n# written in a file name \"pylint_global.[txt|html]\".\nfiles-output=no\n\n# Tells whether to display a full report or only the messages\nreports=yes\n\n# Python expression which should return a note less than 10 (10 is the highest\n# note). You have access to the variables errors warning, statement which\n# respectively contain the number of errors / warnings messages and the total\n# number of statements analyzed. This is used by the global evaluation report\n# (RP0004).\nevaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)\n\n# Add a comment according to your evaluation note. This is used by the global\n# evaluation report (RP0004).\ncomment=no\n\n\n[TYPECHECK]\n\n# Tells whether missing members accessed in mixin class should be ignored. A\n# mixin class is detected if its name ends with \"mixin\" (case insensitive).\nignore-mixin-members=yes\n\n# List of classes names for which member attributes should not be checked\n# (useful for classes with attributes dynamically set).\nignored-classes=SQLObject\n\n# When zope mode is activated, add a predefined set of Zope acquired attributes\n# to generated-members.\nzope=no\n\n# List of members which are set dynamically and missed by pylint inference\n# system, and so shouldn't trigger E0201 when accessed. Python regular\n# expressions are accepted.\ngenerated-members=REQUEST,acl_users,aq_parent\n\n\n[BASIC]\n\n# Required attributes for module, separated by a comma\nrequired-attributes=\n\n# List of builtins function names that should not be used, separated by a comma\nbad-functions=map,filter,apply,input\n\n# Regular expression which should only match correct module names\nmodule-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$\n\n# Regular expression which should only match correct module level names\nconst-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$\n\n# Regular expression which should only match correct class names\nclass-rgx=[A-Z_][a-zA-Z0-9]+$\n\n# Regular expression which should only match correct function names\nfunction-rgx=[a-z_][a-z0-9_]{2,30}$\n\n# Regular expression which should only match correct method names\nmethod-rgx=[a-z_][a-z0-9_]{2,30}$\n\n# Regular expression which should only match correct instance attribute names\nattr-rgx=[a-z_][a-z0-9_]{2,30}$\n\n# Regular expression which should only match correct argument names\nargument-rgx=[a-z_][a-z0-9_]{2,30}$\n\n# Regular expression which should only match correct variable names\nvariable-rgx=[a-z_][a-z0-9_]{2,30}$\n\n# Regular expression which should only match correct list comprehension /\n# generator expression variable names\ninlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$\n\n# Good variable names which should always be accepted, separated by a comma\ngood-names=i,j,k,ex,Run,_\n\n# Bad variable names which should always be refused, separated by a comma\nbad-names=foo,bar,baz,toto,tutu,tata\n\n# Regular expression which should only match functions or classes name which do\n# not require a docstring\nno-docstring-rgx=__.*__\n\n\n[MISCELLANEOUS]\n\n# List of note tags to take in consideration, separated by a comma.\nnotes=FIXME,XXX,TODO\n\n\n[VARIABLES]\n\n# Tells whether we should check for unused import in __init__ files.\ninit-import=no\n\n# A regular expression matching the beginning of the name of dummy variables\n# (i.e. not used).\ndummy-variables-rgx=_|dummy\n\n# List of additional names supposed to be defined in builtins. Remember that\n# you should avoid to define new builtins when possible.\nadditional-builtins=\n\n\n[SIMILARITIES]\n\n# Minimum lines number of a similarity.\nmin-similarity-lines=4\n\n# Ignore comments when computing similarities.\nignore-comments=yes\n\n# Ignore docstrings when computing similarities.\nignore-docstrings=yes\n\n\n[FORMAT]\n\n# Maximum number of characters on a single line.\nmax-line-length=800\n\n# Maximum number of lines in a module\nmax-module-lines=1000\n\n\n[CLASSES]\n\n# List of interface methods to ignore, separated by a comma. This is used for\n# instance to not check methods defines in Zope's Interface base class.\nignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by\n\n# List of method names used to declare (i.e. assign) instance attributes.\ndefining-attr-methods=__init__,__new__,setUp\n\n\n[IMPORTS]\n\n# Deprecated modules which should not be used, separated by a comma\ndeprecated-modules=regsub,string,TERMIOS,Bastion,rexec\n\n# Create a graph of every (i.e. internal and external) dependencies in the\n# given file (report RP0402 must not be disabled)\nimport-graph=\n\n# Create a graph of external dependencies in the given file (report RP0402 must\n# not be disabled)\next-import-graph=\n\n# Create a graph of internal dependencies in the given file (report RP0402 must\n# not be disabled)\nint-import-graph=\n\n\n[DESIGN]\n\n# Maximum number of arguments for function / method\nmax-args=5\n\n# Argument names that match this expression will be ignored. Default to name\n# with leading underscore\nignored-argument-names=_.*\n\n# Maximum number of locals for function / method body\nmax-locals=15\n\n# Maximum number of return / yield for function / method body\nmax-returns=6\n\n# Maximum number of branch for function / method body\nmax-branchs=12\n\n# Maximum number of statements in function / method body\nmax-statements=50\n\n# Maximum number of parents for a class (see R0901).\nmax-parents=7\n\n# Maximum number of attributes for a class (see R0902).\nmax-attributes=7\n\n# Minimum number of public methods for a class (see R0903).\nmin-public-methods=2\n\n# Maximum number of public methods for a class (see R0904).\nmax-public-methods=20\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: python\n\nbefore_install:\n    - sudo apt-get update && sudo apt-get --reinstall install -qq language-pack-pt\n\npython:\n    - \"2.7\"\n    - \"3.4\"\n    - \"3.5\"\n    - \"3.6\"\n    - \"3.7\"\n    - \"3.8\"\n    - \"3.9\"\n    - \"3.10\"\n    - \"3.11\"\n    - \"3.12\"\n\ninstall:\n    - pip install coverage\n    - pip install codecov\n\nscript:\n    - cd tests\n    - nosetests --with-coverage .\n\nafter_success:\n    - codecov\n"
  },
  {
    "path": "CHANGELOG.org",
    "content": "* Changelog\n  All notable changes to this project will be documented in this file.\n\n  This log is kept according to the [[http://keepachangelog.com/][Keep a CHANGELOG]] manifesto\n** 0.7.0\t\t\t\t\t\t\t\t\t     :unreleased:\n*** Added\n    - Subtracting when entering dates (PR #276)\n*** Fixed\n    - =ir= text object now works with most operations (PR #284, closes #273)\n** 0.6.0 <2017-11-06 Mon>\t\t\t\t\t\t\t :released:\n*** Added\n    - Introduced sphinx documentation to Python modules. (PR #237)\n    - Add =Python3= support. (PR #231, closes #226)\n    - Implementing agenda overview for current buffer. (PR #229)\n    - =g:org_aggressive_conceal=, if value =1=, will conceal all simple format\n      identifying characters, default =0=. (PR #188)\n    - (testing on `g:org_aggressive_conceal=1' mode) Add possibility to escape\n      format indicating characters from leading inline markup, by escaping with\n      \"\\\".\n    - Add alternative behavior: refrain from entering insert mode after\n      heading/checkbox creation through keybindings. Activate by setting\n      =g:org_prefer_insert_mode= to 0. (closes #211)\n    - Add export as LaTeX beamer slides (PR #206)\n    - Keybinding to create plainlist item directly. (closes #190)\n    - Make % jump between < and >. (PR #251, closes #250)\n*** Changed\n    - Changed default value for =g:org_indent= from =1= to =0=. (closes #243)\n    - Revamped TODO keyword cycling rules. (PR #237)\n    - In [[syntax/org.vim][syntax/org.vim]], changed `\\@<=' with computational faster `\\zs'\n    - Using =<localleader>c[n/N]= to create new plainlist item following\n      current plainlist item. Now these keybindings will unconditionally\n      create empty checkbox. (closes #190)\n*** Deprecated\n    - Nothing\n*** Removed\n    - Removed the requirement for TODO state keywords to be upper-case.\n      (PR #235)\n*** Fixed\n    - Avoid duplicate =InsertLeave= handlers (PR #222, closes #223)\n    - Fix python3 compatibility issue with regexes\n      (PR #266, closes #263, #265)\n    - Fixed python3 compatible issue within =CalendarAction=.\n      (PR #242, closes #241)\n    - Tree promoting/demoting no longer destroy list and checkbox structure.\n      (closes #217)\n    - Fixed bug when promote/demote headings when it contain lists.\n      (PR #239, partly fixes #217)\n    - Silenced =W18= warning when non-ASCII coded TODO keywords are used.\n      (PR #236)\n    - Fix non-English locale support issue in OrgDate and Agenda. (PR #234,\n      closes #230)\n    - Fix =concealcursor= mis-setting. (from =\"nc\"= to =nc=)\n    - Fix duplicate =InsertLeave= autocmd for =tag_complete=. (closes #223)\n    - Fix utl error when =\\= or white space is in the link by auto-escaping.\n      (closes #220)\n    - Fix typo vbm -> vmb (PR #219)\n    - Fix toggling checkboxes with plain embedded lists (PR #212, closes #209)\n    - Return to right window before setting todo (closes #202)\n    - Fix link to calendar-vim (closes #197)\n    - Fix =out of bound= issue when creating heading/checkbox after last\n      instance in document on NeoVim. (closes #213)\n** 0.5.0 <2015-10-10 Sat>\t\t\t\t\t\t\t :released:\n*** Added\n    - show link description in headings when folded, instead of the whole\n      link\n    - add simplified mappings to create new headings with\n      [<localleader>|<leader>]<CR>\n    - improve incrementing and decrementing of list items\n    - moved changelog information to its own file\n    - add tests for the tags plugin\n    - copy type and indentation when creating new list items\n    - increase/decrease ordered list when adding new items\n    - add support for alphanumeric ordered lists\n    - add test cases for overlapping mappings\n    - add three dots after folded text, like in orgmode\n    - improve highlighting of org-mode properties (closes issue #130)\n    - implement global visibility as it works in Emacs org-mode (closes issue\n      #119)\n    - improve detection of speeddating plugin (closes issue #121)\n    - add support for high speed searching of headings that use certain tags\n      (closes issue #58)\n    - make echo, echom and echoe split messages a line ends and execute a\n      single vim command for each line\n    - add export commands OrgExportToPDF and OrgExportToHTML (closes issue\n      #107)\n    - add variables for customizing the export via Emacs: g:org_export_emacs,\n      g:org_export_verbose, g:org_export_init_script (closes issue #107)\n    - switch to subprocess.Popen for Emcas export (closes issue #107)\n    - add defaults and examples for all variables\n    - add support for inserting new checkboxes with the same keybinging as\n      inserting new headings (thanks to Powen Tan)\n    - implemented support for markdown export (issue #185)\n*** Deprecated\n    - Nothing\n*** Removed\n    - Nothing\n*** Fixed\n    - allow checkbox status to be toggled when there is no indicator present\n      ([])\n    - improve installation instructions (related to issues #111 and #176)\n    - optimize checkbox regex to match also just the type without status and\n      title\n    - fix broken unordered lists\n    - set org_tag_column to textwidth\n    - change commentstring to \"# %s\"\n    - fix syntax highlighting of list items\n    - fix indentation of first checkbox of a heading\n    - fix indentation of first checkbox of a heading\n    - disable highlighting of non-printable characters in todo state\n      selection window\n    - fix highlighting of todo keywords that are followed by additional\n      characters, i.e. TODOs\n    - omit status when entering new checkbox item if current checkbox doesn't\n      have one\n    - fix broken indentation of checkboxes (closes issue #146)\n    - fix CalendarAction is undefined (closes issue #142)\n    - correct overlapping mappings in PluginDate\n    - fix cache problems when inserting a new heading, together with multi\n      line text (closes issue #116)\n    - rename plug to OrgTodoToggleNonInteractive (closes issue #114)\n    - fix jumping to the first character within the body of a heading\n    - use Ignore highlighting instead of NonText for shaded stars (closes\n      issues #173)\n    - fix broken buffer number (closes issue #177)\n    - make exports work with emacs 24.4 (closes issue #178)\n    - improve comments\n    - fix syntax for #+BEGIN_* blocks (issue #186)\n** 0.4.0-0 <2011-10-16 Sun>\t\t\t\t\t\t\t :released:\n   - fix broken repeat settings for moving a heading\n   - improve performance when moving a heading upward or downward (closes\n     issue #108)\n   - improve performance when changing the level of a heading (related to\n     issue #108)\n   - extend liborgmode.headings.HeadingList to allow headings to not be\n     tainted when moving them around\n   - change heading tree text object to ir/ar... because of vim's it/at text\n     object (closes issue #106)\n   - improve performance when inserting a new heading below (closes issue\n     #105)\n   - remove duplicate tags (closes issue #104)\n   - improve performance in insert mode (closes issue #103)\n   - improve performance when opening larger org files (closes issue #103)\n   - replace org.txt by orgguide.txt (closes issue #77)\n   - replace g:org_leader by <LocalLeader> (closes issue #101)\n     To restore the previous behavior add the following line to your vimrc:\n     >\n     let maplocalleader = ','\n     <\n   - change normal command execution to not remap any key (related to issue\n     #85)\n   - fix regression timeout when opening folds (closes issue #100)\n   - vim-orgmode multistate documentation (closes issue #77)\n   - add support for @-signs in tags (closes issue #98)\n   - enable file completion for hyperlinks by default (closes issue #97)\n   - fix traceback when pressing <Esc> while editing a link (closes issue\n     #96)\n   - implement reverse visibility cycling using <S-Tab> (closes issue #95)\n   - change ,, and ,. to remap zr and zm. (closes issue #73)\n   - add .cnf files to the vimball archive (closes #93)\n   - integrate pylint code checker (closes issue #87)\n   - solve encoding issues in the agenda plugin (closes issue #86)\n   - add description for writing test cases\n   - add coverage report target (closes issue #74)\n   - add support for plain lists, thanks to Aleksandar Dimitrov (closes issue\n     #81)\n   - add agenda view, many thanks to Stefan Otte (closes issue #34)\n   - move cursor to the current todo state when selecting the todo state\n     interactively (closes issue #61)\n   - add parameter scope to method settings.get\n   - add method settings.unset\n   - fix cursor positioning when selecting todo states\n   - improve date plugin\n   - update vba targets to its new name vmb\n   - demoting a newly created second level heading doesn't cause all children\n     to\n     be deleted anymore (closes issue #65)\n   - add error message for missing dependencies (closes issue #59)\n   - rename tests directory\n   - change licensing of the documentation to GNU Free Documentation License\n   - integrate orgguide (closes issue #57)\n   - replace DIRECTION_* with an enum (closes issue #56 and issue #49)\n** 0.3.1-0 <2011-08-14 Sun>\t\t\t\t\t\t\t :released:\n   - demoting a newly created second level heading doesn't cause all children\n     to be deleted anymore (closes issue #65)\n   - add error message for missing dependencies (closes issue #59)\n** 0.3.0-0 <2011-08-09 Tue>\t\t\t\t\t\t\t :released:\n   - fix completion menu popup that disappeared because of the usage of\n     vim.command (closes issue #48)\n   - implement interactive todo state selection (closes issue #5)\n   - add orgmode group to au commands in TagProperties plugin (closes issue\n     #53)\n   - allow demotion of first level headings (closes issue #27)\n   - fix encoding issues in Date plugin\n   - add general support for multiple todo sequences (closes Issue #46)\n   - fix folded text for headings containing backslashes or double quotes\n     (closes issue #26)\n   - add Document.get_todo_states() and Document.get_all_todo_states()\n   - don't confuse upper case words at the beginning of a heading with a todo\n     state (closes issue #28)\n   - fix error in setting tags (issue #25)\n   - improve split of heading (issue #24)\n   - add variable g:org_improve_split_heading to enable/disable improve the\n     split of headings (issue #24)\n   - implement shortcut for moving to the partent's next sibling (g}) (issue\n     #22)\n   - fix duplication of children when inserting a new heading (issue #20)\n   - always start insert mode when adding a new heading (issue #21)\n** 0.2.1-0 <2011-06-26 Sun>\t\t\t\t\t\t\t :released:\n   - fix encoding of todo states set by the Todo plugin (thanks to Daniel\n     Carl and kien for pointing out the issue)\n   - add documentation for remapping shortcuts\n   - add documentation for customizing syntax highlighting\n** 0.2.0-0 <2011-06-25 Sat>\t\t\t\t\t\t\t :released:\n   - initial release\n"
  },
  {
    "path": "LICENSE",
    "content": "---------------------------------------------------------------------\nAll source code is licensed under the terms of the following license:\n---------------------------------------------------------------------\n\nCopyright (C) 2010,2011 Jan Christoph Ebersbach\n\nhttp://www.e-jc.de/\n\nAll rights reserved.\n\nThe source code of this program is made available under the terms of the\nGNU Affero General Public License version 3 (GNU AGPL V3) as published\nby the Free Software Foundation.\n\nBinary versions of this program provided by Univention to you as well as\nother copyrighted, protected or trademarked materials like Logos,\ngraphics, fonts, specific documentations and configurations,\ncryptographic keys etc. are subject to a license agreement between you\nand Univention and not subject to the GNU AGPL V3.\n\nIn the case you use this program under the terms of the GNU AGPL V3, the\nprogram is provided in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public\nLicense for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nwith the Debian GNU/Linux or Univention distribution in file\n/usr/share/common-licenses/AGPL-3; if not, see\n<http://www.gnu.org/licenses/>.\n\n\n--------------------------------------------------------------------\nAll documentation found in the directories doc and documentation are\nlicensed under the terms of the following license:\n--------------------------------------------------------------------\n\ndoc/org.txt\nCopyright (C) 2010,2011 Jan Christoph Ebersbach\n\ndoc/orgguide.txt\ndocumentation/emacs_orgguide.org\ndocumentation/emacs_orgguide.texi\nCopyright (C) 2010 Free Software Foundation\n\nPermission is granted to copy, distribute and/or modify this document\nunder the terms of the GNU Free Documentation License, Version 1.3 or\nany later version published by the Free Software Foundation; with no\nInvariant Sections, with the Front-Cover texts being “A GNU Manual,” and\nwith the Back-Cover Texts as in (a) below. A copy of the license is\nincluded in the section entitled “GNU Free Documentation License.”\n\n(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and\nmodify this GNU manual. Buying copies from the FSF supports it in\ndeveloping GNU and promoting software freedom.”\n\nThis document is part of a collection distributed under the GNU Free\nDocumentation License. If you want to distribute this document\nseparately from the collection, you can do so by adding a copy of the\nlicense to the document, as described in section 6 of the license.\n"
  },
  {
    "path": "Makefile",
    "content": "PLUGIN = orgmode\nPREFIX = /usr/local\nVIMDIR = $(PREFIX)/share/vim\n\nall: build\n\nbuild:\n\n# install plugin at destination\ninstall: doc indent ftdetect ftplugin syntax\n\tfor i in doc indent ftdetect ftplugin syntax; do \\\n\t\tfind $$i -type f -name \\*.txt -o -type f -name \\*.cnf -o -type f -name \\*.py -o -type f -name \\*.vim | while read f; do \\\n\t\t\tinstall -m 0755 -d $(DESTDIR)$(VIMDIR)/$$(dirname \"$$f\"); \\\n\t\t\tinstall -m 0644 $$f $(DESTDIR)$(VIMDIR)/$$f; \\\n\t\tdone; \\\n\tdone\n\n# cleanup\nclean: documentation\n\t@find . -name \\*.pyc -o -name \\*.py,cover -exec rm {} \\;\n\t@rm -rf ${PLUGIN}.vmb ${PLUGIN}.vmb.gz tmp files\n\tcd $< && $(MAKE) $@\n\n# generate the vim ball package\n${PLUGIN}.vmb: check build_vmb.vim clean\n\t$(MAKE) DESTDIR=$(PWD)/tmp VIMDIR= install\n\tfind tmp -type f  | sed -e 's/^tmp\\///' > files\n\tcp build_vmb.vim tmp\n\tcd tmp && vim --cmd 'let g:plugin_name=\"${PLUGIN}\"' -s build_vmb.vim\n\t[ -e tmp/${PLUGIN}.vba ] && mv tmp/${PLUGIN}.vba tmp/$@ || true\n\tmv tmp/$@ .\n\n${PLUGIN}.vmb.gz: ${PLUGIN}.vmb\n\t@rm -f ${PLUGIN}.vmb.gz\n\tgzip $<\n\nvmb: ${PLUGIN}.vmb\n\nvmb.gz: ${PLUGIN}.vmb.gz\n\n${PLUGIN}.vba: ${PLUGIN}.vmb\n\tmv $< $@\n\n${PLUGIN}.vba.gz: ${PLUGIN}.vba\n\t@rm -f ${PLUGIN}.vba.gz\n\tgzip $<\n\nvba: ${PLUGIN}.vba\n\nvba.gz: ${PLUGIN}.vba.gz\n\n# run unit tests\ntest: check\n\ncheck: tests/run_tests.py\n\tcd tests && python2 run_tests.py\n\n# generate documentation\ndocs: documentation\n\tcd $< && $(MAKE)\n\n# generate a test coverage report for all python files\ncoverage:\n\t@echo \">>> Coverage depends on the package python-nose and python-coverage, make sure they are installed!\"\n\tcd tests && nosetests2 --with-coverage --cover-html .\n\n# run a static code checker\nlint:\n\t@echo \">>> Lint depends on the package pylint make sure it's installed!\"\n\tpylint --rcfile .pylintrc --disable=C0301,C0103,C0111,C0322,C0323,C0324,W0703,W0612,W0603 orgmode\n\nlintall:\n\t@echo \">>> Lint depends on the package pylint make sure it's installed!\"\n\tpylint --rcfile .pylintrc orgmode\n\n# install vim-orgmode in the .vim/bundle directory for test purposes\nVIMPLUGINDIR = $(HOME)/.vim/bundle/orgmode\n\ninstallvmb: ${PLUGIN}.vmb install_vmb.vim\n\trm -rvf ${VIMPLUGINDIR}\n\tmkdir -p \"${VIMPLUGINDIR}\"\n\tvim --cmd \"let g:installdir='${VIMPLUGINDIR}'\" -s install_vmb.vim $<\n\t@echo \"Plugin was installed in ${VIMPLUGINDIR}. Make sure you are using a plugin loader like pathegon, otherwise the ${PLUGIN} might not work properly.\"\n\ninstallvba: ${PLUGIN}.vba install_vba.vim\n\trm -rvf ${VIMPLUGINDIR}\n\tmkdir -p \"${VIMPLUGINDIR}\"\n\tvim --cmd \"let g:installdir='${VIMPLUGINDIR}'\" -s install_vba.vim $<\n\t@echo \"Plugin was installed in ${VIMPLUGINDIR}. Make sure you are using a plugin loader like pathegon, otherwise the ${PLUGIN} might not work properly.\"\n\n.PHONY: all build test check install clean vmb vmb.gz docs installvmb\n"
  },
  {
    "path": "README.org",
    "content": "* Vim-OrgMode\n\n  #+ATTR_HTML: title=\"Join the chat at https://gitter.im/jceb/vim-orgmode\"\n  [[https://gitter.im/jceb/vim-orgmode?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge][file:https://badges.gitter.im/jceb/vim-orgmode.svg]]\n  [[https://travis-ci.org/jceb/vim-orgmode][file:https://travis-ci.org/jceb/vim-orgmode.svg]]\n  [[https://codecov.io/gh/jceb/vim-orgmode][file:https://codecov.io/gh/jceb/vim-orgmode/branch/master/graph/badge.svg]]\n\n  Text outlining and task management for Vim based on [[http://orgmode.org/][Emacs' Org-Mode]].\n\n  The idea for this plugin was born by listening to the\n  [[http://twit.tv/floss136][Floss Weekly podcast]] introducing Emacs Org-Mode.\n  Org-Mode has a lot of strong features like folding, views (sparse tree) and\n  scheduling of tasks.  These are completed by hyperlinks, tags, todo states,\n  priorities aso.\n\n  vim-orgmode aims at providing the same functionality for Vim.\n\n  [[https://github.com/jceb/vim-orgmode/blob/master/examples/mylife.org][file:examples/mylife.gif]]\n\n** Features\n   Currently vim-orgmode does not support all orgmode features but is quite\n   usable. Short list of the already supported features:\n\n   - Syntax highlighting\n   - Cycle visibility of headings (folding)\n   - Navigate between headings\n   - Edit the structure of the document: add, move, promote, denote headings\n     and more\n   - Hyperlinks within vim-orgmode and outside (files, webpages, etc.)\n   - TODO list management\n   - Tags for headings\n   - Lists in alphanumeric and bullet item notation and checkbox support\n   - Basic date handling\n   - Export to other formats (via Emacs' Org-Mode)\n\n* Installation and Usage\n  Installation and usage instructions are found in the file [[doc/orgguide.txt][doc/orgguide.txt]].\n\n* License\n  Information about the license is found in file [[LICENSE]].\n\n* Changelog\n  All changes are found in file [[https://github.com/jceb/vim-orgmode/blob/master/CHANGELOG.org][CHANGELOG.org]]\n"
  },
  {
    "path": "doc/orgguide.txt",
    "content": "*orgguide.txt*          For Vim version 7.3        Last change: 2019 December 13\n\n     _  _  ____  __  __    _____  ____   ___  __  __  _____  ____  ____\n    ( \\/ )(_  _)(  \\/  )  (  _  )(  _ \\ / __)(  \\/  )(  _  )(  _ \\( ___)\n     \\  /  _)(_  )    (    )(_)(  )   /( (_-. )    (  )(_)(  )(_) ))__)\n      \\/  (____)(_/\\/\\_)  (_____)(_)\\_) \\___/(_/\\/\\_)(_____)(____/(____)\n\n\n==============================================================================\nTABLE OF CONTENTS                            *org* *org-toc* *orgguide* *orgguide-toc*\n\n    1.  About vim-orgmode guide          |orgguide-about|\n    2.  Introduction                     |orgguide-introduction|\n    3.  Installation                     |orgguide-installation|\n    4.  Document structure               |orgguide-docstructure|\n    5.  Tables                           |orgguide-tables|\n    6.  Hyperlinks                       |orgguide-hyperlinks|\n    7.  Todo items                       |orgguide-todo|\n    8.  Tags                             |orgguide-tags|\n    9.  Properties                       |orgguide-properties|\n    10. Dates and Times                  |orgguide-dates|\n    11. Capture - Refile - Archive       |orgguide-capture|\n    12. Agenda views                     |orgguide-agenda|\n    13. Export/Markup for rich export    |orgguide-export|\n    14. Publishing                       |orgguide-publishing|\n    15. Working with source code         |orgguide-source|\n    16. Miscellaneous                    |orgguide-misc|\n    17. MobileOrg                        |orgguide-mobileorg|\n    18. Customization                    |orgguide-customization|\n    19. Development                      |orgguide-development|\n    20. License vim-orgmode              |orgguide-license|\n    21. Contributors                     |orgguide-contributors|\n    22. Changelog                        |orgguide-changelog|\n    23. Links                            |orgguide-links|\n\n==============================================================================\nORG MODE GUIDE                                                  *orgguide-about*\n\nCopyright © 2010 Free Software Foundation\n\n  Permission is granted to copy, distribute and/or modify this document under\n  the terms of the GNU Free Documentation License, Version 1.3 or any later\n  version published by the Free Software Foundation; with no Invariant\n  Sections, with the Front-Cover texts being “A GNU Manual,” and with the\n  Back-Cover Texts as in (a) below. A copy of the license is included in the\n  section entitled “GNU Free Documentation License.”\n\n  (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify\n  this GNU manual. Buying copies from the FSF supports it in developing GNU\n  and promoting software freedom.”\n\n  This document is part of a collection distributed under the GNU Free\n  Documentation License. If you want to distribute this document separately\n  from the collection, you can do so by adding a copy of the license to the\n  document, as described in section 6 of the license.\n\n==============================================================================\nINTRODUCTION                                 *vim-orgmode* *orgguide-introduction*\n\nVim-orgmode: Text outlining and task management for Vim based on Emacs'\nOrg-Mode.\n\nThe idea for this plugin was born by listening to the Floss Weekly podcast\nintroducing Emacs' Org-Mode (http://twit.tv/floss136). Org-Mode has a lot of\nstrong features like folding, views (sparse tree) and scheduling of tasks.\nThese are completed by hyperlinks, tags, todo states, priorities also.\n\nVim-orgmode aims at providing the same functionality for Vim and for command\nline tools*.\n\n* WAITING for command line tools and other programs a library liborgmode is\n  provided.  It encapsulates all functionality for parsing and modifying org\n  files.\n\n------------------------------------------------------------------------------\nPreface~\n  vim-orgmode is a file type plugin for keeping notes, maintaining TODO\n  lists, and doing project planning with a fast and effective plain-text\n  system. It is also an authoring and publishing system.\n\n  This document is a copy of the orgmode-guide for emacs\n  (http://orgmode.org/) with modifications for vim. It contains all basic\n  features and commands, along with important hints for customization.\n\n  To start create a new file with the extension \".org\".\n\n------------------------------------------------------------------------------\nFeatures~\n  Currently vim-orgmode does not support all orgmode features but is quite\n  usable. Short list of the already supported features:\n\n  - Syntax highlighting\n  - Cycle visibility of headings (folding)\n  - Navigate between headings\n  - Edit the structure of the document: add, move, promote, denote headings\n    and more\n  - Hyperlinks within vim-orgmode and outside (files, webpages, etc.)\n  - TODO list management\n  - Tags for headings\n  - Lists in alphanumeric and bullet item notation and checkbox support\n  - Basic date handling\n  - Export to other formats (via emacs)\n\n------------------------------------------------------------------------------\nDefault mappings~\n                                                                  *org-mappings*\nHere is a short overview of the default mappings. They also can be invoked\nvia the 'Org' menu. Most are only usable in command mode.\n\n  Show/Hide:~\n    <TAB>           - Cycle Visibility\n\n  Editing Structure:~\n    In GVIM:~\n      <C-S-CR>        - insert heading above\n      <S-CR>          - insert heading below, taking over children\n      <CR>            - insert heading below, taking over children\n      <C-CR>          - insert heading above, after children\n    In general Vim Versions:~\n      <localleader>hN  - insert heading above\n      <localleader>hh  - insert heading below, taking over children\n      <localleader>hn  - insert heading above, after children\n\n      m}              - move heading down\n      m{              - move heading up\n      m]]             - move subtree down\n      m[[             - move subtree up\n\n      yah             - yank heading\n      dah             - delete heading\n      yar             - yank subtree\n      dar             - delete subtree\n      p               - paste subtree\n\n      >> or >ah       - demote heading\n      << or <ah       - promote heading\n      >ar             - demote subtree\n      <ar             - promote subtree\n\n  Hyperlinks:~\n    gl              - goto link (vim built-in gx would work too)\n    gyl             - yank link\n    gil             - insert new link\n\n    gn              - next link\n    go              - previous link\n\n  TODO Lists:~\n    <localleader>d  - select keyword\n    <S-Left>        - previous keyword\n    <S-Right>       - next keyword\n    <C-S-Left>      - previous keyword set\n    <C-S-Right>     - next keyword set\n\n  Plain List:~\n    <localleader>cl or <CR>     - insert plainlist item below\n    <localleader>cL or <C-S-CR> - insert plainlist item above\n\n  Checkboxes:~\n    <localleader>cc             - toggle status\n    <localleader>cn or <CR>     - insert checkbox below\n    <localleader>cN or <C-S-CR> - insert checkbox above\n\n  TAGS and properties:~\n    <localleader>st     - set tags\n\n  Dates:~\n    <localleader>sa     - insert date\n    <localleader>si     - insert inactive date\n    <localleader>pa     - insert date by using calendar selection\n    <localleader>pi     - insert inactive date by using calendar selection\n\n  Agenda:~\n    <localleader>caa    - agenda for the week\n    <localleader>cat    - agenda of all TODOs\n    <localleader>caA    - agenda for the week for current buffer\n    <localleader>caT    - agenda of all TODOs for current buffer\n\n    Not yet implemented in vim-orgmode~\n    <localleader>caL    - timeline of current buffer\n\n  Export:~\n    <localleader>ep     - export as PDF\n    <localleader>eb     - export as Beamer PDF\n    <localleader>eh     - export as HTML\n    <localleader>el     - export as LaTeX\n\n------------------------------------------------------------------------------\nInline markup~\n\n  We support org authoring markup as closely as possible\n  (we're adding two markdown-like variants for =code= and blockquotes).\n\n  Inline markup:\n>\n  *bold*\n  /italic/\n  _underline_\n  +strike-through+\n  =code=\n  ~verbatim~\n<\n\n  Note:\n  - /italic/ is rendered as reverse in most terms (works fine in gVim, though)\n  - +strike-through+ doesn't work on Vim / GVim\n  - the non-standard `code' markup is also supported\n  - =code= and ~verbatim~ are also supported as block-level markup, see below.\n\n  Ref: http://orgmode.org/manual/Emphasis-and-monospace.html\n\n------------------------------------------------------------------------------\nINSTALLATION AND UPGRADE                                 *orgguide-installation*\n\n  Installation can be done with plugin managers, e.g. vim-plug\n  (https://github.com/junegunn/vim-plug), dein.vim\n  (https://github.com/Shougo/dein.vim), pathogen.vim \n  (https://github.com/tpope/vim-pathogen) or if you're using Vim >= 8.0, you\n  can use the built-in plugin manager.\n\n  Add the following to your .vimrc, for *vim-plug* : \n>\n    Plug 'jceb/vim-orgmode'\n<\n  And for *dein.vim* : \n>\n    call dein#add('jceb/vim-orgmode')\n<\n  With pathogen, you need to run the following in your terminal:\n>\n    cd ~/.vim/bundle && \\\n    git clone https://github.com/jceb/vim-orgmode.git\n<\n  With the package feature of Vim 8, it is a bit more involved. Run the\n  following in your terminal\n>\n    mkdir -p ~/.vim/pack/git-plugins/start\n    cd ~/.vim/pack/git-plugins/start\n    git clone https://github.com/jceb/vim-orgmode\n<\n  Then, add this to your ~/.vimrc:\n>\n    packloadall\n    silent! helptags ALL\n<\n  NOTE: For some functionality vim-orgmode relies on external plugins which\n  are mentioned in suggested plugins.\n\n------------------------------------------------------------------------------\nSuggested plugins~\n\n  Universal Text Linking~\n    (http://www.vim.org/scripts/script.php?script_id=293) general support for\n    text linking. The hyperlinks feature of vim-orgmode depends on this\n    plugin.\n\n  repeat~\n    (http://www.vim.org/scripts/script.php?script_id=2136)\n    Repeat actions that would not be repeatable otherwise. This plugin is\n    needed when you want to repeat the previous orgmode action.\n\n  taglist~\n    (http://www.vim.org/scripts/script.php?script_id=273)\n    Display tags for the currently edited file. Vim-orgmode ships with support\n    for displaying the heading structure and hyperlinks in the taglist plugin.\n\n  tagbar~\n    (http://www.vim.org/scripts/script.php?script_id=3465)\n    A new approach to displaying tags for the currently edited file.\n    Vim-orgmode ships with support for displaying the heading structure and\n    hyperlinks in the tagbar plugin.\n\n  speeddating~\n    (http://www.vim.org/scripts/script.php?script_id=2120)\n    In-/decrease dates the vim way: C-a and C-x. Dates and times in the\n    orgmode format can be in-/decreased if this plugins is installed.\n\n  Narrow Region~\n    (http://www.vim.org/scripts/script.php?script_id=3075)\n    Emulation of Emacs' Narrow Region feature. It might be useful when dealing\n    with large orgmode files.\n\n  pathogen~\n    (http://www.vim.org/scripts/script.php?script_id=2332)\n    Easy management of multiple vim plugins.\n\n  calendar~\n    (https://github.com/mattn/calendar-vim)\n    This plugin will create a calendar window for timestamp insertion.\n\n  SyntaxRange~\n    (http://www.vim.org/scripts/script.php?script_id=4168)\n    Use proper syntax highlighting for code blocks such as:\n>\n    #+BEGIN_SRC cpp\n    int i = 1;\n    #+END_SRC\n<\n\n------------------------------------------------------------------------------\nFeedback~\n   If you find problems with vim-orgmode, or if you have questions, remarks,\n   or ideas about it, please create a ticket on\n   https://github.com/jceb/vim-orgmode\n\n==============================================================================\nDOCUMENT STRUCTURE                                      *orgguide-docstructure*\n\n------------------------------------------------------------------------------\nOutlines~\n  Outlines allow a document to be organized in a hierarchical structure, which\n  (at least for me) is the best representation of notes and thoughts. An\n  overview of this structure is achieved by folding (hiding) large parts of\n  the document to show only the general document structure and the parts\n  currently being worked on. vim-orgmode greatly simplifies the use of\n  outlines by compressing the entire show/hide functionality into a single\n  command, <Plug>OrgToggleFolding, which is bound to the <TAB> key.\n\n------------------------------------------------------------------------------\nHeadlines~\n\n  Headlines define the structure of an outline tree. The headlines in\n  vim-orgmode start with one or more stars, on the left margin. For example:\n>\n  * Top level headline\n  ** Second level\n  *** 3rd level\n      some text\n  *** 3rd level\n      more text\n\n  * Another top level headline\n<\n\n  Some people find the many stars too noisy and would prefer an outline\n  that has whitespace followed by a single star as headline starters.\n  |g:org_heading_shade_leading_stars| describes a setup to realize this.\n\n  Body text under headings is not indented by default, but you can control\n  this  with the  |g:org_indent| variable.\n\n------------------------------------------------------------------------------\nText objects~\n\n  Vim offers a mighty feature called |text-objects|. A text object is bound to\n  a certain character sequence that can be used in combination with all kinds\n  of editing and selection tasks.\n\n  vim-orgmode implements a number of text objects to make editing org files\n  easier:\n\n  ih                    inner heading, referring to the current heading\n                        excluding the heading level characters (*)\n  ah                    a heading, referring to the current heading including\n                        everything\n  ir                    inner subtree, starting with the current heading\n  ar                    a subtree, starting with the current heading\n  Oh                    inner outer heading, referring to the parent\n  Or                    inner outer heading, including subtree, referring to\n                        the parent\n  OH                    an outer heading\n  OT                    an outer subtree\n\n  Motions can be used like text objects as well. See |orgguide-motion|.\n\n------------------------------------------------------------------------------\nVisibility cycling~\n  Outlines make it possible to hide parts of the text in the buffer.\n  vim-orgmode uses just two commands, bound to <Tab> and <S-Tab> to change the\n  visibility in the buffer.\n\n  <Tab>       or                                *orgguide-Tab* or *orgguide-S-Tab*\n  <S-Tab>               Subtree cycling: Rotate current subtree among the\n                        states\n>\n  ,-> FOLDED -> CHILDREN -> SUBTREE --.\n  '-----------------------------------'\n<\n\n  When called with the shift key, global cycling is invoked.\n\n  <LocalLeader>,    or      *orgguide-<LocalLeader>,* or *orgguide-<LocalLeader>.*\n  <LocalLeader>.        Global cycling: Rotate the entire buffer among the\n                        states. The same can be achieved by using the\n                        keybindings zm and zr.\n>\n  ,-> OVERVIEW -> CONTENTS -> SHOW ALL --.\n  '--------------------------------------'\n<\n\n  Vim-orgmode doesn't implement the following functionality, yet.~\n  When Emacs first visits an org file, the global state is set to\n  OVERVIEW, i.e. only the top level headlines are visible. This can be\n  configured through the variable =org-startup-folded=, or on a per-file\n  basis by adding a startup keyword =overview=, =content=, =showall=, like\n  this:\n>\n   #+STARTUP: content\n<\n------------------------------------------------------------------------------\nMotion~\n                                                               *orgguide-motion*\n  The following commands jump to other headlines in the buffer.\n\n  }                     Next heading.\n\n  {                     Previous heading.\n\n  ]]                    Next heading same level.\n\n  [[                    Previous heading same level.\n\n  g{                    Backward to higher level heading.\n\n  g}                    Forward to higher level heading.\n\n------------------------------------------------------------------------------\nStructure editing~\n\n                                                                *orgguide-S-CR*\n  <S-CR>                Insert new heading with same level as current. If the\n                        cursor is in a plain list item, a new item is created\n                        (see section [[#Plain-lists][Plain lists]]). When this\n                        command is used in the middle of a line, the line is\n                        split and the rest of the line becomes the new\n                        headline.\n\n  Not yet implemented in vim-orgmode~\n  M-S-<CR>              Insert new TODO entry with same level as current\n                        heading.\n\n  <Tab>         or\n  <S-Tab>               In a new entry with no text yet, <Tab> and <S-Tab>\n                        will cycle through reasonable levels.\n\n  <<            or                              *orgguide-<<* or *orgguide-CTRL-d*\n  <C-d> (insert mode)   Promote current heading by one level.\n\n  >>            or                              *orgguide->>* or *orgguide-CTRL-t*\n  <C-t> (insert mode)   Demote current heading by one level.\n\n                                                                  *orgguide-<[[*\n  <[[                   Promote the current subtree by one level.\n\n                                                                  *orgguide->]]*\n  >]]                   Demote the current subtree by one level.\n\n                                                                   *orgguide-m{*\n  m{                    Move heading up (swap with previous/next subtree of\n                        same level).\n\n                                                                   *orgguide-m}*\n  m}                    Move heading down (swap with previous/next subtree of\n                        same level).\n\n                                                                  *orgguide-m[[*\n  m[[                   Move subtree up (swap with previous/next subtree of\n                        same level).\n\n                                                                  *orgguide-m]]*\n  m]]                   Move subtree down (swap with previous/next subtree of\n                        same level).\n\n  Not yet implemented in vim-orgmode~\n  C-c C-w                Refile entry or region to a different location. See\n                        section [[#Refiling-notes][Refiling notes]].\n\n                                                           *orgguide-<Leader>nr*\n  <Leader>nr            Narrow buffer to current subtree / widen it again\n                        (only if NarrowRegion plugin is installed)\n\n  When there is an active region (Transient Mark mode), promotion and demotion\n  work on all headlines in the region.\n\n------------------------------------------------------------------------------\nSparse trees~\n    Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nPlain lists~\n                                                           *orgguide-plain-list*\n  Within an entry of the outline tree, hand-formatted lists can provide\n  additional structure.\n\n  They also provide a way to create lists of checkboxes (see section\n  |orgguide-checkboxes|).\n\n  vim-orgmode supports editing such lists, and the exporter (see section\n  |orgguide-export|) parses and formats them.\n\n  vim-orgmode knows ordered lists, unordered lists, and description lists:\n  - 'Unordered' list items start with ‘-’, ‘+’, or ‘*’ as bullets.\n  - 'Ordered' list items start with ‘1.’ or ‘1)’.\n  - 'Description' list use ‘ :: ’ to separate the 'term' from the\n    description.\n\n  Items belonging to the same list must have the same indentation on the\n  first line. An item ends before the next line that is indented like its\n  bullet/number, or less. A list ends when all items are closed, or before\n  two blank lines. An example:\n>\n  ** Lord of the Rings\n     My favorite scenes are (in this order)\n     1. The attack of the Rohirrim\n     2. Eowyn's fight with the witch king\n        + this was already my favorite scene in the book\n        + I really like Miranda Otto.\n     Important actors in this film are:\n     - Elijah Wood :: He plays Frodo\n     - Sean Austin :: He plays Sam, Frodo's friend.\n<\n\n------------------------------------------------------------------------------\nFootnotes~\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nTABLES                                                         *orgguide-tables*\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nHYPERLINKS                                                 *orgguide-hyperlinks*\n\nNOTE: The |utl| plugin is used for this feature and needs to be installed.\n      http://www.vim.org/scripts/script.php?script_id=293\n\nLike HTML, vim-orgmode provides links inside a file, external links to other\nfiles, Usenet articles, emails, and much more.\n\n------------------------------------------------------------------------------\nLink format~\n                                                           *orgguide-linkformat*\n  vim-orgmode will recognize plain URL-like links and activate them as links.\n  The general link format, however, looks like this:\n>\n    [[link][description]]       or alternatively           [[link]]\n<\n\n  If vim was compiled with |+conceal|, vim-orgmode will shorten this format to\n  just display 'description' or 'link' once the link was completely entered\n  (that is, if all brackets are present) and you've left insert mode or\n  you're editing another line.\n  To edit the invisible ‘link’ part, go into insert mode, or call the\n  'Insert/edit Link' command by pressing 'gil'.\n\n------------------------------------------------------------------------------\nInternal links~\n  Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nExternal links~\n\n  |utl| supports links to files and websites. Others can be added by extending\n  utl (see |utl-smartSamples|).  External links are URL-like locators. They\n  start with a short identifying string followed by a colon. There can be no\n  space after the colon. Here are some examples:\n>\n    http://www.astro.uva.nl/~dominik          on the web\n    file:/home/dominik/images/jupiter.jpg     file, absolute path\n    /home/dominik/images/jupiter.jpg          same as above\n<\n\n  A link should be enclosed in double brackets and may contain a descriptive\n  text to be displayed instead of the URL (see section |orgguide-linkformat|),\n  for example:\n>\n    [[http://www.vim.org/][VIM]]\n<\n\n------------------------------------------------------------------------------\nHandling links~\n\n  vim-orgmode provides methods to create a link in the correct syntax, to\n  insert it into an org file, and to follow the link.\n\n  Not yet implemented in vim-orgmode~\n  C-c l                 Store a link to the current location. This is a\n                        /global/ command (you must create the key binding\n                        yourself) which can be used in any buffer to create a\n                        link. The link will be stored for later insertion into\n                        an org buffer (see below).\n\n                                                                  *orgguide-gil*\n  gil                   Insert a link. This prompts for a link to be inserted\n                        into the buffer. You can just type a link, or use\n                        history keys <Up> and <Down> to access stored links.\n                        You will be prompted for the description part of the\n                        link. File name completion is enabled to link to a\n                        local file. In addition vim-orgmode provides the\n                        command :OrgHyperlinkInsert to insert a link from\n                        command line.\n\n  gil                   When the cursor is on an existing link, gil allows you\n                        to edit the link and description parts of the link.\n\n  Not yet implemented in vim-orgmode~\n  C-c C-o or mouse-1 or mouse-2  Open link at point.\n\n  Not yet implemented in vim-orgmode~\n  C-c &                 Jump back to a recorded position. A position is\n                        recorded by the commands following internal links, and\n                        by C-c %. Using this command several times in direct\n                        succession moves through a ring of previously recorded\n                        positions.\n\n------------------------------------------------------------------------------\nTargeted links~\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nTODO ITEMS                                                       *orgguide-todo*\n\nvim-orgmode does not maintain TODO lists as separate documents. Instead, TODO\nitems are an integral part of the notes file, because TODO items usually come\nup while taking notes! With vim-orgmode, simply mark any entry in a tree as\nbeing a TODO item. In this way, information is not duplicated, and the entire\ncontext from which the TODO item emerged is always present.\n\nOf course, this technique for managing TODO items scatters them throughout\nyour notes file. vim-orgmode compensates for this by providing methods to give\nyou an overview of all the things that you have to do.\n\n------------------------------------------------------------------------------\nUsing TODO states~\n\n  Any headline becomes a TODO item when it starts with the word ‘TODO’,\n  for example:\n>\n      *** TODO Write letter to Sam Fortune\n<\n\n  The most important commands to work with TODO entries are:\n\n  <LocalLeader>ct       Rotate the TODO state of the current item among. See\n                        |orgguide-tags-settings|for more information.\n>\n       ,-> (unmarked) -> TODO -> DONE --.\n       '--------------------------------'\n<\n\n  Not yet implemented in vim-orgmode~\n  The same rotation can also be done “remotely” from the timeline and\n  agenda buffers with the t command key (see section\n  |orgguide-agenda-commands|).\n\n  <S-right> or <S-left> Select the following/preceding TODO state, similar to\n                        cycling.\n\n  Not yet implemented in vim-orgmode~\n  C-c / t               View TODO items in a /sparse tree/ (see section\n                        [[#Sparse-trees][Sparse trees]]). Folds the buffer,\n                        but shows all TODO items and the headings hierarchy\n                        above them.\n\n  <LocalLeader>cat      Show the global TODO list. This collects the TODO\n                        items from all agenda files (see section\n                        |orgguide-agenda-views|) into a single buffer.\n\n  Not yet implemented in vim-orgmode~\n  S-M-<CR>              Insert a new TODO entry below the current one.\n\n------------------------------------------------------------------------------\nMulti-state workflows~\n\n  You can use TODO keywords to indicate different 'sequential' states in\n  the process of working on an item, for example:\n>\n  :let g:org_todo_keywords=['TODO', 'FEEDBACK', 'VERIFY', '|', 'DONE', 'DELEGATED']\n<\n\n  The vertical bar separates the TODO keywords (states that 'need action')\n  from the DONE states (which need 'no further action'). If you don’t\n  provide the separator bar, the last state is used as the DONE state.\n  With this setup, the command <S-Right> will cycle an entry from TODO to\n  FEEDBACK, then to VERIFY, and finally to DONE and DELEGATED.\n\n  Sometimes you may want to use different sets of TODO keywords in\n  parallel. For example, you may want to have the basic TODO/DONE, but\n  also a workflow for bug fixing, and a separate state indicating that an\n  item has been canceled (so it is not DONE, but also does not require\n  action). Your setup would then look like this:\n>\n  :let g:org_todo_keywords = [['TODO(t)', '|', 'DONE(d)'],\n      \\ ['REPORT(r)', 'BUG(b)', 'KNOWNCAUSE(k)', '|', 'FIXED(f)'],\n      \\ ['CANCELED(c)']]\n<\n  The keywords should all be different, this helps vim-orgmode to keep track\n  of which subsequence should be used for a given entry. The example also\n  shows how to define keys for fast access of a particular state, by\n  adding a letter in parenthesis after each keyword - you will be prompted\n  for the key after pressing <LocalLeader>d.\n\n                                                       *orgguide-<LocalLeader>d*\n  <LocalLeader>d        prompt for fast access of a todo state\n\n  Not yet implemented in vim-orgmode~\n  To define TODO keywords that are valid only in a single file, use the\n  following text anywhere in the file.\n\n>\n  #+BEGIN_EXAMPLE\n      #+TODO: TODO(t) | DONE(d)\n      #+TODO: REPORT(r) BUG(b) KNOWNCAUSE(k) | FIXED(f)\n      #+TODO: | CANCELED(c)\n  #+END_EXAMPLE\n<\n\n  After changing one of these lines, use C-c C-c with the cursor still in\n  the line to make the changes known to vim-orgmode.\n\n------------------------------------------------------------------------------\nProgress logging~\n  Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nPriorities~\n  Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nBreaking tasks down into subtasks~\n  Not fully implemented in vim-orgmode~\n\nIt is often advisable to break down large tasks into smaller, manageable\nsubtasks. You can do this by creating an outline tree below a TODO item,\nwith detailed subtasks on the tree. To keep the overview over the\nfraction of subtasks that are already completed, insert either ‘[/]’ or\n‘[%]’ anywhere in the headline. These cookies will be updated each time\nthe TODO status of a child changes, or when pressing C-c C-c on the\ncookie. For example:\n\n>\n    * Organize Party [33%]\n    ** TODO Call people [1/2]\n    *** TODO Peter\n    *** DONE Sarah\n    ** TODO Buy food\n    ** DONE Talk to neighbor\n<\n\n<localleader>c#\t        Update the checkboxes status of current heading. It\n                        also update the heading status too.\n\n------------------------------------------------------------------------------\nCheckboxes~\n                                                           *orgguide-checkboxes*\n\nEvery item in a plain list (see section |orgguide-plain-list|)\ncan be made into a checkbox by starting it with the string ‘[ ]’.\nCheckboxes are not included into the global TODO list, so they are often\ngreat to split a task into a number of simple steps. Here is an example\nof a checkbox list.\n\n>\n    * TODO Organize party [1/3]\n      - [-] call people [1/2]\n        - [ ] Peter\n        - [X] Sarah\n      - [X] order food\n      - [ ] think about what music to play\n<\n\nCheckboxes work hierarchically, so if a checkbox item has children that\nare checkboxes, toggling one of the children checkboxes will make the\nparent checkbox reflect if none, some, or all of the children are\nchecked.\n\nThe following commands work with checkboxes:\n\n<localleader>cc         Toggle checkbox status or (with prefix arg) checkbox\n                        presence at point.\n\n<localleader>cn    or\n<CR> or <S-CR>          Insert a new checkbox below current line.\n\n<localleader>cN    or\n<C-S-CR>                Insert a new checkbox above current line.\n\n==============================================================================\nTAGS                                                             *orgguide-tags*\n\nAn excellent way to implement labels and contexts for cross-correlating\ninformation is to assign 'tags' to headlines. vim-orgmode has extensive\nsupport for tags.\n\nEvery headline can contain a list of tags; they occur at the end of the\nheadline. Tags are normal words containing letters, numbers, ‘_’, and\n‘@’. Tags must be preceded and followed by a single colon, e.g.,\n‘:work:’. Several tags can be specified, as in ‘:work:urgent:’. Tags\nwill by default be in bold face with the same color as the headline.\n\n------------------------------------------------------------------------------\nTag inheritance~\n                                                     *orgguide-tags-inheritance*\n  Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nSetting tags~\n                                                        *orgguide-tags-settings*\n  Tags can simply be typed into the buffer at the end of a headline. After\n  a colon, <TAB> offers completion on tags. There is also a special\n  command for inserting tags:\n\n                                                      *orgguide-<LocalLeader>st*\n  <LocalLeader>st       Enter new tags for the current headline. vim-orgmode\n                        will either offer completion or a special single-key\n                        interface for setting tags, see below.  After pressing\n                        <CR>, the tags will be inserted and aligned to\n                        'org_tags_column'.\n\n                                                      *orgguide-<LocalLeader>ft*\n  <LocalLeader>ft       Find tags in the current file.\n\n  vim-orgmode will support tag insertion based on a 'list of tags'. By default\n  this list is constructed dynamically, containing all tags currently used\n  in the buffer.\n\n------------------------------------------------------------------------------\nTag searches~\n                                                          *orgguide-tags-search*\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nPROPERTIES                                                 *orgguide-properties*\n\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nDATES AND TIMES                                                 *orgguide-dates*\n\nTo assist project planning, TODO items can be labeled with a date and/or\na time. The specially formatted string carrying the date and time\ninformation is called a 'timestamp' in vim-orgmode.\n\n------------------------------------------------------------------------------\nTimestamps~\n\n  A timestamp is a specification of a date (possibly with a time or a range of\n  times) in a special format, either <2003-09-16 Tue> or <2003-09-16 Tue\n  09:39> or <2003-09-16 Tue 12:00-12:30>. A timestamp can appear anywhere in\n  the headline or body of an org tree entry. Its presence causes entries to\n  be shown on specific dates in the agenda (see section |orgguide-agenda|). We\n  distinguish:\n\n  Plain timestamp; Event; Appointment ~\n    A simple timestamp just assigns a date/time to an item. This is just like\n    writing down an appointment or event in a paper agenda.\n>\n    * Meet Peter at the movies <2006-11-01 Wed 19:15>\n    * Discussion on climate change <2006-11-02 Thu 20:00-22:00>\n<\n  Timestamp with repeater interval ~\n    Not yet implemented in vim-orgmode~\n\n  Diary-style sexp entries ~\n    Not yet implemented in vim-orgmode~\n\n  Time/Date range~\n    Two timestamps connected by ‘--’ denote a range.\n>\n    ** Meeting in Amsterdam\n       <2004-08-23 Mon>--<2004-08-26 Thu>\n<\n  Inactive timestamp~\n    Just like a plain timestamp, but with square brackets instead of angular\n    ones. These timestamps are inactive in the sense that they do 'not'\n    trigger an entry to show up in the agenda.\n>\n    * Gillian comes late for the fifth time [2006-11-01 Wed]\n<\n------------------------------------------------------------------------------\nCreating timestamps~\n\n  For vim-orgmode to recognize timestamps, they need to be in the specific\n  format. All commands listed below produce timestamps in the correct format.\n\n                                                      *orgmode-<LocalLeader>-sa*\n  <LocalLeader>sa       Prompt for a date and insert a corresponding\n                        timestamp.\n\n                        Not yet implemented in vim-orgmode~\n                        When the cursor is at an existing timestamp in the\n                        buffer, the command is used to modify this timestamp\n                        instead of inserting a new one.\n\n                        Not yet implemented in vim-orgmode~\n                        When this command is used twice in succession, a time\n                        range is inserted. With a prefix, also add the current\n                        time.\n\n                                                       *orgmode-<LocalLeader>si*\n  <LocalLeader>si       Like |orgmode-<LocalLeader>-sa|, but insert an inactive\n                        timestamp that will not cause an agenda entry.\n\n                                              *orgmode-ctrl-a* or *orgmode-ctrl-x*\n  CTRL-A or CTRL-X      Change the item under the cursor in a timestamp.\n                        The cursor can be on a year, month, day, hour or\n                        minute.  NOTE: The plugin 'speeddating' should be\n                        installed for this feature.\n\n                        Not yet implemented in vim-orgmode~\n                        When the timestamp contains a time range like\n                        ‘15:30-16:30’, modifying the first time will also\n                        shift the second, shifting the time block with\n                        constant length.  To change the length, modify the\n                        second time.\n\n  When vim-orgmode prompts for a date/time, it will accept any string\n  containing some date and/or time information, and intelligently interpret\n  the string, deriving defaults for unspecified information from the current\n  date and time.\n    Example~\n      If the current date is <2016-06-14 Tue>, entering +3 at the prompt will\n      insert the date <2016-06-17 Fri>, entering sat will insert date\n      <2016-06-18 Sat>\n\n  You can also select a date in the pop-up calendar.\n  NOTE: The plugin 'calendar' should be installed for this feature.\n\n                                                       *orgmode-<LocalLeader>pa*\n  <LocalLeader>pa\t      Open a calendar and prompt a user selected date, then\n                        insert a corresponding timestamp.\n\n                                                       *orgmode-<LocalLeader>pi*\n  <LocalLeader>pi\t      Like |orgmode-<LocalLeader>-pa|, but insert an inactive\n                        timestamp that will not cause an agenda entry.\n\n------------------------------------------------------------------------------\nDeadlines and scheduling~\n  Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nClocking work time~\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nCAPTURE - REFILE - ARCHIVE                                    *orgguide-capture*\n\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nAGENDA VIEWS                                                   *orgguide-agenda*\n\nDue to the way vim-orgmode works, TODO items, time-stamped items, and tagged\nheadlines can be scattered throughout a file or even a number of files. To get\nan overview of open action items, or of events that are important for a\nparticular date, this information must be collected, sorted and displayed in\nan organized way. There are several different views, see below.\n\nThe extracted information is displayed in a special agenda buffer. This\nbuffer is read-only.\n\nNot yet implemented in vim-orgmode~\n... but provides commands to visit the corresponding locations in the original\norg files, and even to edit these files remotely.  Remote editing from the\nagenda buffer means, for example, that you can change the dates of deadlines\nand appointments from the agenda buffer. The commands available in the Agenda\nbuffer are listed in |orgguide-agenda-commands|.\n\n- |orgguide-agenda-files|          Files being searched for agenda information\n- |orgguide-agenda-dispatcher|     Keyboard access to agenda views\n- |orgguide-agenda-views|          What is available out of the box?\n- |orgguide-agenda-commands|       Remote editing of org trees\n- |orgguide-agenda-custom|         Defining special searches and views\n\n------------------------------------------------------------------------------\nAgenda files~\n                                      *g:org_agenda_files* *orgguide-agenda-files*\n  Default: []\n  The information to be shown is normally collected from all 'agendafiles',\n  the files listed in the variable g:org_agenda_files.\n\n  You can change the list of agenda files like this:\n>\n    let g:org_agenda_files = ['~/org/index.org', '~/org/project.org']\n<\n\n  Also globbing is allowed. This makes it easy to use ALL *.org files in a\n  folder. Using all *.org files in ~/org/ is done like this:\n>\n    let g:org_agenda_files = ['~/org/*.org']\n<\n\n  WARNING: This might be slow if you have a lot of org files.\n\n------------------------------------------------------------------------------\nThe agenda dispatcher ~\n                                                    *orgguide-agenda-dispatcher*\n  Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nThe built-in agenda views ~\n                                                         *orgguide-agenda-views*\n\n  The weekly/daily agenda~\n    The purpose of the weekly/daily 'agenda' is to act like a page of a\n    paper agenda, showing all the tasks for the current week or day.\n\n                                                     *orgguide-<LocalLeader>caa*\n    <LocalLeader>caa    Compile an agenda for the current week from a list of\n                        org files. The agenda shows the entries for each day.\n\n  The global TODO list~\n    The global TODO list contains all unfinished TODO items formatted and\n    collected into a single place.\n\n    Not yet implemented in vim-orgmode~\n    Remote editing of TODO items lets you change the state of a TODO entry\n    with a single key press. The commands available in the TODO list are\n    described in |agenda-commands|\n\n                                                     *orgguide-<LocalLeader>cat*\n    <LocalLeader>cat    Show the global TODO list. This collects the TODO\n                        items from all agenda files into a single buffer.\n\n    Not yet implemented in vim-orgmode~\n                                                     *orgguide-<LocalLeader>caT*\n    <LocalLeader>caT    Like the above, but allows selection of a specific\n                        TODO keyword.\n\n  Matching tags and properties~\n    Not yet implemented in vim-orgmode~\n\n  Timeline for a single file~\n    The timeline summarizes all time-stamped items from a single vim-orgmode\n    file in a /time-sorted view/. The main purpose of this command is to\n    give an overview over events in a project.\n\n                                                     *orgguide-<LocalLeader>caL*\n    <LocalLeader>caL    Show a time-sorted view of the vim-orgmode, with all\n                        time-stamped items.\n\n  Search view~\n    Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nCommands in the agenda buffer~\n                                                      *orgguide-agenda-commands*\n  Entries in the agenda buffer are linked back to the org file where they\n  originate. Commands are provided to show and jump to the\n  original entry location, and to edit the org files “remotely” from the\n  agenda buffer.\n\n  Not yet implemented in vim-orgmode~\n  only partly implemented\n\n  Motion~\n    Not yet implemented in vim-orgmode~\n\n  View/Go to org file~\n                                                           *orgguide-agenda-Tab*\n    <Tab>               Go to the original location of the item in an\n                        alternative window.\n\n                                                            *orgguide-agenda-CR*\n    <CR>                Go to the original location of the item and stay in\n                        the same/the agenda window.\n\n                                                          *orgguide-agenda-S-CR*\n    <S-CR>              Go to the original location of the item in a new split\n                        window.\n\n    Not yet implemented in vim-orgmode~\n\n  Change display~\n    Not yet implemented in vim-orgmode~\n\n------------------------------------------------------------------------------\nCustom agenda views~\n                                                        *orgguide-agenda-custom*\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nEXPORTING                                                      *orgguide-export*\n\nNOTE: vim-orgmode relies on Emacs for this feature. Emacs _and_ Emacs'\n      org-mode need to be installed! For PDF export a Latex environment\n      is needed as well!\n\nvim-orgmode documents can be exported into a variety of other formats:\nASCII export for inclusion into emails, HTML to publish on the web,\nLaTeX/PDF for beautiful printed documents and DocBook to enter the world\nof many other formats using DocBook tools. There is also export to\niCalendar format so that planning information can be incorporated into\ndesktop calendars.\n\nCurrently, the export to pdf, html, latex and markdown is supported via the\nfollowing commands and the 'export' menu:\n>\n  :OrgExportToPDF\n  :OrgExportToBeamerPDF\n  :OrgExportToHTML\n  :OrgExportToLaTeX\n  :OrgExportToMarkdown\n<\n\nMake sure that you have configured your emacs accordingly, as for instance\nthe markdown exporter is not loaded by default. To load it, add\n\n>\n (eval-after-load \"org\"\n     '(require 'ox-md nil t))\n<\n\nto your init.el. Make also sure to specify your path by using the\n|g:org_export_init_script| option.\n\n                                                            *g:org_export_emacs*\nDefault: \"/usr/bin/emacs\"\nPath to Emacs executable. Example:\n>\n  :let g:org_export_emacs=\"~/bin/emacs\"\n<\n\n                                                          *g:org_export_verbose*\nDefault: 0\nIf set, Emacs' export output is displayed.\n>\n  :let g:org_export_verbose=1\n<\n\n                                                      *g:org_export_init_script*\nDefault: \"\"\nFor the export via Emacs a separate configuration file can be sourced to\ndetermine Emacs' export behavior. Examples:\n\nSource the ~/.emacs configuration file:\n>\n  :let g:org_export_init_script=\"~/.emacs\"\n<\n\nOr source a different file:\n>\n  :let g:org_export_init_script=\"~/.emacs_org_init\"\n<\n\n==============================================================================\nPUBLISHING                                                 *orgguide-publishing*\n\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nWORKING WITH SOURCE CODE                                       *orgguide-source*\n\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nMISCELLANEOUS                                                    *orgguide-misc*\n\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nMOBILEORG                                                   *orgguide-mobileorg*\n\n  Not yet implemented in vim-orgmode~\n\n==============================================================================\nCUSTOMIZATION                                           *orgguide-customization*\n\n------------------------------------------------------------------------------\nRemapping shortcuts~\n  vim-orgmode provides an easy way for remapping the default keyboard\n  shortcuts. For this task it relies on vim's <Plug> mappings. All shortcuts\n  of vim-orgmode are accessible by <Plug>s.\n\n  To change a keyboard shortcut the name of the related <Plug> is needed.\n  First we need to look up the current mapping in the Org menu. The following\n  command reveals the <Plug>'s name:\n>\n  :map <current_mapping>\n<\n\n  The result should look something like this:\n>\n  :map ,t\n  n ,t @<Plug>OrgSetTags\n<\n\n  Now we can create an alternate mapping:\n>\n  nmap <new_mapping> <the_plug>\n<\n\n  To change the mapping for editing tags to <leader>t the vimrc entry would\n  look like this:\n>\n  nmap <leader>t @<Plug>OrgSetTags\n<\n\n------------------------------------------------------------------------------\nAlternate behavior~\n  vim-orgmode provides some variables for users to customize certain behaviors\n  of their orgmode if so desired.\n\n                                                      *g:org_prefer_insert_mode*\n  Default: 1\n  Defines if vim-orgmode will automatically jump into Insert Mode after a new\n  heading/checkbox/plainlist instance is created through keyboard bindings. If\n  value is set to 0, orgmode will retain it's original mode.\n  Example:\n>\n  let org_prefer_insert_mode = 1\n<\n\n------------------------------------------------------------------------------\nsyntax highlighting and indentation~\n  Syntax highlighting is customizable to fit nicely with the user's\n  colorscheme.\n\n                                                      *g:org_aggressive_conceal*\n  Default: 0\n  Defines if format indicating characters for inline markups(bold, italic,\n  inline code, verbatims, in-file hyper-link, etc.) are displayed. Format\n  indicating characters will be concealed if value is `1`, rendering a much\n  cleaner view. However, since this feature is newly introduced(<2016-04-08>)\n  and still need further testing. It is inactive by default. Example:\n>\n  let g:org_aggressive_conceal = 0\n<\n\n                                                *g:org_heading_highlight_colors*\n  Default: ['Title', 'Constant', 'Identifier', 'Statement', 'PreProc', 'Type',\n          \\ 'Special']\n  Define the highlighting colors/group names for headings. Example:\n>\n  let g:org_heading_highlight_colors = ['Title', 'Constant', 'Identifier',\n    \\   'Statement', 'PreProc', 'Type', 'Special']\n<\n\n                                                *g:org_heading_highlight_levels*\n  Default: len(g:org_heading_highlight_colors)\n  Define the number of levels of highlighting. If this number is bigger than\n  the list of colors defined in of g:org_heading_highlight_colors the colors\n  of g:org_heading_highlight_colors get repeated. Example:\n>\n  let g:org_heading_highlight_levels = len(g:org_heading_highlight_colors)\n<\n\n                                             *g:org_heading_shade_leading_stars*\n  Default: 1\n  Defines if leading stars are displayed in the color of the heading or if a\n  special NonText highlighting is used that hides them from user. Example:\n>\n  let g:org_heading_shade_leading_stars = 1\n<\n\n                                                           *g:org_todo_keywords*\n  Default: ['TODO', '|', 'DONE']\n  Defines the keywords that are highlighted in headings. For more information\n  about this variable, please consult the org-mode documentation\n  (http://orgmode.org/org.html#index-org_002dtodo_002dkeywords-511). Example:\n>\n  let g:org_todo_keywords = ['TODO', '|', 'DONE']\n<\n\n                                                      *g:org_todo_keyword_faces*\n  Default: []\n  Defines special faces (styles) for displaying g:org_todo_keywords. Please\n  refer to vim documentation (topic |attr-list|) for allowed values for\n  :weight, :slant, :decoration. Muliple colors can be separated by comma for\n  :foreground and :background faces to provide different colors for GUI and\n  terminal mode. Example:\n>\n  let g:org_todo_keyword_faces = []\n<\n\n                                                                  *g:org_indent*\n  Default: 0\n  Defines if body text is indented. By default, text is not indented according\n  to heading level (heading.level + 1). You can enable it by setting:\n>\n  let g:org_indent = 1\n<\n\n  Syntax Highlighting Examples~\n    Define an additionally keyword 'WAITING' and set the foreground color to\n    'cyan'. Define another keyword 'CANCELED' and set the foreground color to\n    red, background to black and the weight to normal, slant to italc and\n    decoration to underline:\n\n>\n    let g:org_todo_keywords = [['TODO', 'WAITING', '|', 'DONE'],\n      \\   ['|', 'CANCELED']]\n    let g:org_todo_keyword_faces = [['WAITING', 'cyan'], ['CANCELED',\n      \\   [':foreground red', ':background black', ':weight bold',\n      \\   ':slant italic', ':decoration underline']]]\n<\n\n==============================================================================\nDEVELOPMENT                                               *orgguide-development*\n\nThe development of vim-orgmode is coordinated via github:\n  https://github.com/jceb/vim-orgmode\n\nIf you like this project, have questions, suggestions or problems, simply drop\nus a line and open an issue. Patches are very welcome!\n\nHere is a quick start about the vim-orgmode development.\n\n------------------------------------------------------------------------------\nStructure and Source Code~\n  The majority of the source code is stored in folder ftplugin/orgmode. This\n  is where the actual functionality of the plugin is located.\n\n  I choose to implement vim-orgmode mainly in Python. I hope this will ease\n  the implementation especially with the functionality of the Python standard\n  library at hand.\n\n  Right below the directory ftplugin/orgmode the basic implementation of\n  vim-orgmode is found. This basic functionality provides everything for\n  higher level implementations that modify the buffer, provide a menu and\n  keybindings to the user and everything else that is needed.\n\n  Below the directory ftplugin/orgmode/plugins the plugins are located. Every\n  plugin must provide a class equal to its filename with the .py-extension.\n  An example for a plugin can be found in file\n  ftplugin/orgmode/plugins/Example.py.\n\n                                                                 *g:org_plugins*\n  Default: ['ShowHide', '|', 'Navigator', 'EditStructure', '|', 'Hyperlinks',\n          \\ '|', 'Todo', 'TagsProperties', 'Date', 'Agenda', 'Misc', '|',\n          \\ 'Export']\n  Every plugin must be enabled by the user by setting the g:org_plugins\n  variable. By default all shipped plugins are enabled. Example:\n>\n    let g:org_plugins = ['ShowHide', '|', 'Navigator', 'EditStructure']\n<\n\n  Files and folders~\n    .\n    ├── debian                  - files needed for building a Debian package\n    ├── doc                     - vim documentation\n    ├── documentation           - development documentation\n    ├── examples                - example of aplugin\n    ├── ftdetect                - Filetype detection for orgmode files\n    ├── ftplugin                - Home of the main part of vim-orgmode\n    │   └── orgmode             - Home for all Python code\n    │       ├── liborgmode      - vim unrelated part of vim-orgmde. Contains\n    │       │                     basic data structures and algorithms to\n    │       │                     parse and edit orgfiles.\n    │       └── plugins         - Home for all orgmode plugins\n    ├── indent                  - Indentation for orgmode files\n    ├── syntax                  - Syntax highlighting\n    ├── tests                   - Tests to verify the consistency and\n    │                             correctness of orgmode and the plugins\n    ├── build_vmb.vim           - Build file for creating a Vimball\n    ├── install-vmb.vim         - Local installation of vmb via make target\n    ├── LICENSE                 - License Information\n    ├── README.org              - README :)\n    └── Makefile                - make commands\n\n------------------------------------------------------------------------------\nWriting a plugin~\n  To write a plugin:\n  1. copy file ftplugin/orgmode/plugins/Example.py to\n     ftplugin/orgmode/plugins/YourPlugin.py\n  2. Change class name to \"YourPlugin\"\n  3. Set the menu name, it doesn't need to match the filename anymore, e.g.\n     \"Your Plugin\"\n  4. Prepare keybindings in function register by defining a proper action and\n     a key this action should be mapped to. For further information refer to\n     section Keybindings.\n  5. Register your plugin:\n>\n  let g:org_plugins = ['ShowHide', '|', 'Navigator', 'EditStructure',\n    \\ 'YourPlugin']\n<\n\n  6. Write unittests and implement YourPlugin.\n\n------------------------------------------------------------------------------\nKeybindings~\n  Keybindings alias mappings are described very well in the vim\n  documentation, see |map-modes|. vim-orgmode tries to make it easy for the\n  developer to register new keybindings, make them customizable and provide\n  menu entries so that the user can access the functionality like in original\n  orgmode.\n\n  This is done by providing three classes: Keybinding, Plug and ActionEntry\n\n  Keybinding~\n    This is the basic class that encapsulates a single keybinding consisting\n    of a key/mapping and an action. Several options can be set when creating\n    the object to specify the mode and all kinds of other things.\n\n    If a Plug is given instead of an action string the Plug is bound to the\n    key. All relevant data is read from the Plug, e.g. name, mode aso.\n\n    Example~\n      Map g{ to moving to parent heading in normal mode:\n>\n      Keybinding('g{', \\\n        ':py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>', \\\n        mode=MODE_NORMAL)\n\n      vim -> :nmap g{\n        \\ :py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>\n<\n\n      Map g{ to moving to parent heading in normal mode by using a Plug:\n>\n      Keybinding('g{', Plug('OrgJumpToParentNormal', \\\n        ':py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>'))\n\n      vim -> :nnoremap <Plug>OrgJumpToParentNormal :py\n        \\ ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>\n      vim -> :nmap g{ <Plug>OrgJumpToParentNormal\n<\n\n  Plug~\n    A Plug is a unique keybinding that can not be executed by pressing\n    any key. This makes it a special Keybinding that takes a name and\n    an action to create an object. A plug normally goes together with a\n    regular Keybinding to bind the Plug to a key.\n\n    This special behavior is needed to ensure that keybindings are\n    customizable by the user. If the user creates a keybinding to a\n    Plug the Keybinding object makes sure that the users keybinding is\n    used and the keybinding specified by the plugin is not used.\n\n    Example~\n      Map g{ to moving to parent heading in normal mode by using a Plug:\n>\n      Keybinding('g{', Plug('OrgJumpToParentNormal', \\\n        ':py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>'))\n\n      vim -> :nnoremap <Plug>OrgJumpToParentNormal\n        \\ :py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>\n      vim -> :nmap g{ <Plug>OrgJumpToParentNormal\n<\n\n  ActionEntry~\n    An ActionEntry makes Keybindings accessible by the vim menu. It takes a\n    description and a Keybinding object and builds a menu entry from this. The\n    resulting object can be added to a Submenu object by using the + operator.\n\n    Example~\n      Map g{ to moving to parent heading in normal mode by using a Plug:\n>\n      k = Keybinding('g{', Plug('OrgJumpToParentNormal', \\\n        ':py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>'))\n\n      vim -> :nnoremap <Plug>OrgJumpToParentNormal\n        \\ :py ORGMODE.plugins[\"Navigator\"].parent(mode=\"normal\")<CR>\n      vim -> :nmap g{ <Plug>OrgJumpToParentNormal\n\n      menu + ActionEntry('&Up', k)\n      vim -> :nmenu &Org.&Naviagte Headings.&Up<Tab>g{\n        \\ <Plug>OrgJumpToParentNormal\n>\n------------------------------------------------------------------------------\nCreating Tests Cases~\n  For every plugin it's important to write automated test cases. This is\n  important to ensure that little changes don't break things at the other end\n  of the project.\n\n  vim-orgmode relies on Pyunit (http://docs.python.org/library/unittest.html).\n  All tests are located in the tests directory. Run\n>\n  make test\n<\n\n  to run all tests. To create a new test the test should be added to the\n  corresponding test file.\n\n  In case a new plugin is created a new test file needs to be created as well.\n  The test needs to be added to the test suite located in the file\n  tests/run_tests.py.\n\n  Finally the\n>\n  make coverage\n<\n\n  should be run. The result shows the test coverage of all project files. One\n  hundred percent (100%) is of course the goal :-)\n\n==============================================================================\nLINKS                                                           *orgguide-links*\n\n- Original org-mode for Emacs (http://orgmode.org)\n\n- VimOrganizer, another vim port of Emacs org-mode\n  (http://www.vim.org/scripts/script.php?script_id=3342)\n\n==============================================================================\nCHANGELOG                                                   *orgguide-changelog*\n\nIs found in file CHANGELOG.org\n\n==============================================================================\nCONTRIBUTORS                                             *orgguide-contributors*\n\nThanks to all how contributed to vim-orgmode. All contributors are name here\nin alphabetic order:\n\n- Stefan Otte\n- Aleksandar Dimitrov\n\n==============================================================================\nLICENSE VIM-ORGMODE                                           *orgguide-license*\n\nCopyright (C) 2010, 2011 Jan Christoph Ebersbach\n\nhttp://www.e-jc.de/\n\nAll rights reserved.\n\nThe source code of this program is made available under the terms of the GNU\nAffero General Public License version 3 (GNU AGPL V3) as published by the Free\nSoftware Foundation.\n\nBinary versions of this program provided by Univention to you as well as other\ncopyrighted, protected or trademarked materials like Logos, graphics, fonts,\nspecific documentations and configurations, cryptographic keys etc. are\nsubject to a license agreement between you and Univention and not subject to\nthe GNU AGPL V3.\n\nIn the case you use this program under the terms of the GNU AGPL V3, the\nprogram is provided in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR\nA PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License with\nthe Debian GNU/Linux or Univention distribution in file\n/usr/share/common-licenses/AGPL-3; if not, see <http://www.gnu.org/licenses/>.\n\nvim:tw=78:ts=2:sw=2:expandtab:ft=help:norl:\n"
  },
  {
    "path": "examples/mylife.org",
    "content": "* My Life in plain text\n  - [X] birth\n  - [-] life [50%]\n        - [X] use vim\n        - [ ] get everything else done\n* Write minutes of last meeting <2014-08-08 Fri>\t\t\t     :work:\n** DONE John said\n   this\n** TODO Mary said\n   that\n** WAITING What did Mark say?\n   [[http://example.com/here/is/the/recording][1st recording]]\n   [[http://example.com/here/is/the/recording][2nd recording]]\n* Some folding headline 1\t\t\t\t\t\t\t\t:one:\n** Folded\n*** Even more folded\n* Some folding headline 2\n** Folded\t\t\t\t\t\t\t\t\t\t\t:two:\n*** Even more folded\n* Some folding headline 3\n** Folded\n*** Even more folded\t\t\t\t\t\t\t\t    :three:\n* Some folding headline 4\n** Folded\n*** Even more folded\n    completely unfolded\n"
  },
  {
    "path": "examples/plugins/PluginExample.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom orgmode import echo, echom, echoe, ORGMODE, apply_count, repeat\nfrom orgmode.menu import Submenu, Separator, ActionEntry\nfrom orgmode.keybinding import Keybinding, Plug, Command\n\nimport vim\n\n\nclass Example(object):\n    u\"\"\"\n    Example plugin.\n\n    TODO: Extend this doc!\n    \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Example')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    @classmethod\n    def action(cls):\n        u\"\"\"\n        Some kind of action.\n\n        :returns: TODO\n        \"\"\"\n        pass\n\n    def register(self):\n        u\"\"\"\n        Registration of the plugin.\n\n        Key bindings and other initialization should be done here.\n        \"\"\"\n        # an Action menu entry which binds \"keybinding\" to action \":action\"\n        self.commands.append(Command(u'OrgActionCommand',\n                u':py ORGMODE.plugins[\"Example\"].action()'))\n        self.keybindings.append(Keybinding(u'keybinding',\n                Plug(u'OrgAction', self.commands[-1])))\n        self.menu + ActionEntry(u'&Action', self.keybindings[-1])\n"
  },
  {
    "path": "ftdetect/org.vim",
    "content": "autocmd BufNewFile,BufRead *.org setfiletype org\n\"autocmd BufNewFile,BufReadPost org:todo* setfiletype orgtodo\n"
  },
  {
    "path": "ftplugin/org.cnf",
    "content": "--langdef=org\n--langmap=org:.org\n--regex-org=/^(\\*+)[[:space:]]+(.*)([[:space:]]+:[^\\t ]*:)?$/\\1 \\2/s,sections/\n--regex-org=/\\[\\[([^][]+)\\]\\]/\\1/h,hyperlinks/\n--regex-org=/\\[\\[[^][]+\\]\\[([^][]+)\\]\\]/\\1/h,hyperlinks/\n"
  },
  {
    "path": "ftplugin/org.vim",
    "content": "\" org.vim -- Text outlining and task management for Vim based on Emacs' Org-Mode\n\" @Author       : Jan Christoph Ebersbach (jceb@e-jc.de)\n\" @License      : AGPL3 (see http://www.gnu.org/licenses/agpl.txt)\n\" @Created      : 2010-10-03\n\" @Last Modified: Tue 13. Sep 2011 20:52:57 +0200 CEST\n\" @Revision     : 0.4\n\" vi: ft=vim:tw=80:sw=4:ts=4:fdm=marker\n\nif v:version > 702\n\tif has('python3')\n\t\tlet s:py_version = 'python3 '\n\t\tlet s:py_env = 'python3 << EOF'\n\telseif has('python')\n\t\tlet s:py_version = 'python '\n\t\tlet s:py_env = 'python << EOF'\n\telse\n\t\techoerr \"Unable to start orgmode. Orgmode depends on Vim >= 7.3 with Python support complied in.\"\n\t\tfinish\n\tendif\nelse\n\techoerr \"Unable to start orgmode. Orgmode depends on Vim >= 7.3 with Python support complied in.\"\n\tfinish\nendif\n\n\" Init buffer for file {{{1\nif ! exists('b:did_ftplugin')\n\t\" default emacs settings\n\tsetlocal comments=fb:*,b:#,fb:-\n\tsetlocal commentstring=#\\ %s\n\tsetlocal conceallevel=2 concealcursor=nc\n\t\" original emacs settings are: setlocal tabstop=6 shiftwidth=6, but because\n\t\" of checkbox indentation the following settings are used:\n\tsetlocal tabstop=6 shiftwidth=6\n\tif exists('g:org_tag_column')\n\t\texe 'setlocal textwidth='.g:org_tag_column\n\telse\n\t\tsetlocal textwidth=77\n\tendif\n\n\t\" expand tab for counting level of checkbox\n\tsetlocal expandtab\n\n\t\" enable % for angle brackets < >\n\tsetlocal matchpairs+=<:>\n\n\t\" register keybindings if they don't have been registered before\n\tif exists(\"g:loaded_org\")\n\t\texe s:py_version . 'ORGMODE.register_keybindings()'\n\tendif\nendif\n\n\" Load orgmode just once {{{1\nif &cp || exists(\"g:loaded_org\")\n    finish\nendif\nlet g:loaded_org = 1\n\n\" Default org plugins that will be loaded (in the given order) {{{2\nif ! exists('g:org_plugins') && ! exists('b:org_plugins')\n\tlet g:org_plugins = ['ShowHide', '|', 'Navigator', 'EditStructure', 'EditCheckbox', '|', 'Hyperlinks', '|', 'Todo', 'TagsProperties', 'Date', 'Agenda', 'Misc', '|', 'Export']\nendif\n\n\" Default org plugin settings {{{2\n\" What does this do?\nif ! exists('g:org_syntax_highlight_leading_stars') && ! exists('b:org_syntax_highlight_leading_stars')\n\tlet g:org_syntax_highlight_leading_stars = 1\nendif\n\n\" setting to conceal aggressively\nif ! exists('g:org_aggressive_conceal') && ! exists('b:org_aggressive_conceal')\n\tlet g:org_aggressive_conceal = 0\nendif\n\n\" Defined in separate plugins\n\" Adding Behavior preference:\n\"       1:          go into insert-mode when new heading/checkbox/plainlist added\n\"       0:          retain original mode when new heading/checkbox/plainlist added\nif ! exists('g:org_prefer_insert_mode') && ! exists('b:org_prefer_insert_mode')\n    let g:org_prefer_insert_mode = 1\nendif\n\n\" Menu and document handling {{{1\nfunction! <SID>OrgRegisterMenu()\n\texe s:py_version . 'ORGMODE.register_menu()'\nendfunction\n\nfunction! <SID>OrgUnregisterMenu()\n\texe s:py_version . 'ORGMODE.unregister_menu()'\nendfunction\n\nfunction! <SID>OrgDeleteUnusedDocument(bufnr)\n\texe s:py_env\nb = int(vim.eval('a:bufnr'))\nif b in ORGMODE._documents:\n\tdel ORGMODE._documents[b]\nEOF\nendfunction\n\n\" show and hide Org menu depending on the filetype\naugroup orgmode\n\tau BufEnter * :if &filetype == \"org\" | call <SID>OrgRegisterMenu() | endif\n\tau BufLeave * :if &filetype == \"org\" | call <SID>OrgUnregisterMenu() | endif\n\tau BufDelete * :call <SID>OrgDeleteUnusedDocument(expand('<abuf>'))\naugroup END\n\n\" Start orgmode {{{1\n\" Expand our path\nexec s:py_env\nimport glob, vim, os, sys\n\nfor p in vim.eval(\"&runtimepath\").split(','):\n\tdname = os.path.join(p, \"ftplugin\")\n\tmatches = glob.glob(dname)\n\tfor match in matches:\n\t\tif os.path.exists(os.path.join(match, \"orgmode\")):\n\t\t\tif match not in sys.path:\n\t\t\t\tsys.path.append(match)\n\t\t\t\tbreak\n\nfrom orgmode._vim import ORGMODE, insert_at_cursor, get_user_input, date_to_str\nORGMODE.start()\n\nimport datetime\nEOF\n\n\" 3rd Party Plugin Integration {{{1\n\" * Repeat {{{2\ntry\n\tcall repeat#set()\ncatch\nendtry\n\n\" * Tagbar {{{2\nlet g:tagbar_type_org = {\n\t\t\t\\ 'ctagstype' : 'org',\n\t\t\t\\ 'kinds'     : [\n\t\t\t\t\\ 's:sections',\n\t\t\t\t\\ 'h:hyperlinks',\n\t\t\t\\ ],\n\t\t\t\\ 'sort'    : 0,\n\t\t\t\\ 'deffile' : expand('<sfile>:p:h') . '/org.cnf'\n\t\t\t\\ }\n\n\" * Taglist {{{2\nif exists('g:Tlist_Ctags_Cmd')\n\t\" Pass parameters to taglist\n\tlet g:tlist_org_settings = 'org;s:section;h:hyperlinks'\n\tlet g:Tlist_Ctags_Cmd .= ' --options=' . expand('<sfile>:p:h') . '/org.cnf '\nendif\n\n\" * Calendar.vim {{{2\nfun CalendarAction(day, month, year, week, dir)\n\texe s:py_version . \"selected_date = \" . printf(\"datetime.date(%d, %d, %d)\", a:year, a:month, a:day)\n\texe s:py_version . \"org_timestamp = '\" . g:org_timestamp_template . \"' % date_to_str(selected_date)\"\n\n\t\" get_user_input\n\texe s:py_version . \"modifier = get_user_input(org_timestamp)\"\n\t\" change date according to user input\n\texe s:py_version . \"newdate = Date._modify_time(selected_date, modifier)\"\n\texe s:py_version . \"newdate = date_to_str(newdate)\"\n\t\" close Calendar\n\texe \"q\"\n\t\" goto previous window\n\texe \"wincmd p\"\n\texe s:py_version . \"timestamp = '\" . g:org_timestamp_template . \"' % newdate\"\n\texe s:py_version . \"if modifier != None: insert_at_cursor(timestamp)\"\n\t\" restore calendar_action\n\tlet g:calendar_action = g:org_calendar_action_backup\nendf\n"
  },
  {
    "path": "ftplugin/orgmode/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "ftplugin/orgmode/_vim.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    VIM ORGMODE\n    ~~~~~~~~~~~~\n\n    TODO\n\"\"\"\n\ntry:\n    import importlib\n    USE_DEPRECATED_IMP=False\nexcept:\n    import imp\n    USE_DEPRECATED_IMP=True\n\nimport re\nimport sys\n\nimport vim\nfrom datetime import datetime\n\nimport orgmode.keybinding\nimport orgmode.menu\nimport orgmode.plugins\nimport orgmode.settings\nfrom orgmode.exceptions import PluginError\nfrom orgmode.vimbuffer import VimBuffer\nfrom orgmode.liborgmode.agenda import AgendaManager\n\n\nREPEAT_EXISTS = bool(int(vim.eval('exists(\"*repeat#set()\")')))\nTAGSPROPERTIES_EXISTS = False\n\ncache_heading = None\n\nfrom orgmode.py3compat.unicode_compatibility import *\nfrom orgmode.py3compat.encode_compatibility import *\n\n\ndef realign_tags(f):\n    u\"\"\"\n    Update tag alignment, dependency to TagsProperties plugin!\n    \"\"\"\n    def r(*args, **kwargs):\n        global TAGSPROPERTIES_EXISTS\n        res = f(*args, **kwargs)\n\n        if not TAGSPROPERTIES_EXISTS and u'TagsProperties' in ORGMODE.plugins:\n            TAGSPROPERTIES_EXISTS = True\n\n        if TAGSPROPERTIES_EXISTS:\n            ORGMODE.plugins[u'TagsProperties'].realign_tags()\n\n        return res\n    return r\n\n\ndef repeat(f):\n    u\"\"\"\n    Integrate with the repeat plugin if available\n\n    The decorated function must return the name of the <Plug> command to\n    execute by the repeat plugin.\n    \"\"\"\n    def r(*args, **kwargs):\n        res = f(*args, **kwargs)\n        if REPEAT_EXISTS and isinstance(res, basestring):\n            vim.command(u_encode(u'silent! call repeat#set(\"\\\\<Plug>%s\")' % res))\n        return res\n    return r\n\n\ndef apply_count(f):\n    u\"\"\"\n    Decorator which executes function v:count or v:prevount (not implemented,\n    yet) times. The decorated function must return a value that evaluates to\n    True otherwise the function is not repeated.\n    \"\"\"\n    def r(*args, **kwargs):\n        count = 0\n        try:\n            count = int(vim.eval(u_encode(u'v:count')))\n\n            # visual count is not implemented yet\n            #if not count:\n            #    count = int(vim.eval(u'v:prevcount'.encode(u'utf-8')))\n        except BaseException as e:\n            pass\n\n        res = f(*args, **kwargs)\n        count -= 1\n        while res and count > 0:\n            f(*args, **kwargs)\n            count -= 1\n        return res\n    return r\n\n\ndef echo(message):\n    u\"\"\"\n    Print a regular message that will not be visible to the user when\n    multiple lines are printed\n    \"\"\"\n    for m in message.split(u'\\n'):\n        vim.command(u_encode(u':echo \"%s\"' % m))\n\n\ndef echom(message):\n    u\"\"\"\n    Print a regular message that will be visible to the user, even when\n    multiple lines are printed\n    \"\"\"\n    # probably some escaping is needed here\n    for m in message.split(u'\\n'):\n        vim.command(u_encode(u':echomsg \"%s\"' % m))\n\n\ndef echoe(message):\n    u\"\"\"\n    Print an error message. This should only be used for serious errors!\n    \"\"\"\n    # probably some escaping is needed here\n    for m in message.split(u'\\n'):\n        vim.command(u_encode(u':echoerr \"%s\"' % m))\n\n\ndef insert_at_cursor(text, move=True, start_insertmode=False):\n    u\"\"\"Insert text at the position of the cursor.\n\n    If move==True move the cursor with the inserted text.\n    \"\"\"\n    d = ORGMODE.get_document(allow_dirty=True)\n    line, col = vim.current.window.cursor\n    _text = d._content[line - 1]\n    d._content[line - 1] = _text[:col + 1] + text + _text[col + 1:]\n    if move:\n        vim.current.window.cursor = (line, col + len(text))\n    if start_insertmode:\n        vim.command(u_encode(u'startinsert'))\n\n\ndef get_user_input(message):\n    u\"\"\"Print the message and take input from the user.\n    Return the input or None if there is no input.\n    \"\"\"\n    try:\n        vim.command(u_encode(u'call inputsave()'))\n        vim.command(u_encode(u\"let user_input = input('\" + message + u\": ')\"))\n        vim.command(u_encode(u'call inputrestore()'))\n        return u_decode(vim.eval(u_encode(u'user_input')))\n    except:\n        return None\n\n\ndef get_bufnumber(bufname):\n    \"\"\"\n    Return the number of the buffer for the given bufname if it exist;\n    else None.\n    \"\"\"\n    for b in vim.buffers:\n        if b.name == bufname:\n            return int(b.number)\n\n\ndef get_bufname(bufnr):\n    \"\"\"\n    Return the name of the buffer for the given bufnr if it exist; else None.\n    \"\"\"\n    for b in vim.buffers:\n        if b.number == bufnr:\n            return b.name\n\n\ndef indent_orgmode():\n    u\"\"\" Set the indent value for the current line in the variable\n    b:indent_level\n\n    Vim prerequisites:\n        :setlocal indentexpr=Method-which-calls-indent_orgmode\n\n    :returns: None\n    \"\"\"\n    line = int(vim.eval(u_encode(u'v:lnum')))\n    d = ORGMODE.get_document()\n    heading = d.current_heading(line - 1)\n    if heading and line != heading.start_vim:\n        heading.init_checkboxes()\n        checkbox = heading.current_checkbox()\n        level = heading.level + 1\n        if checkbox:\n            if line != checkbox.start_vim:\n                # indent body up to the beginning of the checkbox' text\n                # if checkbox isn't indented to the proper location, the body\n                # won't be indented either\n                level = checkbox.level + len(checkbox.type) + 1 + \\\n                        (4 if checkbox.status else 0)\n        vim.command(u_encode((u'let b:indent_level = %d' % level)))\n\n\ndef fold_text(allow_dirty=False):\n    u\"\"\" Set the fold text\n        :setlocal foldtext=Method-which-calls-foldtext\n\n    :allow_dirty:    Perform a query without (re)building the DOM if True\n    :returns: None\n    \"\"\"\n    line = int(vim.eval(u_encode(u'v:foldstart')))\n    d = ORGMODE.get_document(allow_dirty=allow_dirty)\n    heading = None\n    if allow_dirty:\n        heading = d.find_current_heading(line - 1)\n    else:\n        heading = d.current_heading(line - 1)\n    if heading:\n        str_heading = unicode(heading)\n\n        # expand tabs\n        ts = int(vim.eval(u_encode(u'&ts')))\n        idx = str_heading.find(u'\\t')\n        if idx != -1:\n            tabs, spaces = divmod(idx, ts)\n            str_heading = str_heading.replace(u'\\t', u' ' * (ts - spaces), 1)\n            str_heading = str_heading.replace(u'\\t', u' ' * ts)\n\n        # Workaround for vim.command seems to break the completion menu\n        vim.eval(u_encode(u'SetOrgFoldtext(\"%s...\")' % (re.sub(r'\\[\\[([^[\\]]*\\]\\[)?([^[\\]]+)\\]\\]', r'\\2',\n                str_heading).replace( u'\\\\', u'\\\\\\\\').replace(u'\"', u'\\\\\"'), )))\n\n\ndef fold_orgmode(allow_dirty=False):\n    u\"\"\" Set the fold expression/value for the current line in the variable\n    b:fold_expr\n\n    Vim prerequisites:\n        :setlocal foldmethod=expr\n        :setlocal foldexpr=Method-which-calls-fold_orgmode\n\n    :allow_dirty:    Perform a query without (re)building the DOM if True\n    :returns: None\n    \"\"\"\n    line = int(vim.eval(u_encode(u'v:lnum')))\n    d = ORGMODE.get_document(allow_dirty=allow_dirty)\n    heading = None\n    if allow_dirty:\n        heading = d.find_current_heading(line - 1)\n    else:\n        heading = d.current_heading(line - 1)\n\n    # if cache_heading != heading:\n        # heading.init_checkboxes()\n        # checkbox = heading.current_checkbox()\n\n    # cache_heading = heading\n    if heading:\n        # if checkbox:\n            # vim.command((u'let b:fold_expr = \">%d\"' % heading.level + checkbox.level).encode(u'utf-8'))\n        if 0:\n            pass\n        elif line == heading.start_vim:\n            vim.command(u_encode(u'let b:fold_expr = \">%d\"' % heading.level))\n        #elif line == heading.end_vim:\n        #    vim.command((u'let b:fold_expr = \"<%d\"' % heading.level).encode(u'utf-8'))\n        # end_of_last_child_vim is a performance junky and is actually not needed\n        #elif line == heading.end_of_last_child_vim:\n        #    vim.command((u'let b:fold_expr = \"<%d\"' % heading.level).encode(u'utf-8'))\n        else:\n            vim.command(u_encode(u'let b:fold_expr = %d' % heading.level))\n\n\ndef date_to_str(date):\n    if isinstance(date, datetime):\n        date = date.strftime(u_decode(u_encode(u'%Y-%m-%d %a %H:%M')))\n    else:\n        date = date.strftime(u_decode(u_encode(u'%Y-%m-%d %a')))\n    return date\n\nclass OrgMode(object):\n    u\"\"\" Vim Buffer \"\"\"\n\n    def __init__(self):\n        object.__init__(self)\n        self.debug = bool(int(orgmode.settings.get(u'org_debug', False)))\n\n        self.orgmenu = orgmode.menu.Submenu(u'&Org')\n        self._plugins = {}\n        # list of vim buffer objects\n        self._documents = {}\n\n        # agenda manager\n        self.agenda_manager = AgendaManager()\n\n    def get_document(self, bufnr=0, allow_dirty=False):\n        \"\"\" Retrieve instance of vim buffer document. This Document should be\n        used for manipulating the vim buffer.\n\n        :bufnr:            Retrieve document with bufnr\n        :allow_dirty:    Allow the retrieved document to be dirty\n\n        :returns:    vim buffer instance\n        \"\"\"\n        if bufnr == 0:\n            bufnr = vim.current.buffer.number\n\n        if bufnr in self._documents:\n            if allow_dirty or self._documents[bufnr].is_insync:\n                return self._documents[bufnr]\n        self._documents[bufnr] = VimBuffer(bufnr).init_dom()\n        return self._documents[bufnr]\n\n    @property\n    def plugins(self):\n        return self._plugins.copy()\n\n    @orgmode.keybinding.register_keybindings\n    @orgmode.keybinding.register_commands\n    @orgmode.menu.register_menu\n    def register_plugin(self, plugin):\n        if not isinstance(plugin, basestring):\n            raise ValueError(u'Parameter plugin is not of type string')\n\n        if plugin == u'|':\n            self.orgmenu + orgmode.menu.Separator()\n            self.orgmenu.children[-1].create()\n            return\n\n        if plugin in self._plugins:\n            raise PluginError(u'Plugin %s has already been loaded')\n\n        # a python module\n        module = None\n\n        # actual plugin class\n        _class = None\n\n        if USE_DEPRECATED_IMP:\n            # locate module and initialize plugin class\n            try:\n                module = imp.find_module(plugin, orgmode.plugins.__path__)\n            except ImportError as e:\n                echom(u'Plugin not found: %s' % plugin)\n                if self.debug:\n                    raise e\n                return\n\n            if not module:\n                echom(u'Plugin not found: %s' % plugin)\n                return\n\n        try:\n            if USE_DEPRECATED_IMP:\n                module = imp.load_module(plugin, *module)\n            else:\n                module = importlib.import_module(\".plugins.\" + plugin, \"orgmode\")\n\n            if not hasattr(module, plugin):\n                echoe(u'Unable to find plugin: %s' % plugin)\n                if self.debug:\n                    raise PluginError(u'Unable to find class %s' % plugin)\n                return\n            _class = getattr(module, plugin)\n            self._plugins[plugin] = _class()\n            self._plugins[plugin].register()\n            if self.debug:\n                echo(u'Plugin registered: %s' % plugin)\n            return self._plugins[plugin]\n        except BaseException as e:\n            echoe(u'Unable to activate plugin: %s' % plugin)\n            echoe(u\"%s\" % e)\n            if self.debug:\n                import traceback\n                echoe(traceback.format_exc())\n\n    def register_keybindings(self):\n        @orgmode.keybinding.register_keybindings\n        def dummy(plugin):\n            return plugin\n\n        if sys.version_info < (3, ):\n            for p in self.plugins.itervalues():\n                dummy(p)\n        else:\n            for p in self.plugins.values():\n                dummy(p)\n\n    def register_menu(self):\n        self.orgmenu.create()\n\n    def unregister_menu(self):\n        vim.command(u_encode(u'silent! aunmenu Org'))\n\n    def start(self):\n        u\"\"\" Start orgmode and load all requested plugins\n        \"\"\"\n        plugins = orgmode.settings.get(u\"org_plugins\")\n\n        if not plugins:\n            echom(u'orgmode: No plugins registered.')\n\n        if isinstance(plugins, basestring):\n            try:\n                self.register_plugin(plugins)\n            except BaseException as e:\n                import traceback\n                traceback.print_exc()\n        elif isinstance(plugins, list) or \\\n                isinstance(plugins, tuple):\n            for p in plugins:\n                try:\n                    self.register_plugin(p)\n                except BaseException as e:\n                    echoe('Error in %s plugin:' % p)\n                    import traceback\n                    traceback.print_exc()\n\n        return plugins\n\n\nORGMODE = OrgMode()\n"
  },
  {
    "path": "ftplugin/orgmode/docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = _build\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n\t$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\\'t have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  epub3      to make an epub3\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\t@echo \"  dummy      to check syntax errors of document sources\"\n\n.PHONY: clean\nclean:\n\trm -rf $(BUILDDIR)/*\n\n.PHONY: html\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\n.PHONY: dirhtml\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\n.PHONY: singlehtml\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\n.PHONY: pickle\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\n.PHONY: json\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\n.PHONY: htmlhelp\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\n.PHONY: qthelp\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/orgmode.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/orgmode.qhc\"\n\n.PHONY: applehelp\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\n.PHONY: devhelp\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/orgmode\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/orgmode\"\n\t@echo \"# devhelp\"\n\n.PHONY: epub\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\n.PHONY: epub3\nepub3:\n\t$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3\n\t@echo\n\t@echo \"Build finished. The epub3 file is in $(BUILDDIR)/epub3.\"\n\n.PHONY: latex\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\n.PHONY: latexpdf\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\n.PHONY: latexpdfja\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\n.PHONY: text\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\n.PHONY: man\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\n.PHONY: texinfo\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\n.PHONY: info\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\n.PHONY: gettext\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\n.PHONY: changes\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\n.PHONY: linkcheck\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\n.PHONY: doctest\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\n.PHONY: coverage\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\n.PHONY: xml\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\n.PHONY: pseudoxml\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n\n.PHONY: dummy\ndummy:\n\t$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy\n\t@echo\n\t@echo \"Build finished. Dummy builder generates no files.\"\n"
  },
  {
    "path": "ftplugin/orgmode/docs/conf.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# orgmode documentation build configuration file, created by\n# sphinx-quickstart on Sat May 21 15:51:55 2016.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport mock\n\n# Mock vim\nMOCK_MODULES = ['vim']\nfor m in MOCK_MODULES:\n    sys.modules[m] = mock.Mock()\n\nimport vim\nvim.eval = mock.MagicMock(return_value=1)\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#sys.path.insert(0, os.path.abspath('.'))\nsys.path.insert(0, os.path.abspath('../..'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc',\n    'sphinx.ext.todo',\n    'sphinx.ext.viewcode',\n    'sphinx.ext.doctest',\n    'sphinx.ext.coverage',\n    'sphinx.ext.viewcode',\n    'sphinx.ext.napoleon',\n]\n\n# Napoleon config\nnapoleon_google_docstring = True\nnapoleon_numpy_docstring = True\nnapoleon_include_private_with_doc = True\nnapoleon_include_special_with_doc = True\nnapoleon_use_admonition_for_examples = False\nnapoleon_use_admonition_for_notes = False\nnapoleon_use_admonition_for_references = False\nnapoleon_use_ivar = False\nnapoleon_use_param = True\nnapoleon_use_rtype = True\n\n# Add any paths that contain templates here, relative to this directory.\n#templates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'orgmode'\ncopyright = '2016, Author'\nauthor = 'Author'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = ''\n# The full version, including alpha/beta/rc tags.\nrelease = ''\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = 'en'\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\nadd_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = True\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'alabaster'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.\n# \"<project> v<release> documentation\" by default.\nhtml_title = 'orgmode v0.5'\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (relative to this directory) to use as a favicon of\n# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n#html_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not None, a 'Last updated on:' timestamp is inserted at every page\n# bottom, using the given strftime format.\n# The empty string is equivalent to '%b %d, %Y'.\n#html_last_updated_fmt = None\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# 'ja' uses this config value.\n# 'zh' user can custom change `jieba` dictionary path.\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'orgmodedoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, 'orgmode.tex', 'orgmode Documentation',\n     'Author', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'orgmode', 'orgmode Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (master_doc, 'orgmode', 'orgmode Documentation',\n     author, 'orgmode', 'One line description of project.',\n     'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n\n\n# -- Options for Epub output ----------------------------------------------\n\n# Bibliographic Dublin Core info.\nepub_title = project\nepub_author = author\nepub_publisher = author\nepub_copyright = copyright\n\n# The basename for the epub file. It defaults to the project name.\n#epub_basename = project\n\n# The HTML theme for the epub output. Since the default themes are not\n# optimized for small screen space, using the same theme for HTML and epub\n# output is usually not wise. This defaults to 'epub', a theme designed to save\n# visual space.\n#epub_theme = 'epub'\n\n# The language of the text. It defaults to the language option\n# or 'en' if the language is not set.\n#epub_language = ''\n\n# The scheme of the identifier. Typical schemes are ISBN or URL.\n#epub_scheme = ''\n\n# The unique identifier of the text. This can be a ISBN number\n# or the project homepage.\n#epub_identifier = ''\n\n# A unique identification for the text.\n#epub_uid = ''\n\n# A tuple containing the cover image and cover page html template filenames.\n#epub_cover = ()\n\n# A sequence of (type, uri, title) tuples for the guide element of content.opf.\n#epub_guide = ()\n\n# HTML files that should be inserted before the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#epub_pre_files = []\n\n# HTML files that should be inserted after the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#epub_post_files = []\n\n# A list of files that should not be packed into the epub file.\nepub_exclude_files = ['search.html']\n\n# The depth of the table of contents in toc.ncx.\n#epub_tocdepth = 3\n\n# Allow duplicate toc entries.\n#epub_tocdup = True\n\n# Choose between 'default' and 'includehidden'.\n#epub_tocscope = 'default'\n\n# Fix unsupported image types using the Pillow.\n#epub_fix_images = False\n\n# Scale large images.\n#epub_max_image_width = 0\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#epub_show_urls = 'inline'\n\n# If false, no index is generated.\n#epub_use_index = True\n"
  },
  {
    "path": "ftplugin/orgmode/docs/index.rst",
    "content": ".. orgmode documentation master file, created by\n   sphinx-quickstart on Sat May 21 16:35:00 2016.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to orgmode's documentation!\n===================================\n\nContents:\n\n.. toctree::\n   :maxdepth: 4\n\n   orgmode\n\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n"
  },
  {
    "path": "ftplugin/orgmode/docs/make.bat",
    "content": "@ECHO OFF\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\nset BUILDDIR=_build\r\nset ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .\r\nset I18NSPHINXOPTS=%SPHINXOPTS% .\r\nif NOT \"%PAPER%\" == \"\" (\r\n\tset ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\r\n\tset I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\r\n)\r\n\r\nif \"%1\" == \"\" goto help\r\n\r\nif \"%1\" == \"help\" (\r\n\t:help\r\n\techo.Please use `make ^<target^>` where ^<target^> is one of\r\n\techo.  html       to make standalone HTML files\r\n\techo.  dirhtml    to make HTML files named index.html in directories\r\n\techo.  singlehtml to make a single large HTML file\r\n\techo.  pickle     to make pickle files\r\n\techo.  json       to make JSON files\r\n\techo.  htmlhelp   to make HTML files and a HTML help project\r\n\techo.  qthelp     to make HTML files and a qthelp project\r\n\techo.  devhelp    to make HTML files and a Devhelp project\r\n\techo.  epub       to make an epub\r\n\techo.  epub3      to make an epub3\r\n\techo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\r\n\techo.  text       to make text files\r\n\techo.  man        to make manual pages\r\n\techo.  texinfo    to make Texinfo files\r\n\techo.  gettext    to make PO message catalogs\r\n\techo.  changes    to make an overview over all changed/added/deprecated items\r\n\techo.  xml        to make Docutils-native XML files\r\n\techo.  pseudoxml  to make pseudoxml-XML files for display purposes\r\n\techo.  linkcheck  to check all external links for integrity\r\n\techo.  doctest    to run all doctests embedded in the documentation if enabled\r\n\techo.  coverage   to run coverage check of the documentation if enabled\r\n\techo.  dummy      to check syntax errors of document sources\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"clean\" (\r\n\tfor /d %%i in (%BUILDDIR%\\*) do rmdir /q /s %%i\r\n\tdel /q /s %BUILDDIR%\\*\r\n\tgoto end\r\n)\r\n\r\n\r\nREM Check if sphinx-build is available and fallback to Python version if any\r\n%SPHINXBUILD% 1>NUL 2>NUL\r\nif errorlevel 9009 goto sphinx_python\r\ngoto sphinx_ok\r\n\r\n:sphinx_python\r\n\r\nset SPHINXBUILD=python -m sphinx.__init__\r\n%SPHINXBUILD% 2> nul\r\nif errorlevel 9009 (\r\n\techo.\r\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r\n\techo.installed, then set the SPHINXBUILD environment variable to point\r\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\r\n\techo.may add the Sphinx directory to PATH.\r\n\techo.\r\n\techo.If you don't have Sphinx installed, grab it from\r\n\techo.http://sphinx-doc.org/\r\n\texit /b 1\r\n)\r\n\r\n:sphinx_ok\r\n\r\n\r\nif \"%1\" == \"html\" (\r\n\t%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The HTML pages are in %BUILDDIR%/html.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"dirhtml\" (\r\n\t%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"singlehtml\" (\r\n\t%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"pickle\" (\r\n\t%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can process the pickle files.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"json\" (\r\n\t%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can process the JSON files.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"htmlhelp\" (\r\n\t%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can run HTML Help Workshop with the ^\r\n.hhp project file in %BUILDDIR%/htmlhelp.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"qthelp\" (\r\n\t%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; now you can run \"qcollectiongenerator\" with the ^\r\n.qhcp project file in %BUILDDIR%/qthelp, like this:\r\n\techo.^> qcollectiongenerator %BUILDDIR%\\qthelp\\orgmode.qhcp\r\n\techo.To view the help file:\r\n\techo.^> assistant -collectionFile %BUILDDIR%\\qthelp\\orgmode.ghc\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"devhelp\" (\r\n\t%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"epub\" (\r\n\t%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The epub file is in %BUILDDIR%/epub.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"epub3\" (\r\n\t%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The epub3 file is in %BUILDDIR%/epub3.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"latex\" (\r\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"latexpdf\" (\r\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r\n\tcd %BUILDDIR%/latex\r\n\tmake all-pdf\r\n\tcd %~dp0\r\n\techo.\r\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"latexpdfja\" (\r\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\r\n\tcd %BUILDDIR%/latex\r\n\tmake all-pdf-ja\r\n\tcd %~dp0\r\n\techo.\r\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"text\" (\r\n\t%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The text files are in %BUILDDIR%/text.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"man\" (\r\n\t%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The manual pages are in %BUILDDIR%/man.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"texinfo\" (\r\n\t%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"gettext\" (\r\n\t%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The message catalogs are in %BUILDDIR%/locale.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"changes\" (\r\n\t%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.The overview file is in %BUILDDIR%/changes.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"linkcheck\" (\r\n\t%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Link check complete; look for any errors in the above output ^\r\nor in %BUILDDIR%/linkcheck/output.txt.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"doctest\" (\r\n\t%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Testing of doctests in the sources finished, look at the ^\r\nresults in %BUILDDIR%/doctest/output.txt.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"coverage\" (\r\n\t%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Testing of coverage in the sources finished, look at the ^\r\nresults in %BUILDDIR%/coverage/python.txt.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"xml\" (\r\n\t%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The XML files are in %BUILDDIR%/xml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"pseudoxml\" (\r\n\t%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\r\n\tgoto end\r\n)\r\n\r\nif \"%1\" == \"dummy\" (\r\n\t%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy\r\n\tif errorlevel 1 exit /b 1\r\n\techo.\r\n\techo.Build finished. Dummy builder generates no files.\r\n\tgoto end\r\n)\r\n\r\n:end\r\n"
  },
  {
    "path": "ftplugin/orgmode/docs/orgmode.liborgmode.rst",
    "content": "orgmode.liborgmode package\n==========================\n\nSubmodules\n----------\n\norgmode.liborgmode.agenda module\n--------------------------------\n\n.. automodule:: orgmode.liborgmode.agenda\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.agendafilter module\n--------------------------------------\n\n.. automodule:: orgmode.liborgmode.agendafilter\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.base module\n------------------------------\n\n.. automodule:: orgmode.liborgmode.base\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.checkboxes module\n------------------------------------\n\n.. automodule:: orgmode.liborgmode.checkboxes\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.documents module\n-----------------------------------\n\n.. automodule:: orgmode.liborgmode.documents\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.dom_obj module\n---------------------------------\n\n.. automodule:: orgmode.liborgmode.dom_obj\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.headings module\n----------------------------------\n\n.. automodule:: orgmode.liborgmode.headings\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.liborgmode.orgdate module\n---------------------------------\n\n.. automodule:: orgmode.liborgmode.orgdate\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n\nModule contents\n---------------\n\n.. automodule:: orgmode.liborgmode\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "ftplugin/orgmode/docs/orgmode.plugins.rst",
    "content": "orgmode.plugins package\n=======================\n\nSubmodules\n----------\n\norgmode.plugins.Agenda module\n-----------------------------\n\n.. automodule:: orgmode.plugins.Agenda\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.Date module\n---------------------------\n\n.. automodule:: orgmode.plugins.Date\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.EditCheckbox module\n-----------------------------------\n\n.. automodule:: orgmode.plugins.EditCheckbox\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.EditStructure module\n------------------------------------\n\n.. automodule:: orgmode.plugins.EditStructure\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.Export module\n-----------------------------\n\n.. automodule:: orgmode.plugins.Export\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.Hyperlinks module\n---------------------------------\n\n.. automodule:: orgmode.plugins.Hyperlinks\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.LoggingWork module\n----------------------------------\n\n.. automodule:: orgmode.plugins.LoggingWork\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.Misc module\n---------------------------\n\n.. automodule:: orgmode.plugins.Misc\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.Navigator module\n--------------------------------\n\n.. automodule:: orgmode.plugins.Navigator\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.ShowHide module\n-------------------------------\n\n.. automodule:: orgmode.plugins.ShowHide\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.TagsProperties module\n-------------------------------------\n\n.. automodule:: orgmode.plugins.TagsProperties\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.plugins.Todo module\n---------------------------\n\n.. automodule:: orgmode.plugins.Todo\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n\nModule contents\n---------------\n\n.. automodule:: orgmode.plugins\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "ftplugin/orgmode/docs/orgmode.py3compat.rst",
    "content": "orgmode.py3compat package\n=========================\n\nSubmodules\n----------\n\norgmode.py3compat.encode_compatibility module\n---------------------------------------------\n\n.. automodule:: orgmode.py3compat.encode_compatibility\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.py3compat.py_py3_string module\n--------------------------------------\n\n.. automodule:: orgmode.py3compat.py_py3_string\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.py3compat.unicode_compatibility module\n----------------------------------------------\n\n.. automodule:: orgmode.py3compat.unicode_compatibility\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.py3compat.xrange_compatibility module\n---------------------------------------------\n\n.. automodule:: orgmode.py3compat.xrange_compatibility\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n\nModule contents\n---------------\n\n.. automodule:: orgmode.py3compat\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "ftplugin/orgmode/docs/orgmode.rst",
    "content": "orgmode package\n===============\n\nSubpackages\n-----------\n\n.. toctree::\n\n    orgmode.liborgmode\n    orgmode.plugins\n    orgmode.py3compat\n\nSubmodules\n----------\n\norgmode._vim module\n-------------------\n\n.. automodule:: orgmode._vim\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.exceptions module\n-------------------------\n\n.. automodule:: orgmode.exceptions\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.keybinding module\n-------------------------\n\n.. automodule:: orgmode.keybinding\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.menu module\n-------------------\n\n.. automodule:: orgmode.menu\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.settings module\n-----------------------\n\n.. automodule:: orgmode.settings\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\norgmode.vimbuffer module\n------------------------\n\n.. automodule:: orgmode.vimbuffer\n    :members:\n    :undoc-members:\n    :show-inheritance:\n\n\nModule contents\n---------------\n\n.. automodule:: orgmode\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "ftplugin/orgmode/exceptions.py",
    "content": "# -*- coding: utf-8 -*-\n\n\nclass PluginError(BaseException):\n    def __init__(self, message):\n        BaseException.__init__(self, message)\n\n\nclass BufferNotFound(BaseException):\n    def __init__(self, message):\n        BaseException.__init__(self, message)\n\n\nclass BufferNotInSync(BaseException):\n    def __init__(self, message):\n        BaseException.__init__(self, message)\n\n\nclass HeadingDomError(BaseException):\n    def __init__(self, message):\n        BaseException.__init__(self, message)\n"
  },
  {
    "path": "ftplugin/orgmode/keybinding.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nMODE_ALL = u'a'\nMODE_NORMAL = u'n'\nMODE_VISUAL = u'v'\nMODE_INSERT = u'i'\nMODE_OPERATOR = u'o'\n\nOPTION_BUFFER_ONLY = u'<buffer>'\nOPTION_SLIENT = u'<silent>'\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ndef _register(f, name):\n    def r(*args, **kwargs):\n        p = f(*args, **kwargs)\n        if hasattr(p, name) and isinstance(getattr(p, name), list):\n            for i in getattr(p, name):\n                i.create()\n        return p\n    return r\n\n\ndef register_keybindings(f):\n    return _register(f, u'keybindings')\n\n\ndef register_commands(f):\n    return _register(f, u'commands')\n\n\nclass Command(object):\n    u\"\"\" A vim command \"\"\"\n\n    def __init__(self, name, command, arguments=u'0', complete=None, overwrite_exisiting=False):\n        u\"\"\"\n        :name:        The name of command, first character must be uppercase\n        :command:    The actual command that is executed\n        :arguments:    See :h :command-nargs, only the arguments need to be specified\n        :complete:    See :h :command-completion, only the completion arguments need to be specified\n        \"\"\"\n        object.__init__(self)\n\n        self._name                = name\n        self._command             = command\n        self._arguments           = arguments\n        self._complete            = complete\n        self._overwrite_exisiting = overwrite_exisiting\n\n    def __unicode__(self):\n        return u':%s<CR>' % self.name\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def command(self):\n        return self._command\n\n    @property\n    def arguments(self):\n        return self._arguments\n\n    @property\n    def complete(self):\n        return self._complete\n\n    @property\n    def overwrite_exisiting(self):\n        return self._overwrite_exisiting\n\n    def create(self):\n        u\"\"\" Register/create the command\n        \"\"\"\n        vim.command(u_encode(':command%(overwrite)s -nargs=%(arguments)s %(complete)s %(name)s %(command)s' %\n                {u'overwrite': '!' if self.overwrite_exisiting else '',\n                    u'arguments': u_encode(self.arguments),\n                    u'complete': '-complete=%s' % u_encode(self.complete) if self.complete else '',\n                    u'name': self.name,\n                    u'command': self.command}\n                ))\n\n\nclass Plug(object):\n    u\"\"\" Represents a <Plug> to an abitrary command \"\"\"\n\n    def __init__(self, name, command, mode=MODE_NORMAL):\n        u\"\"\"\n        :name: the name of the <Plug> should be ScriptnameCommandname\n        :command: the actual command\n        \"\"\"\n        object.__init__(self)\n\n        if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR):\n            raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR')\n        self._mode = mode\n\n        self.name = name\n        self.command = command\n        self.created = False\n\n    def __unicode__(self):\n        return u'<Plug>%s' % self.name\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def create(self):\n        if not self.created:\n            self.created = True\n            cmd = self._mode\n            if cmd == MODE_ALL:\n                cmd = u''\n            vim.command(u_encode(u':%snoremap %s %s' % (cmd, str(self), self.command)))\n\n    @property\n    def mode(self):\n        return self._mode\n\n\nclass Keybinding(object):\n    u\"\"\" Representation of a single key binding \"\"\"\n\n    def __init__(self, key, action, mode=None, options=None, remap=True, buffer_only=True, silent=True):\n        u\"\"\"\n        :key: the key(s) action is bound to\n        :action: the action triggered by key(s)\n        :mode: definition in which vim modes the key binding is valid. Should be one of MODE_*\n        :option: list of other options like <silent>, <buffer> ...\n        :repmap: allow or disallow nested mapping\n        :buffer_only: define the key binding only for the current buffer\n        \"\"\"\n        object.__init__(self)\n        self._key = key\n        self._action = action\n\n        # grab mode from plug if not set otherwise\n        if isinstance(self._action, Plug) and not mode:\n            mode = self._action.mode\n\n        if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR):\n            raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR')\n        self._mode = mode\n        self._options = options\n        if self._options is None:\n            self._options = []\n        self._remap = remap\n        self._buffer_only = buffer_only\n        self._silent = silent\n\n        if self._buffer_only and OPTION_BUFFER_ONLY not in self._options:\n            self._options.append(OPTION_BUFFER_ONLY)\n\n        if self._silent and OPTION_SLIENT not in self._options:\n            self._options.append(OPTION_SLIENT)\n\n    @property\n    def key(self):\n        return self._key\n\n    @property\n    def action(self):\n        return str(self._action)\n\n    @property\n    def mode(self):\n        return self._mode\n\n    @property\n    def options(self):\n        return self._options[:]\n\n    @property\n    def remap(self):\n        return self._remap\n\n    @property\n    def buffer_only(self):\n        return self._buffer_only\n\n    @property\n    def silent(self):\n        return self._silent\n\n    def create(self):\n        from orgmode._vim import ORGMODE, echom\n\n        cmd = self._mode\n        if cmd == MODE_ALL:\n            cmd = u''\n        if not self._remap:\n            cmd += u'nore'\n        try:\n            create_mapping = True\n            if isinstance(self._action, Plug):\n                # create plug\n                self._action.create()\n                if int(vim.eval(u_encode(u'hasmapto(\"%s\")' % (self._action, )))):\n                    create_mapping = False\n            if isinstance(self._action, Command):\n                # create command\n                self._action.create()\n\n            if create_mapping:\n                vim.command(u_encode(u':%smap %s %s %s' % (cmd, u' '.join(self._options), self._key, self._action)))\n        except BaseException as e:\n            if ORGMODE.debug:\n                echom(u'Failed to register key binding %s %s' % (self._key, self._action))\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/agenda.py",
    "content": "# -*- coding: utf-8 -*-\n\nu\"\"\"\n    Agenda\n    ~~~~~~~~~~~~~~~~~~\n\n    The agenda is one of the main concepts of orgmode. It allows to\n    collect TODO items from multiple org documents in an agenda view.\n\n    Features:\n    * filtering\n    * sorting\n\"\"\"\n\nfrom orgmode.liborgmode.agendafilter import filter_items\nfrom orgmode.liborgmode.agendafilter import is_within_week_and_active_todo\nfrom orgmode.liborgmode.agendafilter import contains_active_todo\nfrom orgmode.liborgmode.agendafilter import contains_active_date\nfrom orgmode.liborgmode.orgdate import OrgDateTime, OrgTimeRange\nimport datetime\n\ndef agenda_sorting_key(heading):\n    orgtime = heading.active_date\n    if orgtime is None or isinstance(orgtime, OrgDateTime):\n        return orgtime\n    if isinstance(orgtime, OrgTimeRange):\n        return orgtime.start\n\n    # It is an OrgDate. OrgDate cannot be compared with datetime-based Org* values by \n    # default, so it will be converted in such a way that:\n    # * OrgDate value of _today_ will be displayed after today's passed events and before\n    #   today's upcoming scheduled events.\n    # * OrgDate value of a past day will be displayed after all other items of the same\n    #   day.\n    # * OrgDate value of a future day will be displayed before all other items of the same\n    #   day.\n    now = datetime.datetime.now()\n    today = now.date()\n    time_to_add = now.time() if today == orgtime else datetime.time(0, 0) if today < orgtime else datetime.time(23, 59)\n    return datetime.datetime.combine(orgtime, time_to_add)\n\nclass AgendaManager(object):\n    u\"\"\"Simple parsing of Documents to create an agenda.\"\"\"\n    # TODO Move filters in this file, they do the same thing\n\n    def __init__(self):\n        super(AgendaManager, self).__init__()\n\n    def get_todo(self, documents):\n        u\"\"\"\n        Get the todo agenda for the given documents (list of document).\n        \"\"\"\n        filtered = []\n        for document in iter(documents):\n            # filter and return headings\n            filtered.extend(filter_items(document.all_headings(),\n                                [contains_active_todo]))\n        return sorted(filtered, key=agenda_sorting_key)\n\n    def get_next_week_and_active_todo(self, documents):\n        u\"\"\"\n        Get the agenda for next week for the given documents (list of\n        document).\n        \"\"\"\n        filtered = []\n        for document in iter(documents):\n            # filter and return headings\n            filtered.extend(filter_items(document.all_headings(),\n                                [is_within_week_and_active_todo]))\n        return sorted(filtered, key=agenda_sorting_key)\n\n    def get_timestamped_items(self, documents):\n        u\"\"\"\n        Get all time-stamped items in a time-sorted way for the given\n        documents (list of document).\n        \"\"\"\n        filtered = []\n        for document in iter(documents):\n            # filter and return headings\n            filtered.extend(filter_items(document.all_headings(),\n                                [contains_active_date]))\n        return sorted(filtered, key=agenda_sorting_key)\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/agendafilter.py",
    "content": "# -*- coding: utf-8 -*-\n\nu\"\"\"\n    agendafilter\n    ~~~~~~~~~~~~~~~~\n\n    AgendaFilter contains all the filters that can be applied to create the\n    agenda.\n\n\n    All functions except filter_items() in the module are filters. Given a\n    heading they return if the heading meets the criteria of the filter.\n\n    The function filter_items() can combine different filters and only returns\n    the filtered headings.\n\"\"\"\nfrom datetime import datetime\nfrom datetime import timedelta\n\ntry:\n    from itertools import ifilter as filter\nexcept:\n    pass\n\n\ndef filter_items(headings, filters):\n    u\"\"\" Filter the given headings.\n\n    Args:\n        headings (list): Contains headings\n        filters (list): Filters that will be applied. All functions in\n            this module (except this function) are filters.\n\n    Returns:\n        filter iterator: Headings which were not filtered.\n\n    Examples:\n        >>> filtered = filter_items(headings, [contains_active_date,\n                contains_active_todo])\n    \"\"\"\n    filtered = headings\n    for f in filters:\n        filtered = filter(f, filtered)\n    return filtered\n\n\ndef is_within_week(heading):\n    u\"\"\" Test if headings date is within a week\n\n    Returns:\n        bool: True if the date in the deading is within a week in the future (or\n            older False otherwise.\n    \"\"\"\n    if contains_active_date(heading):\n        next_week = datetime.today() + timedelta(days=7)\n        if heading.active_date < next_week:\n            return True\n\n\ndef is_within_week_and_active_todo(heading):\n    u\"\"\"\n    Returns:\n        bool: True if heading contains an active TODO and the date is within a\n            week.\n    \"\"\"\n    return is_within_week(heading) and contains_active_todo(heading)\n\n\ndef contains_active_todo(heading):\n    u\"\"\"\n\n    Returns:\n        bool: True if heading contains an active TODO.\n    \"\"\"\n    # TODO make this more efficient by checking some val and not calling the\n    # function\n    # TODO why is this import failing at top level? circular dependency...\n    from orgmode._vim import ORGMODE\n    active = []\n    for act in ORGMODE.get_document().get_todo_states():\n        active.extend(act[0])\n    return heading.todo in active\n\n\ndef contains_active_date(heading):\n    u\"\"\"\n\n    Returns:\n        bool: True if heading contains an active date.\n    \"\"\"\n    return not(heading.active_date is None)\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/base.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    base\n    ~~~~~~~~~~\n\n    Here are some really basic data structures that are used throughout\n    the liborgmode.\n\"\"\"\n\ntry:\n    from collections import UserList\nexcept:\n    from UserList import UserList\n\ntry:\n    from collections.abc import Iterable\nexcept ImportError:\n    # preserve compatibility with python < 3.10\n    from collections import Iterable\n\nimport sys\nfrom orgmode.py3compat.unicode_compatibility import *\n\n\ndef flatten_list(lst):\n    \"\"\" Flattens a list\n\n    Args:\n        lst (iterable): An iterable that will is non-flat\n\n    Returns:\n        list: Flat list\n    \"\"\"\n    # TODO write tests\n    def gen_lst(item):\n        if isinstance(item, basestring) or isinstance(item, bytes):\n            yield item\n        elif isinstance(item, Iterable):\n            # yield from would be so nice... but c'est la vie\n            for val in item:\n                for final in gen_lst(val):\n                    yield final\n        else:\n            yield item\n    return [i for i in gen_lst(lst)]\n\n\nclass Direction():\n    u\"\"\"\n    Direction is used to indicate the direction of certain actions.\n\n    Example: it defines the direction headings get parted in.\n    \"\"\"\n    FORWARD = 1\n    BACKWARD = 2\n\n\nclass MultiPurposeList(UserList):\n    u\"\"\"\n    A Multi Purpose List is a list that calls a user defined hook on\n    change. The implementation is very basic - the hook is called without any\n    parameters. Otherwise the Multi Purpose List can be used like any other\n    list.\n\n    The member element \"data\" can be used to fill the list without causing the\n    list to be marked dirty. This should only be used during initialization!\n    \"\"\"\n\n    def __init__(self, initlist=None, on_change=None):\n        UserList.__init__(self, initlist)\n        self._on_change = on_change\n\n    def _changed(self):\n        u\"\"\" Call hook \"\"\"\n        if callable(self._on_change):\n            self._on_change()\n\n    def __setitem__(self, i, item):\n        if sys.version_info < (3, ) and isinstance(i, slice):\n            start, stop, _ = i.indices(len(self))\n            UserList.__setslice__(self, start, stop, item)\n        else:\n            UserList.__setitem__(self, i, item)\n        self._changed()\n\n    def __delitem__(self, i):\n        if sys.version_info < (3, ) and isinstance(i, slice):\n            start, stop, _ = i.indices(len(self))\n            UserList.__delslice__(self, start, stop)\n        else:\n            UserList.__delitem__(self, i)\n        self._changed()\n\n    def __getitem__(self, i):\n        if sys.version_info < (3, ):\n            if isinstance(i, slice):\n                # TODO Return just a list. Why?\n                return [self[i] for i in range(*i.indices(len(self)))]\n                # return UserList([self[i] for i in range(*i.indices(len(self)))])\n        return UserList.__getitem__(self, i)\n\n    # NOTE: These wrappers are necessary because of python 2\n    def __setslice__(self, i, j, other):\n        self.__setitem__(slice(i, j), other)\n\n    def __delslice__(self, i, j):\n        self.__delitem__(slice(i, j))\n\n    def __getslice__(self, i, j):\n        return self.__getitem__(slice(i, j))\n\n    def __iadd__(self, other):\n        res = UserList.__iadd__(self, other)\n        self._changed()\n        return res\n\n    def __imul__(self, n):\n        res = UserList.__imul__(self, n)\n        self._changed()\n        return res\n\n    def append(self, item):\n        UserList.append(self, item)\n        self._changed()\n\n    def insert(self, i, item):\n        UserList.insert(self, i, item)\n        self._changed()\n\n    def pop(self, i=-1):\n        item = self[i]\n        del self[i]\n        return item\n\n    def remove(self, item):\n        self.__delitem__(self.index(item))\n\n    def reverse(self):\n        UserList.reverse(self)\n        self._changed()\n\n    def sort(self, *args, **kwds):\n        UserList.sort(self, *args, **kwds)\n        self._changed()\n\n    def extend(self, other):\n        UserList.extend(self, other)\n        self._changed()\n\n\ndef get_domobj_range(content=[], position=0, direction=Direction.FORWARD, identify_fun=None):\n    u\"\"\"\n    Get the start and end line number of the dom obj lines from content.\n\n    :content:        String to be recognized dom obj\n    :position:        Line number in content\n    :direction:        Search direction\n    :identify_fun:  A identify function to recognize dom obj(Heading, Checkbox) title string.\n\n    :return:        Start and end line number for the recognized dom obj.\n    \"\"\"\n    len_cb = len(content)\n\n    if position < 0 or position > len_cb:\n        return (None, None)\n\n    tmp_line = position\n    start = None\n    end = None\n\n    if direction == Direction.FORWARD:\n        while tmp_line < len_cb:\n            if identify_fun(content[tmp_line]) is not None:\n                if start is None:\n                    start = tmp_line\n                elif end is None:\n                    end = tmp_line - 1\n                if start is not None and end is not None:\n                    break\n            tmp_line += 1\n    else:\n        while tmp_line >= 0 and tmp_line < len_cb:\n            if identify_fun(content[tmp_line]) is not None:\n                if start is None:\n                    start = tmp_line\n                elif end is None:\n                    end = tmp_line - 1\n                if start is not None and end is not None:\n                    break\n            tmp_line -= 1 if start is None else -1\n\n    return (start, end)\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/checkboxes.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    checkboxes\n    ~~~~~~~~~~\n\n    TODO: explain this :)\n\"\"\"\n\nimport re\ntry:\n    from collections import UserList\nexcept:\n    from UserList import UserList\n\nimport vim\nfrom orgmode.liborgmode.base import MultiPurposeList, flatten_list\nfrom orgmode.liborgmode.orgdate import OrgTimeRange\nfrom orgmode.liborgmode.orgdate import get_orgdate\nfrom orgmode.liborgmode.dom_obj import DomObj, DomObjList, REGEX_SUBTASK, REGEX_SUBTASK_PERCENT, REGEX_HEADING, REGEX_CHECKBOX\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\n\nclass Checkbox(DomObj):\n    u\"\"\" Structural checkbox object \"\"\"\n    STATUS_ON = u'[X]'\n    STATUS_OFF = u'[ ]'\n    # intermediate status\n    STATUS_INT = u'[-]'\n\n    def __init__(self, level=1, type=u'-', title=u'', status=u'[ ]', body=None):\n        u\"\"\"\n        :level:        Indent level of the checkbox\n        :type:        Type of the checkbox list (-, +, *)\n        :title:        Title of the checkbox\n        :status:    Status of the checkbox ([ ], [X], [-])\n        :body:        Body of the checkbox\n        \"\"\"\n        DomObj.__init__(self, level=level, title=title, body=body)\n\n        # heading\n        self._heading = None\n\n        self._children = CheckboxList(obj=self)\n        self._dirty_checkbox = False\n        # list type\n        self._type = u'-'\n        if type:\n            self.type = type\n        # status\n        self._status = Checkbox.STATUS_OFF\n        if status:\n            self.status = status\n\n    def __unicode__(self):\n        return u' ' * self.level + self.type + u' ' + \\\n            (self.status + u' ' if self.status else u'') + self.title\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def __len__(self):\n        # 1 is for the heading's title\n        return 1 + len(self.body)\n\n    def copy(self, including_children=True, parent=None):\n        u\"\"\"\n        Create a copy of the current checkbox. The checkbox will be completely\n        detached and not even belong to a document anymore.\n\n        :including_children:    If True a copy of all children is create as\n                                well. If False the returned checkbox doesn't\n                                have any children.\n        :parent:                Don't use this parameter. It's set\n                                automatically.\n        \"\"\"\n        checkbox = self.__class__(\n            level=self.level, title=self.title,\n            body=self.body[:])\n        if parent:\n            parent.children.append(checkbox)\n        if including_children and self.children:\n            for item in self.children:\n                item.copy(\n                    including_children=including_children,\n                    parent=checkbox)\n        checkbox._orig_start = self._orig_start\n        checkbox._orig_len = self._orig_len\n\n        checkbox._dirty_heading = self.is_dirty_checkbox\n\n        return checkbox\n\n    @classmethod\n    def parse_checkbox_from_data(cls, data, heading=None, orig_start=None):\n        u\"\"\" Construct a new checkbox from the provided data\n\n        :data:            List of lines\n        :heading:        The heading object this checkbox belongs to\n        :orig_start:    The original start of the heading in case it was read\n                        from a document. If orig_start is provided, the\n                        resulting heading will not be marked dirty.\n\n        :returns:    The newly created checkbox\n        \"\"\"\n        def parse_title(heading_line):\n            # checkbox is not heading\n            if REGEX_HEADING.match(heading_line) is not None:\n                return None\n            m = REGEX_CHECKBOX.match(heading_line)\n            if m:\n                r = m.groupdict()\n                return (len(r[u'level']), r[u'type'], r[u'status'], r[u'title'])\n\n            return None\n\n        if not data:\n            raise ValueError(u'Unable to create checkbox, no data provided.')\n\n        # create new checkbox\n        nc = cls()\n        nc.level, nc.type, nc.status, nc.title = parse_title(data[0])\n        nc.body = data[1:]\n        if orig_start is not None:\n            nc._dirty_heading = False\n            nc._dirty_body = False\n            nc._orig_start = orig_start\n            nc._orig_len = len(nc)\n        if heading:\n            nc._heading = heading\n\n        return nc\n\n    def update_subtasks(self, total=0, on=0):\n        if total != 0:\n            percent = (on * 100) / total\n        else:\n            percent = 0\n\n        count = \"%d/%d\" % (on, total)\n        self.title = REGEX_SUBTASK.sub(\"[%s]\" % (count), self.title)\n        self.title = REGEX_SUBTASK_PERCENT.sub(\"[%d%%]\" % (percent), self.title)\n        d = self._heading.document.write_checkbox(self, including_children=False)\n\n    @classmethod\n    def identify_checkbox(cls, line):\n        u\"\"\" Test if a certain line is a checkbox or not.\n\n        :line: the line to check\n\n        :returns: indent_level\n        \"\"\"\n        # checkbox is not heading\n        if REGEX_HEADING.match(line) is not None:\n            return None\n        m = REGEX_CHECKBOX.match(line)\n        if m:\n            r = m.groupdict()\n            return len(r[u'level'])\n\n        return None\n\n    @property\n    def is_dirty(self):\n        u\"\"\" Return True if the heading's body is marked dirty \"\"\"\n        return self._dirty_checkbox or self._dirty_body\n\n    @property\n    def is_dirty_checkbox(self):\n        u\"\"\" Return True if the heading is marked dirty \"\"\"\n        return self._dirty_checkbox\n\n    def get_index_in_parent_list(self):\n        \"\"\" Retrieve the index value of current checkbox in the parents list of\n        checkboxes. This works also for top level checkboxes.\n\n        :returns:    Index value or None if heading doesn't have a\n                    parent/document or is not in the list of checkboxes\n        \"\"\"\n        if self.parent:\n            return super(Checkbox, self).get_index_in_parent_list()\n        elif self.document:\n            l = self.get_parent_list()\n            if l:\n                return l.index(self)\n\n    def get_parent_list(self):\n        \"\"\" Retrieve the parents' list of headings. This works also for top\n        level headings.\n\n        :returns:    List of headings or None if heading doesn't have a\n                    parent/document or is not in the list of headings\n        \"\"\"\n        if self.parent:\n            return super(Checkbox, self).get_parent_list()\n        elif self.document:\n            if self in self.document.checkboxes:\n                return self.document.checkboxes\n\n    def set_dirty(self):\n        u\"\"\" Mark the heading and body dirty so that it will be rewritten when\n        saving the document \"\"\"\n        self._dirty_checkbox = True\n        self._dirty_body = True\n        if self._document:\n            self._document.set_dirty_document()\n\n    def set_dirty_checkbox(self):\n        u\"\"\" Mark the checkbox dirty so that it will be rewritten when saving the\n        document \"\"\"\n        self._dirty_checkbox = True\n        if self._document:\n            self._document.set_dirty_document()\n\n    @property\n    def previous_checkbox(self):\n        u\"\"\" Serialized access to the previous checkbox \"\"\"\n        return super(Checkbox, self).previous_item\n\n    @property\n    def next_checkbox(self):\n        u\"\"\" Serialized access to the next checkbox \"\"\"\n        return super(Checkbox, self).next_item\n\n    @property\n    def first_checkbox(self):\n        u\"\"\" Access to the first child heading or None if no children exist \"\"\"\n        if self.children:\n            return self.children[0]\n\n    @property\n    def start(self):\n        u\"\"\" Access to the starting line of the checkbox \"\"\"\n        return super(Checkbox, self).start\n\n    def toggle(self):\n        u\"\"\" Toggle status of this checkbox \"\"\"\n        if self.status == Checkbox.STATUS_OFF or self.status is None:\n            self.status = Checkbox.STATUS_ON\n        else:\n            self.status = Checkbox.STATUS_OFF\n        self.set_dirty()\n\n    def all_siblings(self):\n        if not self.parent:\n            p = self._heading\n        else:\n            p = self.parent\n            if not p.children:\n                return\n\n        c = p.first_checkbox\n        while c:\n            yield c\n            c = c.next_sibling\n        return\n\n    def all_children(self):\n        if not self.children:\n            return\n\n        c = self.first_checkbox\n        while c:\n            yield c\n            for d in c.all_children():\n                yield d\n            c = c.next_sibling\n\n        return\n\n    def all_children_status(self):\n        u\"\"\" Return checkboxes status for current checkbox's all children\n\n        :return: (total, on)\n            total: total # of checkboxes\n            on:       # of checkboxes which are on\n        \"\"\"\n        total, on = 0, 0\n        for c in self.all_children():\n            if c.status is not None:\n                total += 1\n\n                if c.status == Checkbox.STATUS_ON:\n                    on += 1\n\n        return (total, on)\n\n    def all_siblings_status(self):\n        u\"\"\" Return checkboxes status for current checkbox's all siblings\n\n        :return: (total, on)\n            total: total # of checkboxes\n            on:       # of checkboxes which are on\n        \"\"\"\n        total, on = 0, 0\n        for c in self.all_siblings():\n            if c.status is not None:\n                total += 1\n\n                if c.status == Checkbox.STATUS_ON:\n                    on += 1\n\n        return (total, on)\n\n    def are_children_all(self, status):\n        u\"\"\" Check all children checkboxes status \"\"\"\n        clen = len(self.children)\n        for i in range(clen):\n            if self.children[i].status != status:\n                return False\n            # recursively check children's status\n            if not self.children[i].are_children_all(status):\n                return False\n\n        return True\n\n    def is_child_one(self, status):\n        u\"\"\" Return true, if there is one child with given status \"\"\"\n        clen = len(self.children)\n        for i in range(clen):\n            if self.children[i].status == status:\n                return True\n\n        return False\n\n    def are_siblings_all(self, status):\n        u\"\"\" Check all sibling checkboxes status \"\"\"\n        for c in self.all_siblings():\n            if c.status != status:\n                return False\n\n        return True\n\n    @DomObj.level.setter\n    def level(self, value):\n        u\"\"\" Set the checkbox level and mark the checkbox and the document\n        dirty \"\"\"\n        self._level = int(value)\n        self.set_dirty_checkbox()\n\n    @DomObj.title.setter\n    def title(self, value):\n        u\"\"\" Set the title and mark the document and the checkbox dirty \"\"\"\n        if type(value) not in (unicode, str):\n            raise ValueError(u'Title must be a string.')\n        v = value\n        if type(v) == str:\n            v = u_decode(v)\n        self._title = v.strip()\n        self.set_dirty_checkbox()\n\n    @property\n    def status(self):\n        u\"\"\" status of current checkbox \"\"\"\n        return self._status\n\n    @status.setter\n    def status(self, value):\n        self._status = value\n        self.set_dirty()\n\n    @status.deleter\n    def status(self):\n        self._status = u''\n\n    @property\n    def type(self):\n        u\"\"\" type of current checkbox list type \"\"\"\n        return self._type\n\n    @type.setter\n    def type(self, value):\n        self._type = value\n\n    @type.deleter\n    def type(self):\n        self._type = u''\n\n\nclass CheckboxList(DomObjList):\n    u\"\"\"\n    Checkbox List\n    \"\"\"\n    def __init__(self, initlist=None, obj=None):\n        \"\"\"\n        :initlist:    Initial data\n        :obj:        Link to a concrete Checkbox or Document object\n        \"\"\"\n        # it's not necessary to register a on_change hook because the heading\n        # list will itself take care of marking headings dirty or adding\n        # headings to the deleted headings list\n        DomObjList.__init__(self, initlist, obj)\n\n    @classmethod\n    def is_checkbox(cls, obj):\n        return CheckboxList.is_domobj(obj)\n\n    def _get_heading(self):\n        if self.__class__.is_checkbox(self._obj):\n            return self._obj._document\n        return self._obj\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/documents.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    documents\n    ~~~~~~~~~\n\n    TODO: explain this :)\n\"\"\"\n\ntry:\n    from collections import UserList\nexcept:\n    from UserList import UserList\n\nfrom orgmode.liborgmode.base import MultiPurposeList, flatten_list, Direction, get_domobj_range\nfrom orgmode.liborgmode.headings import Heading, HeadingList\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\nclass Document(object):\n    u\"\"\"\n    Representation of a whole org-mode document.\n\n    A Document consists basically of headings (see Headings) and some metadata.\n\n    TODO: explain the 'dirty' mechanism\n    \"\"\"\n\n    def __init__(self):\n        u\"\"\"\n        Don't call this constructor directly but use one of the concrete\n        implementations.\n\n        TODO: what are the concrete implementatiions?\n        \"\"\"\n        object.__init__(self)\n\n        # is a list - only the Document methods should work on this list!\n        self._content = None\n        self._dirty_meta_information = False\n        self._dirty_document = False\n        self._meta_information = MultiPurposeList(\n            on_change=self.set_dirty_meta_information)\n        self._orig_meta_information_len = None\n        self._headings = HeadingList(obj=self)\n        self._deleted_headings = []\n\n        # settings needed to align tags properly\n        self._tabstop = 8\n        self._tag_column = 77\n\n        # TODO this doesn't differentiate between ACTIVE and FINISHED todo's\n        self.todo_states = [u'TODO', u'DONE']\n\n    def __unicode__(self):\n        if self.meta_information is None:\n            return u'\\n'.join(self.all_headings())\n        return u'\\n'.join(self.meta_information) + u'\\n' + u'\\n'.join([u'\\n'.join([unicode(i)] + i.body) for i in self.all_headings()])\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def get_all_todo_states(self):\n        u\"\"\" Convenience function that returns all todo and done states and\n        sequences in one big list.\n\n        Returns:\n            list: [all todo/done states]\n        \"\"\"\n        # TODO This is not necessary remove\n        return flatten_list(self.get_todo_states())\n\n    def get_todo_states(self):\n        u\"\"\" Returns a list containing a tuple of two lists of allowed todo\n        states split by todo and done states. Multiple todo-done state\n        sequences can be defined.\n\n        Returns:\n            list: [([todo states], [done states]), ..]\n        \"\"\"\n        # TODO this should be made into property so todo states can be set like\n        # this too.. or there was also some todo property around... oh well..\n        # TODO there is the same method in vimbuffer\n        return self.todo_states\n\n    @property\n    def tabstop(self):\n        u\"\"\" Tabstop for this document \"\"\"\n        return self._tabstop\n\n    @tabstop.setter\n    def tabstop(self, value):\n        self._tabstop = value\n\n    @property\n    def tag_column(self):\n        u\"\"\" The column all tags are right-aligned to \"\"\"\n        return self._tag_column\n\n    @tag_column.setter\n    def tag_column(self, value):\n        self._tag_column = value\n\n    def init_dom(self, heading=Heading):\n        u\"\"\" Initialize all headings in document - build DOM. This method\n        should be call prior to accessing the document.\n\n        Returns:\n            self\n        \"\"\"\n        def init_heading(_h):\n            u\"\"\"\n            :returns    the initialized heading\n            \"\"\"\n            start = _h.end + 1\n            prev_heading = None\n            while True:\n                new_heading = self.find_heading(start, heading=heading)\n\n                # * Heading 1 <- heading\n                # * Heading 1 <- sibling\n                # or\n                # * Heading 2 <- heading\n                # * Heading 1 <- parent's sibling\n                if not new_heading or \\\n                    new_heading.level <= _h.level:\n                    break\n\n                # * Heading 1 <- heading\n                #  * Heading 2 <- first child\n                #  * Heading 2 <- another child\n                new_heading._parent = _h\n                if prev_heading:\n                    prev_heading._next_sibling = new_heading\n                    new_heading._previous_sibling = prev_heading\n                _h.children.data.append(new_heading)\n                # the start and end computation is only\n                # possible when the new heading was properly\n                # added to the document structure\n                init_heading(new_heading)\n                if new_heading.children:\n                    # skip children\n                    start = new_heading.end_of_last_child + 1\n                else:\n                    start = new_heading.end + 1\n                prev_heading = new_heading\n\n            return _h\n\n        h = self.find_heading(heading=heading)\n        # initialize meta information\n        if h:\n            self._meta_information.data.extend(self._content[:h._orig_start])\n        else:\n            self._meta_information.data.extend(self._content[:])\n        self._orig_meta_information_len = len(self.meta_information)\n\n        # initialize dom tree\n        prev_h = None\n        while h:\n            if prev_h:\n                prev_h._next_sibling = h\n                h._previous_sibling = prev_h\n            self.headings.data.append(h)\n            init_heading(h)\n            prev_h = h\n            h = self.find_heading(h.end_of_last_child + 1, heading=heading)\n\n        return self\n\n    @property\n    def meta_information(self):\n        u\"\"\" Meta information is text that precedes all headings in an org-mode\n        document. It might contain additional information about the document,\n        e.g. author\n        \"\"\"\n        return self._meta_information\n\n    @meta_information.setter\n    def meta_information(self, value):\n        if self._orig_meta_information_len is None:\n            self._orig_meta_information_len = len(self.meta_information)\n        if type(value) in (list, tuple) or isinstance(value, UserList):\n            self._meta_information[:] = flatten_list(value)\n        elif type(value) in (str, ):\n            self._meta_information[:] = u_decode(value).split(u'\\n')\n        elif type(value) in (unicode, ):\n            self._meta_information[:] = value.split(u'\\n')\n        self.set_dirty_meta_information()\n\n    @meta_information.deleter\n    def meta_information(self):\n        self.meta_information = u''\n\n    @property\n    def headings(self):\n        u\"\"\" List of top level headings \"\"\"\n        return self._headings\n\n    @headings.setter\n    def headings(self, value):\n        self._headings[:] = value\n\n    @headings.deleter\n    def headings(self):\n        del self.headings[:]\n\n    def write(self):\n        u\"\"\" Write the document\n\n        Returns:\n            bool: True if something was written, otherwise False\n        \"\"\"\n        raise NotImplementedError(u'Abstract method, please use concrete implementation!')\n\n    def set_dirty_meta_information(self):\n        u\"\"\" Mark the meta information dirty.\n\n        Note:\n            Causes meta information to be rewritten when saving the document\n        \"\"\"\n        self._dirty_meta_information = True\n\n    def set_dirty_document(self):\n        u\"\"\" Mark the whole document dirty.\n\n        Note:\n            When changing a heading this method must be executed in order to\n            changed computation of start and end positions from a static to a\n            dynamic computation\n        \"\"\"\n        self._dirty_document = True\n\n    @property\n    def is_dirty(self):\n        u\"\"\" Return information about unsaved changes for the document and all\n        related headings.\n\n        Returns:\n            bool: True if document contains unsaved changes.\n        \"\"\"\n        if self.is_dirty_meta_information:\n            return True\n\n        if self.is_dirty_document:\n            return True\n\n        if self._deleted_headings:\n            return True\n\n        return False\n\n    @property\n    def is_dirty_meta_information(self):\n        u\"\"\" Return True if the meta information is marked dirty \"\"\"\n        return self._dirty_meta_information\n\n    @property\n    def is_dirty_document(self):\n        u\"\"\" Return True if the document is marked dirty \"\"\"\n        return self._dirty_document\n\n    def all_headings(self):\n        u\"\"\" Iterate over all headings of the current document in serialized\n        order\n\n        :returns:    Returns an iterator object which returns all headings of\n                    the current file in serialized order\n        \"\"\"\n        if not self.headings:\n            return\n\n        h = self.headings[0]\n        while h:\n            yield h\n            h = h.next_heading\n        return\n\n    def find_heading(\n        self, position=0, direction=Direction.FORWARD, heading=Heading,\n        connect_with_document=True):\n        u\"\"\" Find heading in the given direction\n\n        Args:\n            position (int): starting line, counting from 0 (in vim you start\n                    counting from 1, don't forget)\n            direction: downwards == Direction.FORWARD,\n                    upwards == Direction.BACKWARD\n            heading:   Heading class from which new heading objects will be\n                    instantiated\n            connect_with_document: if True, the newly created heading will be\n                    connected with the document, otherwise not\n\n        Returns:\n            heading or None: New heading\n        \"\"\"\n        start, end = get_domobj_range(\n            content=self._content, position=position, direction=direction,\n            identify_fun=heading.identify_heading)\n\n        if start is None:\n            return None\n\n        if end is None:\n            end = len(self._content) - 1\n\n        document = self if connect_with_document else None\n\n        return heading.parse_heading_from_data(\n            self._content[start:end + 1], self.get_all_todo_states(),\n            document=document, orig_start=start)\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/dom_obj.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    dom object\n    ~~~~~~~~~~\n\n    TODO: explain this :)\n\"\"\"\n\nimport re\nfrom orgmode.liborgmode.base import MultiPurposeList, flatten_list\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\ntry:\n    from collections import UserList\nexcept:\n    from UserList import UserList\n\n# breaking down tasks regex\nREGEX_SUBTASK = re.compile(r'\\[(\\d*)/(\\d*)\\]')\nREGEX_SUBTASK_PERCENT = re.compile(r'\\[(\\d*)%\\]')\n\n# heading regex\nREGEX_HEADING = re.compile(\n    r'^(?P<level>\\*+)(\\s+(?P<title>.*?))?\\s*(\\s(?P<tags>:[\\w_:@]+:))?$',\n    flags=re.U)\nREGEX_TAG = re.compile(\n    r'^\\s*((?P<title>[^\\s]*?)\\s+)?(?P<tags>:[\\w_:@]+:)$',\n    flags=re.U)\nREGEX_TODO = re.compile(r'^[^\\s]*$')\n\n# checkbox regex:\n#   - [ ] checkbox item\n# - [X] checkbox item\n# - [ ]\n# - no status checkbox\nUnOrderListType = [u'-', u'+', u'*']\nOrderListType = [u'.', u')']\nREGEX_CHECKBOX = re.compile(\n    r'^(?P<level>\\s*)(?P<type>[%s]|([a-zA-Z]|[\\d]+)[%s])(\\s+(?P<status>\\[.\\]))?\\s*(?P<title>.*)$'\n    % (''.join(UnOrderListType), ''.join(OrderListType)), flags=re.U)\n\n\nclass DomObj(object):\n    u\"\"\"\n    A DomObj is DOM structure element, like Heading and Checkbox.\n    Its purpose is to abstract the same parts of Heading and Checkbox objects,\n    and make code reusable.\n\n    All methods and properties are extracted from Heading object.\n    Heading and Checkbox objects inherit from DomObj, and override some specific\n    methods in their own objects.\n\n    Normally, we don't intend to use DomObj directly. However, we can add some more\n    DOM structure element based on this class to make code more concise.\n    \"\"\"\n    # TODO should this and DomObj_list be abstract methods? If so use ABC to\n    # force abstract methods\n\n    def __init__(self, level=1, title=u'', body=None):\n        u\"\"\"\n        :level:        Level of the dom object\n        :title:        Title of the dom object\n        :body:        Body of the dom object\n        \"\"\"\n        object.__init__(self)\n\n        self._document = None\n        self._parent = None\n        self._previous_sibling = None\n        self._next_sibling = None\n        self._children = MultiPurposeList()\n        self._orig_start = None\n        self._orig_len = 0\n\n        self._level = level\n        # title\n        self._title = u''\n        if title:\n            self.title = title\n\n        # body\n        self._dirty_body = False\n        self._body = MultiPurposeList(on_change=self.set_dirty_body)\n        if body:\n            self.body = body\n\n    def __unicode__(self):\n        return u'<dom obj level=%s, title=%s>' % (level, title)\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def __len__(self):\n        # 1 is for the heading's title\n        return 1 + len(self.body)\n\n    @property\n    def is_dirty(self):\n        u\"\"\" Return True if the dom obj body is marked dirty \"\"\"\n        return self._dirty_body\n\n    @property\n    def is_dirty_body(self):\n        u\"\"\" Return True if the dom obj body is marked dirty \"\"\"\n        return self._dirty_body\n\n    def get_index_in_parent_list(self):\n        \"\"\" Retrieve the index value of current dom obj in the parents list of\n        dom objs. This works also for top level dom objs.\n\n        :returns:    Index value or None if dom obj doesn't have a\n                    parent/document or is not in the list of dom objs\n        \"\"\"\n        l = self.get_parent_list()\n        if l:\n            return l.index(self)\n\n    def get_parent_list(self):\n        \"\"\" Retrieve the parents list of dom objs. This works also for top\n        level dom objs.\n\n        :returns:    List of dom objs or None if dom objs doesn't have a\n                    parent/document or is not in the list of dom objs\n        \"\"\"\n        if self.parent:\n            if self in self.parent.children:\n                return self.parent.children\n\n    def set_dirty(self):\n        u\"\"\" Mark the dom objs and body dirty so that it will be rewritten when\n        saving the document \"\"\"\n        if self._document:\n            self._document.set_dirty_document()\n\n    def set_dirty_body(self):\n        u\"\"\" Mark the dom objs' body dirty so that it will be rewritten when\n        saving the document \"\"\"\n        self._dirty_body = True\n        if self._document:\n            self._document.set_dirty_document()\n\n    @property\n    def document(self):\n        u\"\"\" Read only access to the document. If you want to change the\n        document, just assign the dom obj to another document \"\"\"\n        return self._document\n\n    @property\n    def parent(self):\n        u\"\"\" Access to the parent dom obj \"\"\"\n        return self._parent\n\n    @property\n    def number_of_parents(self):\n        u\"\"\" Access to the number of parent dom objs before reaching the root\n        document \"\"\"\n        def count_parents(h):\n            if h.parent:\n                return 1 + count_parents(h.parent)\n            else:\n                return 0\n        return count_parents(self)\n\n    @property\n    def previous_sibling(self):\n        u\"\"\" Access to the previous dom obj that's a sibling of the current one\n        \"\"\"\n        return self._previous_sibling\n\n    @property\n    def next_sibling(self):\n        u\"\"\" Access to the next dom obj that's a sibling of the current one \"\"\"\n        return self._next_sibling\n\n    @property\n    def previous_item(self):\n        u\"\"\" Serialized access to the previous dom obj \"\"\"\n        if self.previous_sibling:\n            h = self.previous_sibling\n            while h.children:\n                h = h.children[-1]\n            return h\n        elif self.parent:\n            return self.parent\n\n    @property\n    def next_item(self):\n        u\"\"\" Serialized access to the next dom obj \"\"\"\n        if self.children:\n            return self.children[0]\n        elif self.next_sibling:\n            return self.next_sibling\n        else:\n            h = self.parent\n            while h:\n                if h.next_sibling:\n                    return h.next_sibling\n                else:\n                    h = h.parent\n\n    @property\n    def start(self):\n        u\"\"\" Access to the starting line of the dom obj \"\"\"\n        if self.document is None or not self.document.is_dirty:\n            return self._orig_start\n\n        def item_len_generator(h):\n            while h:\n                yield len(h)\n                h = h.previous_item\n        return sum(item for item in item_len_generator(self.previous_item))\n\n    @property\n    def start_vim(self):\n        if self.start is not None:\n            return self.start + 1\n\n    @property\n    def end(self):\n        u\"\"\" Access to the ending line of the dom obj \"\"\"\n        if self.start is not None:\n            return self.start + len(self.body)\n\n    @property\n    def end_vim(self):\n        if self.end is not None:\n            return self.end + 1\n\n    @property\n    def end_of_last_child(self):\n        u\"\"\" Access to end of the last child \"\"\"\n        if self.children:\n            child = self.children[-1]\n            while child.children:\n                child = child.children[-1]\n            return child.end\n        return self.end\n\n    @property\n    def end_of_last_child_vim(self):\n        return self.end_of_last_child + 1\n\n    @property\n    def children(self):\n        u\"\"\" MultiPurposeList[dom_objects??]: subheadings of the current DomObj\n\n        Setter method takes list, tuple or userlist with DOMObjects\n        \"\"\"\n        return self._children\n\n    @children.setter\n    def children(self, value):\n        v = value\n        if type(v) in (list, tuple) or isinstance(v, UserList):\n            v = flatten_list(v)\n        self._children[:] = v\n\n    @children.deleter\n    def children(self):\n        del self.children[:]\n\n    @property\n    def first_child(self):\n        u\"\"\" Access to the first child dom obj or None if no children exist \"\"\"\n        if self.children:\n            return self.children[0]\n\n    @property\n    def last_child(self):\n        u\"\"\" Access to the last child dom obj or None if no children exist \"\"\"\n        if self.children:\n            return self.children[-1]\n\n    @property\n    def level(self):\n        u\"\"\" int: Access the the dom obj level\n\n        Setter sets the DOM object and the document as dirty if invoked.\n        \"\"\"\n        return self._level\n\n    @level.setter\n    def level(self, value):\n        # TODO Shouldn't there be and error when values is not int?\n        self._level = int(value)\n        self.set_dirty()\n\n    @level.deleter\n    def level(self):\n        self.level = None\n\n    @property\n    def title(self):\n        u\"\"\" str: Get the title of current dom object\n\n        Setter sets the DOM object and the document as dirty if invoked.\n        \"\"\"\n        return self._title.strip()\n\n    @title.setter\n    def title(self, value):\n        if type(value) not in (unicode, str):\n            raise ValueError(u'Title must be a string.')\n        v = value\n        if type(v) == str:\n            v = u_decode(v)\n        self._title = v.strip()\n        self.set_dirty()\n\n    @title.deleter\n    def title(self):\n        self._title = u''\n\n    @property\n    def body(self):\n        u\"\"\" MultiPurposeList[]: Holds the content belonging to the heading \"\"\"\n        return self._body\n\n    @body.setter\n    def body(self, value):\n        if type(value) in (list, tuple) or isinstance(value, UserList):\n            self._body[:] = flatten_list(value)\n        elif type(value) in (str, ):\n            self._body[:] = u_decode(value).split(u'\\n')\n        elif type(value) in (unicode, ):\n            self._body[:] = value.split(u'\\n')\n        else:\n            self.body = list(unicode(value))\n\n    @body.deleter\n    def body(self):\n        # TODO write this as del self._body[:] because there is no reason to\n        # call so much code for deleting a list\n        self.body = []\n\n\nclass DomObjList(MultiPurposeList):\n    u\"\"\"\n    A Dom Obj List\n    \"\"\"\n    def __init__(self, initlist=None, obj=None):\n        \"\"\"\n        :initlist:    Initial data\n        :obj:        Link to a concrete Heading or Document object\n        \"\"\"\n        # it's not necessary to register a on_change hook because the heading\n        # list will itself take care of marking headings dirty or adding\n        # headings to the deleted headings list\n        MultiPurposeList.__init__(self)\n\n        self._obj = obj\n\n        # initialization must be done here, because\n        # self._document is not initialized when the\n        # constructor of MultiPurposeList is called\n        if initlist:\n            self.extend(initlist)\n\n    @classmethod\n    def is_domobj(cls, obj):\n        # TODO no reason for it to be class method. Does it even need to exist\n        # because it is quite clear what isinstance does and in derived methods\n        # isinstance(Heading, DomObj) would return True anyway.\n        return isinstance(obj, DomObj)\n\n    # TODO this should be made into a property\n    def _get_document(self):\n        if self.__class__.is_domobj(self._obj):\n            return self._obj._document\n        return self._obj\n\n    def __setitem__(self, i, item):\n        if isinstance(i, slice):\n            o = item\n            if self.__class__.is_domobj(o):\n                o = (o, )\n            o = flatten_list(o)\n            for item in o:\n                if not self.__class__.is_domobj(item):\n                    raise ValueError(u'List contains items that are not a Dom obj!')\n\n            # self._add_to_deleted_domobjs(self[i:j])\n            # self._associate_domobj(o, \\\n            # self[i - 1] if i - 1 >= 0 and i < len(self) else None, \\\n            # self[j] if j >= 0 and j < len(self) else None)\n            MultiPurposeList.__setitem__(self, i, o)\n        else:\n            if not self.__class__.is_domobj(item):\n                raise ValueError(u'Item is not a Dom obj!')\n            if item in self:\n                raise ValueError(u'Dom obj is already part of this list!')\n            # self._add_to_deleted_domobjs(self[i])\n\n            # self._associate_domobj(item, \\\n            # self[i - 1] if i - 1 >= 0 else None, \\\n            # self[i + 1] if i + 1 < len(self) else None)\n            MultiPurposeList.__setitem__(self, i, item)\n\n    def __delitem__(self, i, taint=True):\n        if isinstance(i, slice):\n            items = self[i]\n            if items:\n                first = items[0]\n                last = items[-1]\n                if first.previous_sibling:\n                    first.previous_sibling._next_sibling = last.next_sibling\n                if last.next_sibling:\n                    last.next_sibling._previous_sibling = first.previous_sibling\n            # if taint:\n                # self._add_to_deleted_domobjs(items)\n        else:\n            item = self[i]\n            if item.previous_sibling:\n                item.previous_sibling._next_sibling = item.next_sibling\n            if item.next_sibling:\n                item.next_sibling._previous_sibling = item.previous_sibling\n\n            # if taint:\n                # self._add_to_deleted_domobjs(item)\n        MultiPurposeList.__delitem__(self, i)\n\n    def __setslice__(self, i, j, other):\n        self.__setitem__(slice(i, j), other)\n\n    def __delslice__(self, i, j, taint=True):\n        self.__delitem__(slice(i, j), taint=taint)\n\n    def __iadd__(self, other):\n        o = other\n        if self.__class__.is_domobj(o):\n            o = (o, )\n        for item in flatten_list(o):\n            if not self.__class__.is_domobj(item):\n                raise ValueError(u'List contains items that are not a Dom obj!')\n        # self._associate_domobj(o, self[-1] if len(self) > 0 else None, None)\n        return MultiPurposeList.__iadd__(self, o)\n\n    def __imul__(self, n):\n        # TODO das müsste eigentlich ein klonen von objekten zur Folge haben\n        return MultiPurposeList.__imul__(self, n)\n\n    def append(self, item, taint=True):\n        if not self.__class__.is_domobj(item):\n            raise ValueError(u'Item is not a heading!')\n        if item in self:\n            raise ValueError(u'Heading is already part of this list!')\n        # self._associate_domobj(\n        #     item, self[-1] if len(self) > 0 else None,\n        #     None, taint=taint)\n        MultiPurposeList.append(self, item)\n\n    def insert(self, i, item, taint=True):\n        # self._associate_domobj(\n        #     item,\n        #     self[i - 1] if i - 1 >= 0 and i - 1 < len(self) else None,\n        #     self[i] if i >= 0 and i < len(self) else None, taint=taint)\n        MultiPurposeList.insert(self, i, item)\n\n    def pop(self, i=-1):\n        item = self[i]\n        # self._add_to_deleted_domobjs(item)\n        del self[i]\n        return item\n\n    def remove_slice(self, i, j, taint=True):\n        self.__delitem__(slice(i, j), taint=taint)\n\n    def remove(self, item, taint=True):\n        self.__delitem__(self.index(item), taint=taint)\n\n    def reverse(self):\n        MultiPurposeList.reverse(self)\n        prev_h = None\n        for h in self:\n            h._previous_sibling = prev_h\n            h._next_sibling = None\n            prev_h._next_sibling = h\n            h.set_dirty()\n            prev_h = h\n\n    def sort(self, *args, **kwds):\n        MultiPurposeList.sort(*args, **kwds)\n        prev_h = None\n        for h in self:\n            h._previous_sibling = prev_h\n            h._next_sibling = None\n            prev_h._next_sibling = h\n            h.set_dirty()\n            prev_h = h\n\n    def extend(self, other):\n        o = other\n        if self.__class__.is_domobj(o):\n            o = (o, )\n        for item in o:\n            if not self.__class__.is_domobj(item):\n                raise ValueError(u'List contains items that are not a heading!')\n        # self._associate_domobj(o, self[-1] if len(self) > 0 else None, None)\n        MultiPurposeList.extend(self, o)\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/headings.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    headings\n    ~~~~~~~~~\n\n    TODO: explain this :)\n\"\"\"\n\nimport re\n\nimport vim\nfrom orgmode.liborgmode.base import MultiPurposeList, flatten_list, Direction, get_domobj_range\nfrom orgmode.liborgmode.orgdate import OrgTimeRange\nfrom orgmode.liborgmode.orgdate import get_orgdate\nfrom orgmode.liborgmode.checkboxes import Checkbox, CheckboxList\nfrom orgmode.liborgmode.dom_obj import DomObj, DomObjList, REGEX_SUBTASK, REGEX_SUBTASK_PERCENT, REGEX_HEADING, REGEX_TAG, REGEX_TODO\n\nfrom orgmode.py3compat.xrange_compatibility import *\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\ntry:\n    from collections import UserList\nexcept:\n    from UserList import UserList\n    from itertools import ifilter as filter\n\nclass Heading(DomObj):\n    u\"\"\" Structural heading object \"\"\"\n\n    def __init__(self, level=1, title=u'', tags=None, todo=None, body=None, active_date=None):\n        u\"\"\"\n        :level:        Level of the heading\n        :title:        Title of the heading\n        :tags:        Tags of the heading\n        :todo:        Todo state of the heading\n        :body:        Body of the heading\n        :active_date: active date that is used in the agenda\n        \"\"\"\n        DomObj.__init__(self, level=level, title=title, body=body)\n\n        self._children = HeadingList(obj=self)\n        self._dirty_heading = False\n\n        # todo\n        self._todo = None\n        if todo:\n            self.todo = todo\n\n        # tags\n        self._tags = MultiPurposeList(on_change=self.set_dirty_heading)\n        if tags:\n            self.tags = tags\n\n        # active date\n        self._active_date = active_date\n        if active_date:\n            self.active_date = active_date\n\n        # checkboxes\n        self._checkboxes = CheckboxList(obj=self)\n        self._cached_checkbox = None\n\n    def __unicode__(self):\n        res = u'*' * self.level\n        if self.todo:\n            res = u' '.join((res, self.todo))\n        if self.title:\n            res = u' '.join((res, self.title))\n\n        # compute position of tags\n        if self.tags:\n            tabs = 0\n            spaces = 2\n            tags = u':%s:' % (u':'.join(self.tags), )\n\n            # FIXME this is broken because of missing associations for headings\n            ts = 6\n            tag_column = 77\n            if self.document:\n                ts = self.document.tabstop\n                tag_column = self.document.tag_column\n\n            len_heading = len(res)\n            len_tags = len(tags)\n            if len_heading + spaces + len_tags < tag_column:\n                spaces_to_next_tabstop = ts - divmod(len_heading, ts)[1]\n\n                if len_heading + spaces_to_next_tabstop + len_tags < tag_column:\n                    tabs, spaces = divmod(\n                        tag_column - (len_heading + spaces_to_next_tabstop + len_tags),\n                        ts)\n\n                    if spaces_to_next_tabstop:\n                        tabs += 1\n                else:\n                    spaces = tag_column - (len_heading + len_tags)\n\n            res += u'\\t' * tabs + u' ' * spaces + tags\n\n        # append a trailing space when there are just * and no text\n        if len(res) == self.level:\n            res += u' '\n        return res\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def __len__(self):\n        # 1 is for the heading's title\n        return 1 + len(self.body)\n\n    def __lt__(self, other):\n        \"\"\"\n        Headings can be sorted by date.\n        \"\"\"\n        try:\n            if self.active_date < other.active_date:\n                return True\n            elif self.active_date == other.active_date:\n                return False\n            elif self.active_date > other.active_date:\n                return False\n        except:\n            if self.active_date and not other.active_date:\n                return True\n            elif not self.active_date and other.active_date:\n                return False\n            elif not self.active_date and not other.active_date:\n                return False\n\n    def __le__(self, other):\n        \"\"\"\n        Headings can be sorted by date.\n        \"\"\"\n        try:\n            if self.active_date < other.active_date:\n                return True\n            elif self.active_date == other.active_date:\n                return True\n            elif self.active_date > other.active_date:\n                return False\n        except:\n            if self.active_date and not other.active_date:\n                return True\n            elif not self.active_date and other.active_date:\n                return False\n            elif not self.active_date and not other.active:\n                return True\n\n    def __ge__(self, other):\n        \"\"\"\n        Headings can be sorted by date.\n        \"\"\"\n        try:\n            if self.active_date > other.active_date:\n                return True\n            elif self.active_date == other.active_date:\n                return True\n            elif self.active_date < other.active_date:\n                return False\n        except:\n            if not self.active_date and other.active_date:\n                return True\n            elif self.active_date and not other.active_date:\n                return False\n            elif not self.active_date and not other.active:\n                return True\n\n    def __gt__(self, other):\n        \"\"\"\n        Headings can be sorted by date.\n        \"\"\"\n        try:\n            if self.active_date > other.active_date:\n                return True\n            elif self.active_date == other.active_date:\n                return False\n            elif self.active_date < other.active_date:\n                return False\n        except:\n            if not self.active_date and other.active_date:\n                return True\n            elif self.active_date and not other.active_date:\n                return False\n            elif not self.active_date and not other.active:\n                return False\n\n    def copy(self, including_children=True, parent=None):\n        u\"\"\"\n        Create a copy of the current heading. The heading will be completely\n        detached and not even belong to a document anymore.\n\n        :including_children:    If True a copy of all children is create as\n                                well. If False the returned heading doesn't\n                                have any children.\n        :parent:                Don't use this parameter. It's set\n                                automatically.\n        \"\"\"\n        heading = self.__class__(\n            level=self.level, title=self.title,\n            tags=self.tags, todo=self.todo, body=self.body[:])\n        if parent:\n            parent.children.append(heading)\n        if including_children and self.children:\n            for item in self.children:\n                item.copy(\n                    including_children=including_children,\n                    parent=heading)\n        heading._orig_start = self._orig_start\n        heading._orig_len = self._orig_len\n\n        heading._dirty_heading = self.is_dirty_heading\n\n        return heading\n\n    def all_checkboxes(self):\n        u\"\"\" Iterate over all checkboxes of the current heading in serialized\n        order\n\n        :returns:    Returns an iterator object which returns all checkboxes of\n                    the current heading in serialized order\n        \"\"\"\n        if not self.checkboxes:\n            return\n\n        c = self.first_checkbox\n        while c:\n            yield c\n            c = c.next_checkbox\n        return\n\n    def all_toplevel_checkboxes(self):\n        u\"\"\" return all top level checkboxes for current heading \"\"\"\n        if not self.checkboxes:\n            return\n\n        c = self.first_checkbox\n        while c:\n            yield c\n            c = c.next_sibling\n        return\n\n    def find_checkbox(self, position=0, direction=Direction.FORWARD,\n        checkbox=Checkbox, connect_with_heading=True):\n        u\"\"\" Find checkbox in the given direction\n\n        :position: starting line, counting from 0 (in vim you start\n                    counting from 1, don't forget)\n        :direction: downwards == Direction.FORWARD,\n                    upwards == Direction.BACKWARD\n        :checkbox:  Checkbox class from which new checkbox objects will be\n                    instantiated\n        :connect_with_heading: if True, the newly created checkbox will be\n                                connected with the heading, otherwise not\n\n        :returns:    New checkbox object or None\n        \"\"\"\n        doc = self.document\n        (start, end) = get_domobj_range(content=doc._content, position=position, direction=direction, identify_fun=checkbox.identify_checkbox)\n        # if out of current headinig range, return None\n        heading_end = self.start + len(self) - 1\n        if start is not None and start > heading_end:\n            return None\n\n        if end is not None and end > heading_end:\n            end = heading_end\n\n        if start is not None and end is None:\n            end = heading_end\n        if start is not None and end is not None:\n            return checkbox.parse_checkbox_from_data(\n                doc._content[start:end + 1],\n                heading=self if connect_with_heading else None, orig_start=start)\n\n    def init_checkboxes(self, checkbox=Checkbox):\n        u\"\"\" Initialize all checkboxes in current heading - build DOM.\n\n        :returns:    self\n        \"\"\"\n        def init_checkbox(_c):\n            u\"\"\"\n            :returns    the initialized checkbox\n            \"\"\"\n            start = _c.end + 1\n            prev_checkbox = None\n            while True:\n                new_checkbox = self.find_checkbox(start, checkbox=checkbox)\n\n                # * Checkbox 1 <- checkbox\n                # * Checkbox 1 <- sibling\n                # or\n                #  * Checkbox 2 <- checkbox\n                # * Checkbox 1 <- parent's sibling\n                if not new_checkbox or \\\n                    new_checkbox.level <= _c.level:\n                    break\n\n                # * Checkbox 1 <- heading\n                #  * Checkbox 2 <- first child\n                #  * Checkbox 2 <- another child\n                new_checkbox._parent = _c\n                if prev_checkbox:\n                    prev_checkbox._next_sibling = new_checkbox\n                    new_checkbox._previous_sibling = prev_checkbox\n                _c.children.data.append(new_checkbox)\n                # the start and end computation is only\n                # possible when the new checkbox was properly\n                # added to the document structure\n                init_checkbox(new_checkbox)\n                if new_checkbox.children:\n                    # skip children\n                    start = new_checkbox.end_of_last_child + 1\n                else:\n                    start = new_checkbox.end + 1\n                prev_checkbox = new_checkbox\n\n            return _c\n\n        c = self.find_checkbox(checkbox=checkbox, position=self.start)\n\n        # initialize dom tree\n        prev_c = None\n        while c:\n            if prev_c and prev_c.level == c.level:\n                prev_c._next_sibling = c\n                c._previous_sibling = prev_c\n            self.checkboxes.data.append(c)\n            init_checkbox(c)\n            prev_c = c\n            c = self.find_checkbox(c.end_of_last_child + 1, checkbox=checkbox)\n\n        return self\n\n    def current_checkbox(self, position=None):\n        u\"\"\" Find the current checkbox (search backward) and return the related object\n        :returns:    Checkbox object or None\n        \"\"\"\n        if position is None:\n            position = vim.current.window.cursor[0] - 1\n\n        if not self.checkboxes:\n            return\n\n        def binaryFindInHeading():\n            hi = len(self.checkboxes)\n            lo = 0\n            while lo < hi:\n                mid = (lo + hi) // 2\n                c = self.checkboxes[mid]\n                if c.end_of_last_child < position:\n                    lo = mid + 1\n                elif c.start > position:\n                    hi = mid\n                else:\n                    return binaryFindCheckbox(c)\n\n        def binaryFindCheckbox(checkbox):\n            if not checkbox.children or checkbox.end >= position:\n                return checkbox\n\n            hi = len(checkbox.children)\n            lo = 0\n            while lo < hi:\n                mid = (lo + hi) // 2\n                c = checkbox.children[mid]\n                if c.end_of_last_child < position:\n                    lo = mid + 1\n                elif c.start > position:\n                    hi = mid\n                else:\n                    return binaryFindCheckbox(c)\n\n        # look at the cache to find the heading\n        c_tmp = self._cached_checkbox\n        if c_tmp is not None:\n            if c_tmp.end_of_last_child > position and \\\n                c_tmp.start < position:\n                if c_tmp.end < position:\n                    self._cached_checkbox = binaryFindCheckbox(c_tmp)\n                return self._cached_checkbox\n\n        self._cached_checkbox = binaryFindInHeading()\n        return self._cached_checkbox\n\n    @property\n    def first_checkbox(self):\n        u\"\"\" Access to the first child checkbox or None if no children exist \"\"\"\n        if self.checkboxes:\n            return self.checkboxes[0]\n\n    @classmethod\n    def parse_heading_from_data(\n        cls, data, allowed_todo_states, document=None,\n        orig_start=None):\n        u\"\"\" Construct a new heading from the provided data\n\n        :data:            List of lines\n        :allowed_todo_states: TODO???\n        :document:        The document object this heading belongs to\n        :orig_start:    The original start of the heading in case it was read\n                        from a document. If orig_start is provided, the\n                        resulting heading will not be marked dirty.\n\n        :returns:    The newly created heading\n        \"\"\"\n        test_not_empty = lambda x: x != u''\n\n        def parse_title(heading_line):\n            # WARNING this regular expression fails if there is just one or no\n            # word in the heading but a tag!\n            m = REGEX_HEADING.match(heading_line)\n            if m:\n                r = m.groupdict()\n                level = len(r[u'level'])\n                todo = None\n                title = u''\n                tags = filter(test_not_empty, r[u'tags'].split(u':')) if r[u'tags'] else []\n                tags = list(tags)\n\n                # if there is just one or no word in the heading, redo the parsing\n                mt = REGEX_TAG.match(r[u'title'])\n                if not tags and mt:\n                    r = mt.groupdict()\n                    tags = filter(test_not_empty, r[u'tags'].split(u':')) if r[u'tags'] else []\n                    tags = list(tags)\n                if r[u'title'] is not None:\n                    _todo_title = [i.strip() for i in r[u'title'].split(None, 1)]\n                    if _todo_title and _todo_title[0] in allowed_todo_states:\n                        todo = _todo_title[0]\n                        if len(_todo_title) > 1:\n                            title = _todo_title[1]\n                    else:\n                        title = r[u'title'].strip()\n\n                return (level, todo, title, tags)\n            raise ValueError(u'Data doesn\\'t start with a heading definition.')\n\n        if not data:\n            raise ValueError(u'Unable to create heading, no data provided.')\n\n        # create new heaing\n        new_heading = cls()\n        new_heading.level, new_heading.todo, new_heading.title, new_heading.tags = parse_title(data[0])\n        new_heading.body = data[1:]\n        if orig_start is not None:\n            new_heading._dirty_heading = False\n            new_heading._dirty_body = False\n            new_heading._orig_start = orig_start\n            new_heading._orig_len = len(new_heading)\n        if document:\n            new_heading._document = document\n\n        # try to find active dates\n        tmp_orgdate = get_orgdate(data)\n        if tmp_orgdate and tmp_orgdate.active \\\n            and not isinstance(tmp_orgdate, OrgTimeRange):\n            new_heading.active_date = tmp_orgdate\n        else:\n            new_heading.active_date = None\n\n        return new_heading\n\n    def update_subtasks(self, total=0, on=0):\n        u\"\"\" Update subtask information for current heading\n        :total:    total # of top level checkboxes\n        :on:    # of top level checkboxes which are on\n        \"\"\"\n        if total != 0:\n            percent = (on * 100) / total\n        else:\n            percent = 0\n\n        count = \"%d/%d\" % (on, total)\n        self.title = REGEX_SUBTASK.sub(\"[%s]\" % (count), self.title)\n        self.title = REGEX_SUBTASK_PERCENT.sub(\"[%d%%]\" % (percent), self.title)\n        self.document.write_heading(self, including_children=False)\n\n    @staticmethod\n    def identify_heading(line):\n        u\"\"\" Test if a certain line is a heading or not.\n\n        Args:\n            line (str): the line to check\n\n        Returns:\n            int or None: level of heading or None if line is not heading\n        \"\"\"\n        # TODO would it make sense to return 0 for heading level?\n        # TODO add tests e.g. '*** abc', '**', '', '* ', '*\\t', '*'\n        for i, item in enumerate(line):\n            if item == '*':\n                continue\n            elif i and item in ('\\t', ' '):\n                return i\n            break\n        return None\n\n    @property\n    def is_dirty(self):\n        u\"\"\" Return True if the heading's body is marked dirty \"\"\"\n        return self._dirty_heading or self._dirty_body\n\n    @property\n    def is_dirty_heading(self):\n        u\"\"\" Return True if the heading is marked dirty \"\"\"\n        return self._dirty_heading\n\n    def get_index_in_parent_list(self):\n        \"\"\" Retrieve the index value of current heading in the parents list of\n        headings. This works also for top level headings.\n\n        :returns:    Index value or None if heading doesn't have a\n                    parent/document or is not in the list of headings\n        \"\"\"\n        if self.parent:\n            return super(Heading, self).get_index_in_parent_list()\n        elif self.document:\n            l = self.get_parent_list()\n            if l:\n                return l.index(self)\n\n    def get_parent_list(self):\n        \"\"\" Retrieve the parents' list of headings. This works also for top\n        level headings.\n\n        :returns:    List of headings or None if heading doesn't have a\n                    parent/document or is not in the list of headings\n        \"\"\"\n        if self.parent:\n            return super(Heading, self).get_parent_list()\n        elif self.document:\n            if self in self.document.headings:\n                return self.document.headings\n\n    def set_dirty(self):\n        u\"\"\" Mark the heading and body dirty so that it will be rewritten when\n        saving the document \"\"\"\n        self._dirty_heading = True\n        self._dirty_body = True\n        if self._document:\n            self._document.set_dirty_document()\n\n    def set_dirty_heading(self):\n        u\"\"\" Mark the heading dirty so that it will be rewritten when saving the\n        document \"\"\"\n        self._dirty_heading = True\n        if self._document:\n            self._document.set_dirty_document()\n\n    @property\n    def previous_heading(self):\n        u\"\"\" Serialized access to the previous heading \"\"\"\n        return super(Heading, self).previous_item\n\n    @property\n    def next_heading(self):\n        u\"\"\" Serialized access to the next heading \"\"\"\n        return super(Heading, self).next_item\n\n    @property\n    def start(self):\n        u\"\"\" Access to the starting line of the heading \"\"\"\n        if self.document is None or not self.document.is_dirty:\n            return self._orig_start\n\n        meta_len = len(self.document.meta_information) if \\\n                self.document.meta_information else 0\n        return super(Heading, self).start + meta_len\n\n    @DomObj.level.setter\n    def level(self, value):\n        u\"\"\" Set the heading level and mark the heading and the document dirty \"\"\"\n        self._level = int(value)\n        self.set_dirty_heading()\n\n    @property\n    def todo(self):\n        u\"\"\" Todo state of current heading. When todo state is set\"\"\"\n        # extract todo state from heading\n        return self._todo\n\n    @todo.setter\n    def todo(self, value):\n        # update todo state\n        if type(value) not in (unicode, str, type(None)):\n            raise ValueError(u'Todo state must be a string or None.')\n        if value and not REGEX_TODO.match(value):\n            raise ValueError(u'Found non allowed character in todo state! %s' % value)\n        if not value:\n            self._todo = None\n        else:\n            v = value\n            if type(v) == str:\n                v = u_decode(v)\n            self._todo = v\n        self.set_dirty_heading()\n\n    @todo.deleter\n    def todo(self):\n        self.todo = None\n\n    @property\n    def active_date(self):\n        u\"\"\"\n        active date of the hearing.\n\n        active dates are used in the agenda view. they can be part of the\n        heading and/or the body.\n        \"\"\"\n        return self._active_date\n\n    @active_date.setter\n    def active_date(self, value):\n        self._active_date = value\n\n    @active_date.deleter\n    def active_date(self):\n        self._active_date = None\n\n    @DomObj.title.setter\n    def title(self, value):\n        u\"\"\" Set the title and mark the document and the heading dirty \"\"\"\n        # TODO these setter should be rewritten to also reuse code from DOM OBJ\n        if type(value) not in (unicode, str):\n            raise ValueError(u'Title must be a string.')\n        v = value\n        if type(v) == str:\n            v = u_decode(v)\n        self._title = v.strip()\n        self.set_dirty_heading()\n\n    @property\n    def tags(self):\n        u\"\"\" Tags of the current heading \"\"\"\n        return self._tags\n\n    @tags.setter\n    def tags(self, value):\n        v = value\n        if type(v) in (unicode, str):\n            v = list(unicode(v))\n        if type(v) not in (list, tuple) and not isinstance(v, UserList):\n            v = list(unicode(v))\n        v = flatten_list(v)\n        v_decoded = []\n        for i in v:\n            if type(i) not in (unicode, str):\n                raise ValueError(u'Found non string value in tags! %s' % unicode(i))\n            if u':' in i:\n                raise ValueError(u'Found non allowed character in tag! %s' % i)\n            i_tmp = i.strip().replace(' ', '_').replace('\\t', '_')\n            if type(i) == str:\n                i_tmp = u_decode(i)\n            v_decoded.append(i_tmp)\n\n        self._tags[:] = v_decoded\n\n    @tags.deleter\n    def tags(self):\n        self.tags = []\n\n    @property\n    def checkboxes(self):\n        u\"\"\" All checkboxes in current heading \"\"\"\n        return self._checkboxes\n\n    @checkboxes.setter\n    def checkboxes(self, value):\n        self._checkboxes[:] = value\n\n    @checkboxes.deleter\n    def checkboxes(self):\n        del self.checkboxes[:]\n\n\nclass HeadingList(DomObjList):\n    u\"\"\"\n    A Heading List just contains headings. It's used for documents to store top\n    level headings and for headings to store subheadings.\n\n    A Heading List must be linked to a Document or Heading!\n\n    See documentation of MultiPurposeList for more information.\n    \"\"\"\n    def __init__(self, initlist=None, obj=None):\n        \"\"\"\n        :initlist:    Initial data\n        :obj:        Link to a concrete Heading or Document object\n        \"\"\"\n        # it's not necessary to register a on_change hook because the heading\n        # list will itself take care of marking headings dirty or adding\n        # headings to the deleted headings list\n        DomObjList.__init__(self, initlist, obj)\n\n    @classmethod\n    def is_heading(cls, obj):\n        # TODO no need to make this or is_domobj a class methods\n        return HeadingList.is_domobj(obj)\n\n    def _get_document(self):\n        if self.__class__.is_heading(self._obj):\n            return self._obj._document\n        return self._obj\n\n    def _add_to_deleted_headings(self, item):\n        u\"\"\"\n        Serialize headings so that all subheadings are also marked for deletion\n        \"\"\"\n        if not self._get_document():\n            # HeadingList has not yet been associated\n            return\n\n        if type(item) in (list, tuple) or isinstance(item, UserList):\n            for i in flatten_list(item):\n                self._add_to_deleted_headings(i)\n        else:\n            self._get_document()._deleted_headings.append(\n                item.copy(including_children=False))\n            self._add_to_deleted_headings(item.children)\n            self._get_document().set_dirty_document()\n\n    def _associate_heading(\n        self, heading, previous_sibling, next_sibling,\n        children=False, taint=True):\n        \"\"\"\n        :heading:        The heading or list to associate with the current heading\n        :previous_sibling:    The previous sibling of the current heading. If\n                            heading is a list the first heading will be\n                            connected with the previous sibling and the last\n                            heading with the next sibling. The items in between\n                            will be linked with one another.\n        :next_sibling:    The next sibling of the current heading. If\n                            heading is a list the first heading will be\n                            connected with the previous sibling and the last\n                            heading with the next sibling. The items in between\n                            will be linked with one another.\n        :children:        Marks whether children are processed in the current\n                            iteration or not (should not be use, it's set\n                            automatically)\n        :taint:            If not True, the heading is not marked dirty at the end\n                            of the association process and its orig_start and\n                            orig_len values are not updated.\n        \"\"\"\n        # TODO this method should be externalized and moved to the Heading class\n        # TODO should this method work with slice?\n        if type(heading) in (list, tuple) or isinstance(heading, UserList):\n            prev = previous_sibling\n            current = None\n            for _next in flatten_list(heading):\n                if current:\n                    self._associate_heading(\n                        current, prev, _next,\n                        children=children, taint=taint)\n                    prev = current\n                current = _next\n            if current:\n                self._associate_heading(\n                    current, prev, next_sibling,\n                    children=children, taint=taint)\n        else:\n            if taint:\n                heading._orig_start = None\n                heading._orig_len = None\n            d = self._get_document()\n            if heading._document != d:\n                heading._document = d\n            if not children:\n                # connect heading with previous and next headings\n                heading._previous_sibling = previous_sibling\n                if previous_sibling:\n                    previous_sibling._next_sibling = heading\n                heading._next_sibling = next_sibling\n                if next_sibling:\n                    next_sibling._previous_sibling = heading\n\n                if d == self._obj:\n                    # self._obj is a Document\n                    heading._parent = None\n                elif heading._parent != self._obj:\n                    # self._obj is a Heading\n                    heading._parent = self._obj\n            if taint:\n                heading.set_dirty()\n\n            self._associate_heading(\n                heading.children, None, None,\n                children=True, taint=taint)\n\n    def __setitem__(self, i, item):\n        if isinstance(i, slice):\n            start, stop, step = i.indices(len(self))\n            items = item\n            if self.__class__.is_heading(items):\n                items = (items, )\n            items = flatten_list(items)\n            for head in items:\n                if not self.__class__.is_heading(head):\n                    raise ValueError(u'List contains items that are not a heading!')\n\n            self._add_to_deleted_headings(self[i])\n            self._associate_heading(\n                items,\n                self[start - 1] if start - 1 >= 0 else None,\n                self[stop] if stop < len(self) else None)\n            MultiPurposeList.__setitem__(self, i, items)\n        else:\n            if not self.__class__.is_heading(item):\n                raise ValueError(u'Item is not a heading!')\n            if item in self:\n                raise ValueError(u'Heading is already part of this list!')\n            self._add_to_deleted_headings(self[i])\n            self._associate_heading(\n                item,\n                self[i - 1] if i - 1 >= 0 else None,\n                self[i + 1] if i + 1 < len(self) else None)\n            MultiPurposeList.__setitem__(self, i, item)\n\n    def __delitem__(self, i, taint=True):\n        # TODO refactor this item, it works the same in dom_obj except taint?\n        if isinstance(i, slice):\n            items = self[i]\n            if items:\n                first = items[0]\n                last = items[-1]\n                if first.previous_sibling:\n                    first.previous_sibling._next_sibling = last.next_sibling\n                if last.next_sibling:\n                    last.next_sibling._previous_sibling = first.previous_sibling\n            if taint:\n                self._add_to_deleted_headings(items)\n            MultiPurposeList.__delitem__(self, i)\n        else:\n            item = self[i]\n            if item.previous_sibling:\n                item.previous_sibling._next_sibling = item.next_sibling\n            if item.next_sibling:\n                item.next_sibling._previous_sibling = item.previous_sibling\n\n            if taint:\n                self._add_to_deleted_headings(item)\n            MultiPurposeList.__delitem__(self, i)\n\n    def __iadd__(self, other):\n        o = other\n        if self.__class__.is_heading(o):\n            o = (o, )\n        for item in flatten_list(o):\n            if not self.__class__.is_heading(item):\n                raise ValueError(u'List contains items that are not a heading!')\n        self._associate_heading(o, self[-1] if len(self) > 0 else None, None)\n        return MultiPurposeList.__iadd__(self, o)\n\n    def append(self, item, taint=True):\n        if not self.__class__.is_heading(item):\n            raise ValueError(u'Item is not a heading!')\n        if item in self:\n            raise ValueError(u'Heading is already part of this list!')\n        self._associate_heading(\n            item, self[-1] if len(self) > 0 else None,\n            None, taint=taint)\n        MultiPurposeList.append(self, item)\n\n    def insert(self, i, item, taint=True):\n        self._associate_heading(\n            item,\n            self[i - 1] if i - 1 >= 0 and i - 1 < len(self) else None,\n            self[i] if i >= 0 and i < len(self) else None, taint=taint)\n        MultiPurposeList.insert(self, i, item)\n\n    def pop(self, i=-1):\n        item = self[i]\n        self._add_to_deleted_headings(item)\n        del self[i]\n        return item\n\n    def extend(self, other):\n        o = other\n        if self.__class__.is_heading(o):\n            o = (o, )\n        for item in o:\n            if not self.__class__.is_heading(item):\n                raise ValueError(u'List contains items that are not a heading!')\n        self._associate_heading(o, self[-1] if len(self) > 0 else None, None)\n        MultiPurposeList.extend(self, o)\n"
  },
  {
    "path": "ftplugin/orgmode/liborgmode/orgdate.py",
    "content": "# -*- coding: utf-8 -*-\nu\"\"\"\n    OrgDate\n    ~~~~~~~~~~~~~~~~~~\n\n    This module contains all date/time/timerange representations that exist in\n    orgmode.\n\n    There exist three different kinds:\n\n    * OrgDate: is similar to a date object in python and it looks like\n      '2011-09-07 Wed'.\n\n    * OrgDateTime: is similar to a datetime object in python and looks like\n      '2011-09-07 Wed 10:30'\n\n    * OrgTimeRange: indicates a range of time. It has a start and and end date:\n      * <2011-09-07 Wed>--<2011-09-08 Fri>\n      * <2011-09-07 Wed 10:00-13:00>\n\n    All OrgTime oblects can be active or inactive.\n\"\"\"\n\nimport datetime\nimport re\n\nfrom orgmode.py3compat.encode_compatibility import *\n\n# <2011-09-12 Mon>\n_DATE_REGEX = re.compile(r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w>\", re.UNICODE)\n# [2011-09-12 Mon]\n_DATE_PASSIVE_REGEX = re.compile(r\"\\[(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w\\]\", re.UNICODE)\n\n# <2011-09-12 Mon 10:20>\n_DATETIME_REGEX = re.compile(\n    r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w (\\d{1,2}):(\\d\\d)>\", re.UNICODE)\n# [2011-09-12 Mon 10:20]\n_DATETIME_PASSIVE_REGEX = re.compile(\n    r\"\\[(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w (\\d{1,2}):(\\d\\d)\\]\", re.UNICODE)\n\n# <2011-09-12 Mon>--<2011-09-13 Tue>\n_DATERANGE_REGEX = re.compile(\n    # <2011-09-12 Mon>--\n    r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w>--\"\n    # <2011-09-13 Tue>\n    r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w>\", re.UNICODE)\n# <2011-09-12 Mon 10:00>--<2011-09-12 Mon 11:00>\n_DATETIMERANGE_REGEX = re.compile(\n    # <2011-09-12 Mon 10:00>--\n    r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w (\\d\\d):(\\d\\d)>--\"\n    # <2011-09-12 Mon 11:00>\n    r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w (\\d\\d):(\\d\\d)>\", re.UNICODE)\n# <2011-09-12 Mon 10:00--12:00>\n_DATETIMERANGE_SAME_DAY_REGEX = re.compile(\n    r\"<(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) [A-Z]\\w\\w (\\d\\d):(\\d\\d)-(\\d\\d):(\\d\\d)>\", re.UNICODE)\n\n\ndef get_orgdate(data):\n    u\"\"\"\n    Parse the given data (can be a string or list). Return an OrgDate if data\n    contains a string representation of an OrgDate; otherwise return None.\n\n    data can be a string or a list containing strings.\n    \"\"\"\n    # TODO maybe it should be checked just for iterable? Does it affect here if\n    # in base __getitem__(slice(i,j)) doesn't return a list but userlist...\n    if isinstance(data, list):\n        return _findfirst(_text2orgdate, data)\n    else:\n        return _text2orgdate(data)\n    # if no dates found\n    return None\n\n\ndef _findfirst(f, seq):\n    u\"\"\"\n    Return first item in sequence seq where f(item) == True.\n\n    TODO: this is a general help function and it should be moved somewhere\n    else; preferably into the standard lib :)\n    \"\"\"\n    for found in (f(item) for item in seq if f(item)):\n        return found\n\n\ndef _text2orgdate(string):\n    u\"\"\"\n    Transform the given string into an OrgDate.\n    Return an OrgDate if data contains a string representation of an OrgDate;\n    otherwise return None.\n    \"\"\"\n    # handle active datetime with same day\n    result = _DATETIMERANGE_SAME_DAY_REGEX.search(string)\n    if result:\n        try:\n            (syear, smonth, sday, shour, smin, ehour, emin) = \\\n                [int(m) for m in result.groups()]\n            start = datetime.datetime(syear, smonth, sday, shour, smin)\n            end = datetime.datetime(syear, smonth, sday, ehour, emin)\n            return OrgTimeRange(True, start, end)\n        except BaseException:\n            return None\n\n    # handle active datetime\n    result = _DATETIMERANGE_REGEX.search(string)\n    if result:\n        try:\n            tmp = [int(m) for m in result.groups()]\n            (syear, smonth, sday, shour, smin, eyear, emonth, eday, ehour, emin) = tmp\n            start = datetime.datetime(syear, smonth, sday, shour, smin)\n            end = datetime.datetime(eyear, emonth, eday, ehour, emin)\n            return OrgTimeRange(True, start, end)\n        except BaseException:\n            return None\n\n    # handle active datetime\n    result = _DATERANGE_REGEX.search(string)\n    if result:\n        try:\n            tmp = [int(m) for m in result.groups()]\n            syear, smonth, sday, eyear, emonth, ehour = tmp\n            start = datetime.date(syear, smonth, sday)\n            end = datetime.date(eyear, emonth, ehour)\n            return OrgTimeRange(True, start, end)\n        except BaseException:\n            return None\n\n    # handle active datetime\n    result = _DATETIME_REGEX.search(string)\n    if result:\n        try:\n            year, month, day, hour, minutes = [int(m) for m in result.groups()]\n            return OrgDateTime(True, year, month, day, hour, minutes)\n        except BaseException:\n            return None\n\n    # handle passive datetime\n    result = _DATETIME_PASSIVE_REGEX.search(string)\n    if result:\n        try:\n            year, month, day, hour, minutes = [int(m) for m in result.groups()]\n            return OrgDateTime(False, year, month, day, hour, minutes)\n        except BaseException:\n            return None\n\n    # handle passive dates\n    result = _DATE_PASSIVE_REGEX.search(string)\n    if result:\n        try:\n            year, month, day = [int(m) for m in result.groups()]\n            return OrgDate(False, year, month, day)\n        except BaseException:\n            return None\n\n    # handle active dates\n    result = _DATE_REGEX.search(string)\n    if result:\n        try:\n            year, month, day = [int(m) for m in result.groups()]\n            return OrgDate(True, year, month, day)\n        except BaseException:\n            return None\n\n\nclass OrgDate(datetime.date):\n    u\"\"\"\n    OrgDate represents a normal date like '2011-08-29 Mon'.\n\n    OrgDates can be active or inactive.\n\n    NOTE: date is immutable. That's why there needs to be __new__().\n    See: http://docs.python.org/reference/datamodel.html#object.__new__\n    \"\"\"\n    def __init__(self, active, year, month, day):\n        self.active = active\n        pass\n\n    def __new__(cls, active, year, month, day):\n        return datetime.date.__new__(cls, year, month, day)\n\n    def __unicode__(self):\n        u\"\"\"\n        Return a string representation.\n        \"\"\"\n        if self.active:\n            return self.strftime(u'<%Y-%m-%d %a>')\n        else:\n            return self.strftime(u'[%Y-%m-%d %a]')\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def timestr(self):\n        return '--:--'\n\n    def date(self):\n        return self\n\n    def strftime(self, fmt):\n        return u_decode(datetime.date.strftime(self, u_encode(fmt)))\n\n\nclass OrgDateTime(datetime.datetime):\n    u\"\"\"\n    OrgDateTime represents a normal date like '2011-08-29 Mon'.\n\n    OrgDateTime can be active or inactive.\n\n    NOTE: date is immutable. That's why there needs to be __new__().\n    See: http://docs.python.org/reference/datamodel.html#object.__new__\n    \"\"\"\n\n    def __init__(self, active, year, month, day, hour, mins):\n        self.active = active\n\n    def __new__(cls, active, year, month, day, hour, minute):\n        return datetime.datetime.__new__(cls, year, month, day, hour, minute)\n\n    def __unicode__(self):\n        u\"\"\"\n        Return a string representation.\n        \"\"\"\n        if self.active:\n            return self.strftime(u'<%Y-%m-%d %a %H:%M>')\n        else:\n            return self.strftime(u'[%Y-%m-%d %a %H:%M]')\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def timestr(self):\n        return self.strftime('%H:%M')\n\n    def date(self):\n        return OrgDate(self.active, self.year, self.month, self.day)\n\n    def strftime(self, fmt):\n        return u_decode(datetime.datetime.strftime(self, u_encode(fmt)))\n\n\nclass OrgTimeRange(object):\n    u\"\"\"\n    OrgTimeRange objects have a start and an end. Start and ent can be date\n    or datetime. Start and end have to be the same type.\n\n    OrgTimeRange objects look like this:\n    * <2011-09-07 Wed>--<2011-09-08 Fri>\n    * <2011-09-07 Wed 20:00>--<2011-09-08 Fri 10:00>\n    * <2011-09-07 Wed 10:00-13:00>\n    \"\"\"\n\n    def __init__(self, active, start, end):\n        u\"\"\"\n        stat and end must be datetime.date or datetime.datetime (both of the\n        same type).\n        \"\"\"\n        super(OrgTimeRange, self).__init__()\n        self.start = start\n        self.end = end\n        self.active = active\n\n    def __unicode__(self):\n        u\"\"\"\n        Return a string representation.\n        \"\"\"\n        # active\n        if self.active:\n            # datetime\n            if isinstance(self.start, datetime.datetime):\n                # if start and end are on same the day\n                if self.start.year == self.end.year and\\\n                    self.start.month == self.end.month and\\\n                    self.start.day == self.end.day:\n                    return u\"<%s-%s>\" % (\n                        self.start.strftime(u'%Y-%m-%d %a %H:%M'),\n                        self.end.strftime(u'%H:%M'))\n                else:\n                    return u\"<%s>--<%s>\" % (\n                        self.start.strftime(u'%Y-%m-%d %a %H:%M'),\n                        self.end.strftime(u'%Y-%m-%d %a %H:%M'))\n            # date\n            if isinstance(self.start, datetime.date):\n                return u\"<%s>--<%s>\" % (\n                    self.start.strftime(u'%Y-%m-%d %a'),\n                    self.end.strftime(u'%Y-%m-%d %a'))\n        # inactive\n        else:\n            if isinstance(self.start, datetime.datetime):\n                # if start and end are on same the day\n                if self.start.year == self.end.year and\\\n                    self.start.month == self.end.month and\\\n                    self.start.day == self.end.day:\n                    return u\"[%s-%s]\" % (\n                        self.start.strftime(u'%Y-%m-%d %a %H:%M'),\n                        self.end.strftime(u'%H:%M'))\n                else:\n                    return u\"[%s]--[%s]\" % (\n                        self.start.strftime(u'%Y-%m-%d %a %H:%M'),\n                        self.end.strftime(u'%Y-%m-%d %a %H:%M'))\n            if isinstance(self.start, datetime.date):\n                return u\"[%s]--[%s]\" % (\n                    self.start.strftime(u'%Y-%m-%d %a'),\n                    self.end.strftime(u'%Y-%m-%d %a'))\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def date(self):\n        return OrgDate(self.active, self.start.year, self.start.month, self.start.day)\n"
  },
  {
    "path": "ftplugin/orgmode/menu.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode.keybinding import Command, Plug, Keybinding\nfrom orgmode.keybinding import MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ndef register_menu(f):\n    def r(*args, **kwargs):\n        p = f(*args, **kwargs)\n        def create(entry):\n            if isinstance(entry, Submenu) or isinstance(entry, Separator) \\\n                    or isinstance(entry, ActionEntry):\n                entry.create()\n\n        if hasattr(p, u'menu'):\n            if isinstance(p.menu, list) or isinstance(p.menu, tuple):\n                for e in p.menu:\n                    create(e)\n            else:\n                create(p.menu)\n        return p\n    return r\n\n\ndef add_cmd_mapping_menu(plugin, name, function, key_mapping, menu_desrc):\n    u\"\"\"A helper function to create a vim command and keybinding and add these\n    to the menu for a given plugin.\n\n    :plugin: the plugin to operate on.\n    :name: the name of the vim command (and the name of the Plug)\n    :function: the actual python function which is called when executing the\n                vim command.\n    :key_mapping: the keymapping to execute the command.\n    :menu_desrc: the text which appears in the menu.\n    \"\"\"\n    cmd = Command(name, function)\n    keybinding = Keybinding(key_mapping, Plug(name, cmd))\n\n    plugin.commands.append(cmd)\n    plugin.keybindings.append(keybinding)\n    plugin.menu + ActionEntry(menu_desrc, keybinding)\n\n\nclass Submenu(object):\n    u\"\"\" Submenu entry \"\"\"\n\n    def __init__(self, name, parent=None):\n        object.__init__(self)\n        self.name = name\n        self.parent = parent\n        self._children = []\n\n    def __add__(self, entry):\n        if entry not in self._children:\n            self._children.append(entry)\n            entry.parent = self\n            return entry\n\n    def __sub__(self, entry):\n        if entry in self._children:\n            idx = self._children.index(entry)\n            del self._children[idx]\n\n    @property\n    def children(self):\n        return self._children[:]\n\n    def get_menu(self):\n        n = self.name.replace(u' ', u'\\\\ ')\n        if self.parent:\n            return u'%s.%s' % (self.parent.get_menu(), n)\n        return n\n\n    def create(self):\n        for c in self.children:\n            c.create()\n\n    def __str__(self):\n        res = self.name\n        for c in self.children:\n            res += str(c)\n        return res\n\nclass Separator(object):\n    u\"\"\" Menu entry for a Separator \"\"\"\n\n    def __init__(self, parent=None):\n        object.__init__(self)\n        self.parent = parent\n\n    def __unicode__(self):\n        return u'-----'\n\n    def __str__(self):\n        return u_encode(self.__unicode__())\n\n    def create(self):\n        if self.parent:\n            menu = self.parent.get_menu()\n            vim.command(u_encode(u'menu %s.-%s- :' % (menu, id(self))))\n\nclass ActionEntry(object):\n    u\"\"\" ActionEntry entry \"\"\"\n\n    def __init__(self, lname, action, rname=None, mode=MODE_NORMAL, parent=None):\n        u\"\"\"\n        :lname: menu title on the left hand side of the menu entry\n        :action: could be a vim command sequence or an actual Keybinding\n        :rname: menu title that appears on the right hand side of the menu\n                entry. If action is a Keybinding this value ignored and is\n                taken from the Keybinding\n        :mode: defines when the menu entry/action is executable\n        :parent: the parent instance of this object. The only valid parent is Submenu\n        \"\"\"\n        object.__init__(self)\n        self._lname = lname\n        self._action = action\n        self._rname = rname\n        if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT):\n            raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT')\n        self._mode = mode\n        self.parent = parent\n\n    def __str__(self):\n        return u'%s\\t%s' % (self.lname, self.rname)\n\n    @property\n    def lname(self):\n        return self._lname.replace(u' ', u'\\\\ ')\n\n    @property\n    def action(self):\n        if isinstance(self._action, Keybinding):\n            return self._action.action\n        return self._action\n\n    @property\n    def rname(self):\n        if isinstance(self._action, Keybinding):\n            return self._action.key.replace(u'<Tab>', u'Tab')\n        return self._rname\n\n    @property\n    def mode(self):\n        if isinstance(self._action, Keybinding):\n            return self._action.mode\n        return self._mode\n\n    def create(self):\n        menucmd = u':%smenu ' % self.mode\n        menu = u''\n        cmd = u''\n\n        if self.parent:\n            menu = self.parent.get_menu()\n        menu += u'.%s' % self.lname\n\n        if self.rname:\n            cmd = u'%s %s<Tab>%s %s' % (menucmd, menu, self.rname, self.action)\n        else:\n            cmd = u'%s %s %s' % (menucmd, menu, self.action)\n\n        vim.command(u_encode(cmd))\n\n        # keybindings should be stored in the plugin.keybindings property and be registered by the appropriate keybinding registrar\n        #if isinstance(self._action, Keybinding):\n        #    self._action.create()\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Agenda.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom datetime import date\nimport os\nimport glob\n\nimport vim\n\nfrom orgmode._vim import ORGMODE, get_bufnumber, get_bufname, echoe\nfrom orgmode import settings\nfrom orgmode.keybinding import Keybinding, Plug, Command\nfrom orgmode.menu import Submenu, ActionEntry, add_cmd_mapping_menu\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass Agenda(object):\n    u\"\"\"\n    The Agenda Plugin uses liborgmode.agenda to display the agenda views.\n\n    The main task is to format the agenda from liborgmode.agenda.\n    Also all the mappings: jump from agenda to todo, etc are realized here.\n    \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Agenda')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    @classmethod\n    def _switch_to(cls, bufname, vim_commands=None):\n        u\"\"\"\n        Swicht to the buffer with bufname.\n\n        A list of vim.commands (if given) gets executed as well.\n\n        TODO: this should be extracted and imporved to create an easy to use\n        way to create buffers/jump to buffers. Otherwise there are going to be\n        quite a few ways to open buffers in vimorgmode.\n        \"\"\"\n        cmds = [\n            u'botright split org:%s' % bufname,\n            u'setlocal buftype=nofile',\n            u'setlocal modifiable',\n            u'setlocal nonumber',\n            # call opendoc() on enter the original todo item\n            u'nnoremap <silent> <buffer> <CR> :exec \"%s ORGMODE.plugins[u\\'Agenda\\'].opendoc()\"<CR>' % VIM_PY_CALL,\n            u'nnoremap <silent> <buffer> <TAB> :exec \"%s ORGMODE.plugins[u\\'Agenda\\'].opendoc(switch=True)\"<CR>' % VIM_PY_CALL,\n            u'nnoremap <silent> <buffer> <S-CR> :exec \"%s ORGMODE.plugins[u\\'Agenda\\'].opendoc(split=True)\"<CR>' % VIM_PY_CALL,\n            # statusline\n            u'setlocal statusline=Org\\\\ %s' % bufname]\n        if vim_commands:\n            cmds.extend(vim_commands)\n        for cmd in cmds:\n            vim.command(u_encode(cmd))\n\n    @classmethod\n    def _get_agendadocuments(self):\n        u\"\"\"\n        Return the org documents of the agenda files; return None if no\n        agenda documents are defined.\n\n        TODO: maybe turn this into an decorator?\n        \"\"\"\n        # load org files of agenda\n        agenda_files = settings.get(u'org_agenda_files', u',')\n        if not agenda_files or agenda_files == ',':\n            echoe(\n                u\"No org_agenda_files defined. Use :let \"\n                u\"g:org_agenda_files=['~/org/index.org'] to add \"\n                u\"files to the agenda view.\")\n            return\n        return self._load_agendafiles(agenda_files)\n\n    @classmethod\n    def _load_agendafiles(self, agenda_files):\n        # glob for files in agenda_files\n        resolved_files = []\n        for f in agenda_files:\n            f = glob.glob(os.path.join(\n                os.path.expanduser(os.path.dirname(f)),\n                os.path.basename(f)))\n            resolved_files.extend(f)\n\n        agenda_files = [os.path.realpath(f) for f in resolved_files]\n\n        # load the agenda files into buffers\n        for agenda_file in agenda_files:\n            vim.command(u_encode(u'badd %s' % agenda_file.replace(\" \", \"\\\\ \")))\n\n        # determine the buffer nr of the agenda files\n        agenda_nums = [get_bufnumber(fn) for fn in agenda_files]\n\n        # collect all documents of the agenda files and create the agenda\n        return [ORGMODE.get_document(i) for i in agenda_nums if i is not None]\n\n    @classmethod\n    def opendoc(cls, split=False, switch=False):\n        u\"\"\"\n        If you are in the agenda view jump to the document the item in the\n        current line belongs to. cls.line2doc is used for that.\n\n        :split: if True, open the document in a new split window.\n        :switch: if True, switch to another window and open the the document\n            there.\n        \"\"\"\n        row, _ = vim.current.window.cursor\n        try:\n            bufname, bufnr, destrow = cls.line2doc[row]\n        except:\n            return\n\n        # reload source file if it is not loaded\n        if get_bufname(bufnr) is None:\n            vim.command(u_encode(u'badd %s' % bufname))\n            bufnr = get_bufnumber(bufname)\n            tmp = cls.line2doc[row]\n            cls.line2doc[bufnr] = tmp\n            # delete old endry\n            del cls.line2doc[row]\n\n        if split:\n            vim.command(u_encode(u\"sbuffer %s\" % bufnr))\n        elif switch:\n            vim.command(u_encode(u\"wincmd w\"))\n            vim.command(u_encode(u\"buffer %d\" % bufnr))\n        else:\n            vim.command(u_encode(u\"buffer %s\" % bufnr))\n        vim.command(u_encode(u\"normal! %dgg <CR>\" % (destrow + 1)))\n\n    @classmethod\n    def list_next_week(cls):\n        agenda_documents = cls._get_agendadocuments()\n        if not agenda_documents:\n            return\n        cls.list_next_week_for(agenda_documents)\n\n    @classmethod\n    def list_next_week_for_buffer(cls):\n        agenda_documents = vim.current.buffer.name\n        loaded_agendafiles = cls._load_agendafiles([agenda_documents])\n        cls.list_next_week_for(loaded_agendafiles)\n\n\n    @classmethod\n    def list_next_week_for(cls, agenda_documents):\n        raw_agenda = ORGMODE.agenda_manager.get_next_week_and_active_todo(\n            agenda_documents)\n\n        # if raw_agenda is empty, return directly\n        if not raw_agenda:\n            vim.command('echom \"All caught-up. No agenda or active todo next week.\"')\n            return\n\n        # create buffer at bottom\n        cmd = [u'setlocal filetype=orgagenda', ]\n        cls._switch_to(u'AGENDA', cmd)\n\n        # line2doc is a dic with the mapping:\n        #     line in agenda buffer --> source document\n        # It's easy to jump to the right document this way\n        cls.line2doc = {}\n        # format text for agenda\n        last_date = None\n        final_agenda = [u'Week Agenda:']\n        for i, h in enumerate(raw_agenda):\n            # insert date information for every new date (not datetime)\n            active_date_no_time = h.active_date.date()\n            if active_date_no_time != last_date:\n                today = date.today()\n                # insert additional \"TODAY\" string\n                if active_date_no_time == today:\n                    section = unicode(active_date_no_time) + u\" TODAY\"\n                    today_row = len(final_agenda) + 1\n                else:\n                    section = unicode(active_date_no_time)\n                final_agenda.append(section)\n\n                # update last_date\n                last_date = active_date_no_time\n\n            p = h\n            tags = []\n            while p is not None:\n                tags += p.tags\n                p = p.parent\n\n            bufname = os.path.basename(vim.buffers[h.document.bufnr].name)\n            bufname = bufname[:-4] if bufname.endswith(u'.org') else bufname\n            formatted = u\"  %(bufname)s (%(bufnr)d)  %(todo)s  %(timestr)s  %(title)s %(tags)s\" % {\n                'bufname': bufname,\n                'bufnr': h.document.bufnr,\n                'todo': h.todo,\n                'timestr': h.active_date.timestr(),\n                'title': h.title,\n                'tags': ':' + ':'.join(tags) + ':' if tags else ''\n            }\n            final_agenda.append(formatted)\n            cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)\n\n        # show agenda\n        vim.current.buffer[:] = [u_encode(i) for i in final_agenda]\n        vim.command(u_encode(u'setlocal nomodifiable  conceallevel=2 concealcursor=nc'))\n        # try to jump to the position of today\n        try:\n            vim.command(u_encode(u'normal! %sgg<CR>' % today_row))\n        except:\n            pass\n\n    @classmethod\n    def list_all_todos(cls, current_buffer=False):\n        u\"\"\" List all todos in one buffer.\n\n        Args:\n            current_buffer (bool):\n                False: all agenda files\n                True: current org_file\n        \"\"\"\n        if current_buffer:\n            agenda_documents = vim.current.buffer.name\n            loaded_agendafiles = cls._load_agendafiles([agenda_documents])\n        else:\n            loaded_agendafiles = cls._get_agendadocuments()\n        if not loaded_agendafiles:\n            return\n        raw_agenda = ORGMODE.agenda_manager.get_todo(loaded_agendafiles)\n\n        cls.line2doc = {}\n        # create buffer at bottom\n        cmd = [u'setlocal filetype=orgagenda']\n        cls._switch_to(u'AGENDA', cmd)\n\n        # format text of agenda\n        final_agenda = []\n        for i, h in enumerate(raw_agenda):\n            tmp = u\"%s %s\" % (h.todo, h.title)\n            final_agenda.append(tmp)\n            cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)\n\n        # show agenda\n        vim.current.buffer[:] = [u_encode(i) for i in final_agenda]\n        vim.command(u_encode(u'setlocal nomodifiable  conceallevel=2 concealcursor=nc'))\n\n    @classmethod\n    def list_timeline(cls):\n        \"\"\"\n        List a timeline of the current buffer to get an overview of the\n        current file.\n        \"\"\"\n        raw_agenda = ORGMODE.agenda_manager.get_timestamped_items(\n            [ORGMODE.get_document()])\n\n        # create buffer at bottom\n        cmd = [u'setlocal filetype=orgagenda']\n        cls._switch_to(u'AGENDA', cmd)\n\n        cls.line2doc = {}\n        # format text of agenda\n        final_agenda = []\n        for i, h in enumerate(raw_agenda):\n            tmp = fmt.format('{} {}', h.todo, h.title).lstrip().rstrip()\n            final_agenda.append(tmp)\n            cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)\n\n        # show agenda\n        vim.current.buffer[:] = [u_encode(i) for i in final_agenda]\n        vim.command(u_encode(u'setlocal nomodifiable conceallevel=2 concealcursor=nc'))\n\n    def register(self):\n        u\"\"\"\n        Registration of the plugin.\n\n        Key bindings and other initialization should be done here.\n        \"\"\"\n        add_cmd_mapping_menu(\n            self,\n            name=u\"OrgAgendaTodo\",\n            function=u'%s ORGMODE.plugins[u\"Agenda\"].list_all_todos()' % VIM_PY_CALL,\n            key_mapping=u'<localleader>cat',\n            menu_desrc=u'Agenda for all TODOs'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u\"OrgBufferAgendaTodo\",\n            function=u'%s ORGMODE.plugins[u\"Agenda\"].list_all_todos(current_buffer=True)' % VIM_PY_CALL,\n            key_mapping=u'<localleader>caT',\n            menu_desrc=u'Agenda for all TODOs based on current buffer'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u\"OrgAgendaWeek\",\n            function=u'%s ORGMODE.plugins[u\"Agenda\"].list_next_week()' % VIM_PY_CALL,\n            key_mapping=u'<localleader>caa',\n            menu_desrc=u'Agenda for the week'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u\"OrgBufferAgendaWeek\",\n            function=u'%s ORGMODE.plugins[u\"Agenda\"].list_next_week_for_buffer()' % VIM_PY_CALL,\n            key_mapping=u'<localleader>caA',\n            menu_desrc=u'Agenda for the week based on current buffer'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgAgendaTimeline',\n            function=u'%s ORGMODE.plugins[u\"Agenda\"].list_timeline()' % VIM_PY_CALL,\n            key_mapping=u'<localleader>caL',\n            menu_desrc=u'Timeline for this buffer'\n        )\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Date.py",
    "content": "# -*- coding: utf-8 -*-\nimport re\nfrom datetime import timedelta, date, datetime\n\nimport operator\n\nimport vim\n\nfrom orgmode._vim import ORGMODE, echom, insert_at_cursor, get_user_input\nfrom orgmode import settings\nfrom orgmode.keybinding import Keybinding, Plug\nfrom orgmode.menu import Submenu, ActionEntry, add_cmd_mapping_menu\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass Date(object):\n    u\"\"\"\n    Handles all date and timestamp related tasks.\n\n    TODO: extend functionality (calendar, repetitions, ranges). See\n            http://orgmode.org/guide/Dates-and-Times.html#Dates-and-Times\n    \"\"\"\n\n    date_regex = r\"\\d\\d\\d\\d-\\d\\d-\\d\\d\"\n    datetime_regex = r\"[A-Z]\\w\\w \\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d>\"\n\n    month_mapping = {\n        u'jan': 1, u'feb': 2, u'mar': 3, u'apr': 4, u'may': 5,\n        u'jun': 6, u'jul': 7, u'aug': 8, u'sep': 9, u'oct': 10, u'nov': 11,\n        u'dec': 12}\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Dates and Scheduling')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n        # set speeddating format that is compatible with orgmode\n        try:\n            if int(vim.eval(u_encode(u'exists(\":SpeedDatingFormat\")'))) == 2:\n                vim.command(u_encode(u':1SpeedDatingFormat %Y-%m-%d %a'))\n                vim.command(u_encode(u':1SpeedDatingFormat %Y-%m-%d %a %H:%M'))\n            else:\n                echom(u'Speeddating plugin not installed. Please install it.')\n        except:\n            echom(u'Speeddating plugin not installed. Please install it.')\n\n    @classmethod\n    def _modify_time(cls, startdate, modifier):\n        u\"\"\"Modify the given startdate according to modifier. Return the new\n        date or datetime.\n\n        See http://orgmode.org/manual/The-date_002ftime-prompt.html\n        \"\"\"\n        if modifier is None or modifier == '' or modifier == '.':\n            return startdate\n\n        # rm crap from modifier\n        modifier = modifier.strip()\n\n        ops = {'-': operator.sub, '+': operator.add}\n\n        # check real date\n        date_regex = r\"(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)\"\n        match = re.search(date_regex, modifier)\n        if match:\n            year, month, day = match.groups()\n            newdate = date(int(year), int(month), int(day))\n\n        # check abbreviated date, separated with '-'\n        date_regex = u\"(\\\\d{1,2})-(\\\\d+)-(\\\\d+)\"\n        match = re.search(date_regex, modifier)\n        if match:\n            year, month, day = match.groups()\n            newdate = date(2000 + int(year), int(month), int(day))\n\n        # check abbreviated date, separated with '/'\n        # month/day\n        date_regex = u\"(\\\\d{1,2})/(\\\\d{1,2})\"\n        match = re.search(date_regex, modifier)\n        if match:\n            month, day = match.groups()\n            newdate = date(startdate.year, int(month), int(day))\n            # date should be always in the future\n            if newdate < startdate:\n                newdate = date(startdate.year + 1, int(month), int(day))\n\n        # check full date, separated with 'space'\n        # month day year\n        # 'sep 12 9' --> 2009 9 12\n        date_regex = u\"(\\\\w\\\\w\\\\w) (\\\\d{1,2}) (\\\\d{1,2})\"\n        match = re.search(date_regex, modifier)\n        if match:\n            gr = match.groups()\n            day = int(gr[1])\n            month = int(cls.month_mapping[gr[0]])\n            year = 2000 + int(gr[2])\n            newdate = date(year, int(month), int(day))\n\n        # check days as integers\n        date_regex = u\"^(\\\\d{1,2})$\"\n        match = re.search(date_regex, modifier)\n        if match:\n            newday, = match.groups()\n            newday = int(newday)\n            if newday > startdate.day:\n                newdate = date(startdate.year, startdate.month, newday)\n            else:\n                # TODO: DIRTY, fix this\n                #       this does NOT cover all edge cases\n                newdate = startdate + timedelta(days=28)\n                newdate = date(newdate.year, newdate.month, newday)\n\n        # check for full days: Mon, Tue, Wed, Thu, Fri, Sat, Sun\n        modifier_lc = modifier.lower()\n        match = re.search(u'mon|tue|wed|thu|fri|sat|sun', modifier_lc)\n        if match:\n            weekday_mapping = {\n                u'mon': 0, u'tue': 1, u'wed': 2, u'thu': 3,\n                u'fri': 4, u'sat': 5, u'sun': 6}\n            diff = (weekday_mapping[modifier_lc] - startdate.weekday()) % 7\n            # use next weeks weekday if current weekday is the same as modifier\n            if diff == 0:\n                diff = 7\n            newdate = startdate + timedelta(days=diff)\n\n        # check for days modifier with appended d\n        match = re.search(u'^(\\\\+|-)(\\\\d*)d', modifier)\n        if match:\n            op, days = match.groups()\n            newdate = ops[op](startdate, timedelta(days=int(days)))\n\n        # check for days modifier without appended d\n        match = re.search(u'^(\\\\+|-)(\\\\d*) |^(\\\\+|-)(\\\\d*)$', modifier)\n        if match:\n            groups = match.groups()\n            try:\n                op = groups[0]\n                days = int(groups[1])\n            except:\n                op = groups[2]\n                days = int(groups[3])\n            newdate = ops[op](startdate, timedelta(days=days))\n\n        # check for week modifier\n        match = re.search(u'^(\\\\+|-)(\\\\d+)w', modifier)\n        if match:\n            op, weeks = match.groups()\n            newdate = ops[op](startdate, timedelta(weeks=int(weeks)))\n\n        # check for month modifier\n        match = re.search(u'^(\\\\+|-)(\\\\d+)m', modifier)\n        if match:\n            op, months = match.groups()\n            newdate = date(startdate.year, ops[op](startdate.month, int(months)),\n                    startdate.day)\n\n        # check for year modifier\n        match = re.search(u'^(\\\\+|-)(\\\\d*)y', modifier)\n        if match:\n            op, years = match.groups()\n            newdate = date(ops[op](startdate.year, int(years)), startdate.month,\n                    startdate.day)\n\n        # check for month day\n        match = re.search(\n            u'(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (\\\\d{1,2})',\n            modifier.lower())\n        if match:\n            month = cls.month_mapping[match.groups()[0]]\n            day = int(match.groups()[1])\n            newdate = date(startdate.year, int(month), int(day))\n            # date should be always in the future\n            if newdate < startdate:\n                newdate = date(startdate.year + 1, int(month), int(day))\n\n        # check abbreviated date, separated with '/'\n        # month/day/year\n        date_regex = u\"(\\\\d{1,2})/(\\\\d+)/(\\\\d+)\"\n        match = re.search(date_regex, modifier)\n        if match:\n            month, day, year = match.groups()\n            newdate = date(2000 + int(year), int(month), int(day))\n\n        # check for month day year\n        # sep 12 2011\n        match = re.search(\n            u'(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (\\\\d{1,2}) (\\\\d{1,4})',\n            modifier.lower())\n        if match:\n            month = int(cls.month_mapping[match.groups()[0]])\n            day = int(match.groups()[1])\n            if len(match.groups()[2]) < 4:\n                year = 2000 + int(match.groups()[2])\n            else:\n                year = int(match.groups()[2])\n            newdate = date(year, month, day)\n\n        # check for time: HH:MM\n        # '12:45' --> datetime(2006, 06, 13, 12, 45))\n        match = re.search(u'(\\\\d{1,2}):(\\\\d\\\\d)$', modifier)\n        if match:\n            try:\n                startdate = newdate\n            except:\n                pass\n            return datetime(\n                startdate.year, startdate.month, startdate.day,\n                int(match.groups()[0]), int(match.groups()[1]))\n\n        try:\n            return newdate\n        except:\n            return startdate\n\n    @classmethod\n    def insert_timestamp(cls, active=True):\n        u\"\"\"\n        Insert a timestamp at the cursor position.\n\n        TODO: show fancy calendar to pick the date from.\n        TODO: add all modifier of orgmode.\n        \"\"\"\n        today = date.today()\n        msg = u''.join([\n            u'Inserting ',\n            unicode(u_decode(today.strftime(u'%Y-%m-%d %a'))),\n            u' | Modify date'])\n        modifier = get_user_input(msg)\n\n        # abort if the user canceled the input prompt\n        if modifier is None:\n            return\n\n        newdate = cls._modify_time(today, modifier)\n\n        # format\n        if isinstance(newdate, datetime):\n            newdate = newdate.strftime(\n                u_decode(u_encode(u'%Y-%m-%d %a %H:%M')))\n        else:\n            newdate = newdate.strftime(\n                u_decode(u_encode(u'%Y-%m-%d %a')))\n        timestamp = u'<%s>' % newdate if active else u'[%s]' % newdate\n\n        insert_at_cursor(timestamp)\n\n    @classmethod\n    def insert_timestamp_with_calendar(cls, active=True):\n        u\"\"\"\n        Insert a timestamp at the cursor position.\n        Show fancy calendar to pick the date from.\n\n        TODO: add all modifier of orgmode.\n        \"\"\"\n        if int(vim.eval(u_encode(u'exists(\":CalendarH\")'))) != 2:\n            vim.command(\"echo 'Please install plugin Calendar to enable this function'\")\n            return\n        vim.command(\"CalendarH\")\n        # backup calendar_action\n        calendar_action = vim.eval(\"g:calendar_action\")\n        vim.command(\"let g:org_calendar_action_backup = '\" + calendar_action + \"'\")\n        vim.command(\"let g:calendar_action = 'CalendarAction'\")\n\n        timestamp_template = u'<%s>' if active else u'[%s]'\n        # timestamp template\n        vim.command(\"let g:org_timestamp_template = '\" + timestamp_template + \"'\")\n\n    def register(self):\n        u\"\"\"\n        Registration of the plugin.\n\n        Key bindings and other initialization should be done here.\n        \"\"\"\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgDateInsertTimestampActiveCmdLine',\n            key_mapping=u'<localleader>sa',\n            function=u'%s ORGMODE.plugins[u\"Date\"].insert_timestamp()' % VIM_PY_CALL,\n            menu_desrc=u'Timest&amp'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgDateInsertTimestampInactiveCmdLine',\n            key_mapping='<localleader>si',\n            function=u'%s ORGMODE.plugins[u\"Date\"].insert_timestamp(False)' % VIM_PY_CALL,\n            menu_desrc=u'Timestamp (&inactive)'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgDateInsertTimestampActiveWithCalendar',\n            key_mapping=u'<localleader>pa',\n            function=u'%s ORGMODE.plugins[u\"Date\"].insert_timestamp_with_calendar()' % VIM_PY_CALL,\n            menu_desrc=u'Timestamp with Calendar'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgDateInsertTimestampInactiveWithCalendar',\n            key_mapping=u'<localleader>pi',\n            function=u'%s ORGMODE.plugins[u\"Date\"].insert_timestamp_with_calendar(False)' % VIM_PY_CALL,\n            menu_desrc=u'Timestamp with Calendar(inactive)'\n        )\n\n        submenu = self.menu + Submenu(u'Change &Date')\n        submenu + ActionEntry(u'Day &Earlier', u'<C-x>', u'<C-x>')\n        submenu + ActionEntry(u'Day &Later', u'<C-a>', u'<C-a>')\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/EditCheckbox.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\nfrom orgmode._vim import echo, echom, echoe, ORGMODE, apply_count, repeat, insert_at_cursor, indent_orgmode\nfrom orgmode import settings\nfrom orgmode.menu import Submenu, Separator, ActionEntry, add_cmd_mapping_menu\nfrom orgmode.keybinding import Keybinding, Plug, Command\nfrom orgmode.liborgmode.checkboxes import Checkbox\nfrom orgmode.liborgmode.dom_obj import OrderListType\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\nclass EditCheckbox(object):\n    u\"\"\"\n    Checkbox plugin.\n    \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Edit Checkbox')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    @classmethod\n    def new_checkbox(cls, below=None, plain=None):\n        '''\n        if below is:\n            True -> create new list below current line\n            False/None -> create new list above current line\n        if plain is:\n            True -> create a plainlist item\n            False/None -> create an empty checkbox\n        '''\n        d = ORGMODE.get_document()\n        h = d.current_heading()\n        if h is None:\n            return\n        # init checkboxes for current heading\n        h.init_checkboxes()\n        c = h.current_checkbox()\n\n        nc = Checkbox()\n        nc._heading = h\n\n        # default checkbox level\n        level = h.level + 1\n        start = vim.current.window.cursor[0] - 1\n        # if no checkbox is found, insert at current line with indent level=1\n        if c is None:\n            h.checkboxes.append(nc)\n        else:\n            l = c.get_parent_list()\n            idx = c.get_index_in_parent_list()\n            if l is not None and idx is not None:\n                l.insert(idx + (1 if below else 0), nc)\n                # workaround for broken associations, Issue #165\n                nc._parent = c.parent\n                if below:\n                    if c.next_sibling:\n                        c.next_sibling._previous_sibling = nc\n                    nc._next_sibling = c.next_sibling\n                    c._next_sibling = nc\n                    nc._previous_sibling = c\n                else:\n                    if c.previous_sibling:\n                        c.previous_sibling._next_sibling = nc\n                    nc._next_sibling = c\n                    nc._previous_sibling = c.previous_sibling\n                    c._previous_sibling = nc\n\n            t = c.type\n            # increase key for ordered lists\n            if t[-1] in OrderListType:\n                try:\n                    num = int(t[:-1]) + (1 if below else -1)\n                    if num < 0:\n                        # don't decrease to numbers below zero\n                        echom(u\"Can't decrement further than '0'\")\n                        return\n                    t = '%d%s' % (num, t[-1])\n                except ValueError:\n                    try:\n                        char = ord(t[:-1]) + (1 if below else -1)\n                        if below:\n                            if char == 91:\n                                # stop incrementing at Z (90)\n                                echom(u\"Can't increment further than 'Z'\")\n                                return\n                            elif char == 123:\n                                # increment from z (122) to A\n                                char = 65\n                        else:\n                            if char == 96:\n                                # stop decrementing at a (97)\n                                echom(u\"Can't decrement further than 'a'\")\n                                return\n                            elif char == 64:\n                                # decrement from A (65) to z\n                                char = 122\n                        t = u'%s%s' % (chr(char), t[-1])\n                    except ValueError:\n                        pass\n            nc.type = t\n            level = c.level\n\n            if below:\n                start = c.end_of_last_child\n            else:\n                start = c.start\n\n        if plain:      # only create plainlist item when requested\n            nc.status = None\n        nc.level = level\n\n        if below:\n            start += 1\n        # vim's buffer behave just opposite to Python's list when inserting a\n        # new item.  The new entry is appended in vim put prepended in Python!\n        vim.current.buffer.append(\"\") # workaround for neovim\n        vim.current.buffer[start:start] = [unicode(nc)]\n        del vim.current.buffer[-1] # restore from workaround for neovim\n\n        # update checkboxes status\n        cls.update_checkboxes_status()\n\n        # do not start insert upon adding new checkbox, Issue #211\n        if int(settings.get(u'org_prefer_insert_mode', u'1')):\n            vim.command(u_encode(u'exe \"normal %dgg\"|startinsert!' % (start + 1, )))\n        else:\n            vim.command(u_encode(u'exe \"normal %dgg$\"' % (start + 1, )))\n\n    @classmethod\n    def toggle(cls, checkbox=None):\n        u\"\"\"\n        Toggle the checkbox given in the parameter.\n        If the checkbox is not given, it will toggle the current checkbox.\n        \"\"\"\n        d = ORGMODE.get_document()\n        current_heading = d.current_heading()\n        # init checkboxes for current heading\n        if current_heading is None:\n            return\n        current_heading = current_heading.init_checkboxes()\n\n        if checkbox is None:\n            # get current_checkbox\n            c = current_heading.current_checkbox()\n            # no checkbox found\n            if c is None:\n                cls.update_checkboxes_status()\n                return\n        else:\n            c = checkbox\n\n        if c.status == Checkbox.STATUS_OFF or c.status is None:\n            # set checkbox status on if all children are on\n            if c.all_children_status()[0] == 0 or c.are_children_all(Checkbox.STATUS_ON):\n                c.toggle()\n                d.write_checkbox(c)\n            elif c.status is None:\n                c.status = Checkbox.STATUS_OFF\n                d.write_checkbox(c)\n\n        elif c.status == Checkbox.STATUS_ON:\n            if c.all_children_status()[0] == 0 or c.is_child_one(Checkbox.STATUS_OFF):\n                c.toggle()\n                d.write_checkbox(c)\n\n        elif c.status == Checkbox.STATUS_INT:\n            # can't toggle intermediate state directly according to emacs orgmode\n            pass\n        # update checkboxes status\n        cls.update_checkboxes_status()\n\n    @classmethod\n    def _update_subtasks(cls):\n        d = ORGMODE.get_document()\n        h = d.current_heading()\n        # init checkboxes for current heading\n        h.init_checkboxes()\n        # update heading subtask info\n        c = h.first_checkbox\n        if c is None:\n            return\n        total, on = c.all_siblings_status()\n        h.update_subtasks(total, on)\n        # update all checkboxes under current heading\n        cls._update_checkboxes_subtasks(c)\n\n    @classmethod\n    def _update_checkboxes_subtasks(cls, checkbox):\n        # update checkboxes\n        for c in checkbox.all_siblings():\n            if c.children:\n                total, on = c.first_child.all_siblings_status()\n                c.update_subtasks(total, on)\n                cls._update_checkboxes_subtasks(c.first_child)\n\n    @classmethod\n    def update_checkboxes_status(cls):\n        d = ORGMODE.get_document()\n        h = d.current_heading()\n        if h is None:\n            return\n        # init checkboxes for current heading\n        h.init_checkboxes()\n\n        cls._update_checkboxes_status(h.first_checkbox)\n        cls._update_subtasks()\n\n    @classmethod\n    def _update_checkboxes_status(cls, checkbox=None):\n        u\"\"\" helper function for update checkboxes status\n            :checkbox: The first checkbox of this indent level\n            :return: The status of the parent checkbox\n        \"\"\"\n        if checkbox is None:\n            return\n\n        status_off, status_on, status_int, total = 0, 0, 0, 0\n        # update all top level checkboxes' status\n        for c in checkbox.all_siblings():\n            current_status = c.status\n            # if this checkbox is not leaf, its status should determine by all its children\n            if c.all_children_status()[0] > 0:\n                current_status = cls._update_checkboxes_status(c.first_child)\n\n            # don't update status if the checkbox has no status\n            if c.status is None:\n                current_status = None\n            # the checkbox needs to have status\n            else:\n                total += 1\n\n            # count number of status in this checkbox level\n            if current_status == Checkbox.STATUS_OFF:\n                status_off += 1\n            elif current_status == Checkbox.STATUS_ON:\n                status_on += 1\n            elif current_status == Checkbox.STATUS_INT:\n                status_int += 1\n\n            # write status if any update\n            if current_status is not None and c.status != current_status:\n                c.status = current_status\n                d = ORGMODE.get_document()\n                d.write_checkbox(c)\n\n        parent_status = Checkbox.STATUS_INT\n        # all silbing checkboxes are off status\n        if total == 0:\n            pass\n        elif status_off == total:\n            parent_status = Checkbox.STATUS_OFF\n        # all silbing checkboxes are on status\n        elif status_on == total:\n            parent_status = Checkbox.STATUS_ON\n        # one silbing checkbox is on or int status\n        elif status_on != 0 or status_int != 0:\n            parent_status = Checkbox.STATUS_INT\n        # other cases\n        else:\n            parent_status = None\n\n        return parent_status\n\n    def register(self):\n        u\"\"\"\n        Registration of the plugin.\n\n        Key bindings and other initialization should be done here.\n        \"\"\"\n# default setting if it is not already set.\n\n# checkbox related operation\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgCheckBoxNewAbove',\n            function=u'%s ORGMODE.plugins[u\"EditCheckbox\"].new_checkbox()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>cN',\n            menu_desrc=u'New CheckBox Above'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgCheckBoxNewBelow',\n            function=u'%s ORGMODE.plugins[u\"EditCheckbox\"].new_checkbox(below=True)<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>cn',\n            menu_desrc=u'New CheckBox Below'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgCheckBoxToggle',\n            function=u':silent! %s ORGMODE.plugins[u\"EditCheckbox\"].toggle()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>cc',\n            menu_desrc=u'Toggle Checkbox'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgCheckBoxUpdate',\n            function=u':silent! %s ORGMODE.plugins[u\"EditCheckbox\"].update_checkboxes_status()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>c#',\n            menu_desrc=u'Update Subtasks'\n        )\n# plainlist related operation\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgPlainListItemNewAbove',\n            function=u'%s ORGMODE.plugins[u\"EditCheckbox\"].new_checkbox(plain=True)<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>cL',\n            menu_desrc=u'New PlainList Item Above'\n        )\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgPlainListItemNewBelow',\n            function=u'%s ORGMODE.plugins[u\"EditCheckbox\"].new_checkbox(below=True, plain=True)<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>cl',\n            menu_desrc=u'New PlainList Item Below'\n        )\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/EditStructure.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode._vim import ORGMODE, apply_count, repeat, realign_tags\nfrom orgmode import settings\nfrom orgmode.exceptions import HeadingDomError\nfrom orgmode.keybinding import Keybinding, Plug, MODE_INSERT, MODE_NORMAL\nfrom orgmode.menu import Submenu, Separator, ActionEntry\nfrom orgmode.liborgmode.base import Direction\nfrom orgmode.liborgmode.headings import Heading\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\n\nclass EditStructure(object):\n    u\"\"\" EditStructure plugin \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'&Edit Structure')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n    @classmethod\n    def new_heading(cls, below=None, insert_mode=False, end_of_last_child=False):\n        u\"\"\"\n        :below:                True, insert heading below current heading, False,\n                            insert heading above current heading, None, special\n                            behavior for insert mode, use the current text as\n                            heading\n        :insert_mode:        True, if action is performed in insert mode\n        :end_of_last_child:    True, insert heading at the end of last child,\n                            otherwise the newly created heading will \"take\n                            over\" the current heading's children\n        \"\"\"\n        d = ORGMODE.get_document()\n        current_heading = d.current_heading()\n        cursor = vim.current.window.cursor[:]\n        if not current_heading:\n            # the user is in meta data region\n            pos = cursor[0] - 1\n            heading = Heading(title=d.meta_information[pos], body=d.meta_information[pos + 1:])\n            d.headings.insert(0, heading)\n            del d.meta_information[pos:]\n            d.write()\n            vim.command(u_encode(u'exe \"normal %dgg\"|startinsert!' % (heading.start_vim, )))\n            return heading\n\n        # check for plain list(checkbox)\n        current_heading.init_checkboxes()\n        c = current_heading.current_checkbox()\n        if c is not None:\n            ORGMODE.plugins[u\"EditCheckbox\"].new_checkbox(below, not c.status)\n            return\n\n        heading = Heading(level=current_heading.level)\n\n        # it's weird but this is the behavior of original orgmode\n        if below is None:\n            below = cursor[1] != 0 or end_of_last_child\n\n        # insert newly created heading\n        l = current_heading.get_parent_list()\n        idx = current_heading.get_index_in_parent_list()\n        if l is not None and idx is not None:\n            l.insert(idx + (1 if below else 0), heading)\n        else:\n            raise HeadingDomError(u'Current heading is not properly linked in DOM')\n\n        if below and not end_of_last_child:\n            # append heading at the end of current heading and also take\n            # over the children of current heading\n            for child in current_heading.children:\n                heading.children.append(child, taint=False)\n            current_heading.children.remove_slice(\n                0, len(current_heading.children),\n                taint=False)\n\n        # if cursor is currently on a heading, insert parts of it into the\n        # newly created heading\n        if insert_mode and cursor[1] != 0 and cursor[0] == current_heading.start_vim:\n            offset = cursor[1] - current_heading.level - 1 - (\n                len(current_heading.todo) + 1 if current_heading.todo else 0)\n            if offset < 0:\n                offset = 0\n            if int(settings.get(u'org_improve_split_heading', u'1')) and \\\n                offset > 0 and len(current_heading.title) == offset + 1 \\\n                and current_heading.title[offset - 1] not in (u' ', u'\\t'):\n                offset += 1\n            heading.title = current_heading.title[offset:]\n            current_heading.title = current_heading.title[:offset]\n            heading.body = current_heading.body[:]\n            current_heading.body = []\n\n        d.write()\n        # do not start insert upon adding new headings, unless already in insert mode. Issue #211\n        if int(settings.get(u'org_prefer_insert_mode', u'1')) or insert_mode:\n            vim.command(u_encode(u'exe \"normal %dgg\"|startinsert!' % (heading.start_vim, )))\n        else:\n            vim.command(u_encode(u'exe \"normal %dgg$\"' % (heading.start_vim, )))\n\n        # return newly created heading\n        return heading\n\n    @classmethod\n    def _append_heading(cls, heading, parent):\n        if heading.level <= parent.level:\n            raise ValueError('Heading level not is lower than parent level: %d ! > %d' % (heading.level, parent.level))\n\n        if parent.children and parent.children[-1].level < heading.level:\n            cls._append_heading(heading, parent.children[-1])\n        else:\n            parent.children.append(heading, taint=False)\n\n    @classmethod\n    def _change_heading_level(cls, level, including_children=True, on_heading=False, insert_mode=False):\n        u\"\"\"\n        Change level of heading realtively with or without including children.\n\n        :level:                    the number of levels to promote/demote heading\n        :including_children:    True if should should be included in promoting/demoting\n        :on_heading:            True if promoting/demoting should only happen when the cursor is on the heading\n        :insert_mode:            True if vim is in insert mode\n        \"\"\"\n        # TODO : current promote and demote works for only headings. Since\n        #          checkboxes also have tree structure. We should think of\n        #          expanding the functionality of promoting and demoting to\n        #          checkboxes as well\n        d = ORGMODE.get_document()\n        current_heading = d.current_heading()\n        if not current_heading or on_heading and current_heading.start_vim != vim.current.window.cursor[0]:\n            # TODO figure out the actually pressed keybinding and feed these\n            # keys instead of making keys up like this\n            if level > 0:\n                if insert_mode:\n                    vim.eval(u_encode(u'feedkeys(\"\\\\<C-t>\", \"n\")'))\n                elif including_children:\n                    vim.eval(u_encode(u'feedkeys(\">]]\", \"n\")'))\n                elif on_heading:\n                    vim.eval(u_encode(u'feedkeys(\">>\", \"n\")'))\n                else:\n                    vim.eval(u_encode(u'feedkeys(\">}\", \"n\")'))\n            else:\n                if insert_mode:\n                    vim.eval(u_encode(u'feedkeys(\"\\\\<C-d>\", \"n\")'))\n                elif including_children:\n                    vim.eval(u_encode(u'feedkeys(\"<]]\", \"n\")'))\n                elif on_heading:\n                    vim.eval(u_encode(u'feedkeys(\"<<\", \"n\")'))\n                else:\n                    vim.eval(u_encode(u'feedkeys(\"<}\", \"n\")'))\n            # return True because otherwise apply_count will not work\n            return True\n\n        # don't allow demotion below level 1\n        if current_heading.level == 1 and level < 1:\n            return False\n\n        # reduce level of demotion to a minimum heading level of 1\n        if (current_heading.level + level) < 1:\n            level = 1\n\n        def indent(heading, ic):\n            if not heading:\n                return\n            heading.level += level\n\n            if ic:\n                for child in heading.children:\n                    indent(child, ic)\n\n        # save cursor position\n        c = vim.current.window.cursor[:]\n\n        # indent the promoted/demoted heading\n        indent_end_vim = current_heading.end_of_last_child_vim if including_children else current_heading.end_vim\n        indent(current_heading, including_children)\n\n        # when changing the level of a heading, its position in the DOM\n        # needs to be updated. It's likely that the heading gets a new\n        # parent and new children when demoted or promoted\n\n        # find new parent\n        p = current_heading.parent\n        pl = current_heading.get_parent_list()\n        ps = current_heading.previous_sibling\n        nhl = current_heading.level\n\n        if level > 0:\n            # demotion\n            # subheading or top level heading\n            if ps and nhl > ps.level:\n                pl.remove(current_heading, taint=False)\n                # find heading that is the new parent heading\n                oh = ps\n                h = ps\n                while nhl > h.level:\n                    oh = h\n                    if h.children:\n                        h = h.children[-1]\n                    else:\n                        break\n                np = h if nhl > h.level else oh\n\n                # append current heading to new heading\n                np.children.append(current_heading, taint=False)\n\n                # if children are not included, distribute them among the\n                # parent heading and it's siblings\n                if not including_children:\n                    for h in current_heading.children[:]:\n                        if h and h.level <= nhl:\n                            cls._append_heading(h, np)\n                            current_heading.children.remove(h, taint=False)\n        else:\n            # promotion\n            if p and nhl <= p.level:\n                idx = current_heading.get_index_in_parent_list() + 1\n                # find the new parent heading\n                oh = p\n                h = p\n                while nhl <= h.level:\n                    # append new children to current heading\n                    for child in h.children[idx:]:\n                        cls._append_heading(child, current_heading)\n                    h.children.remove_slice(idx, len(h.children), taint=False)\n                    idx = h.get_index_in_parent_list() + 1\n                    if h.parent:\n                        h = h.parent\n                    else:\n                        break\n                ns = oh.next_sibling\n                while ns and ns.level > current_heading.level:\n                    nns = ns.next_sibling\n                    cls._append_heading(ns, current_heading)\n                    ns = nns\n\n                # append current heading to new parent heading / document\n                pl.remove(current_heading, taint=False)\n                if nhl > h.level:\n                    h.children.insert(idx, current_heading, taint=False)\n                else:\n                    d.headings.insert(idx, current_heading, taint=False)\n\n        d.write()\n\n        # restore cursor position\n        vim.current.window.cursor = (c[0], c[1] + level)\n\n        return True\n\n    @classmethod\n    @realign_tags\n    @repeat\n    @apply_count\n    def demote_heading(cls, including_children=True, on_heading=False, insert_mode=False):\n        if cls._change_heading_level(1, including_children=including_children, on_heading=on_heading, insert_mode=insert_mode):\n            if including_children:\n                return u'OrgDemoteSubtree'\n            return u'OrgDemoteHeading'\n\n    @classmethod\n    @realign_tags\n    @repeat\n    @apply_count\n    def promote_heading(cls, including_children=True, on_heading=False, insert_mode=False):\n        if cls._change_heading_level(-1, including_children=including_children, on_heading=on_heading, insert_mode=insert_mode):\n            if including_children:\n                return u'OrgPromoteSubtreeNormal'\n            return u'OrgPromoteHeadingNormal'\n\n    @classmethod\n    def _move_heading(cls, direction=Direction.FORWARD, including_children=True):\n        u\"\"\" Move heading up or down\n\n        :returns: heading or None\n        \"\"\"\n        d = ORGMODE.get_document()\n        current_heading = d.current_heading()\n        if not current_heading or \\\n            (direction == Direction.FORWARD and not current_heading.next_sibling) or \\\n            (direction == Direction.BACKWARD and not current_heading.previous_sibling):\n            return None\n\n        cursor_offset = vim.current.window.cursor[0] - (current_heading._orig_start + 1)\n        l = current_heading.get_parent_list()\n        if l is None:\n            raise HeadingDomError(u'Current heading is not properly linked in DOM')\n\n        if not including_children:\n            if current_heading.previous_sibling:\n                npl = current_heading.previous_sibling.children\n                for child in current_heading.children:\n                    npl.append(child, taint=False)\n            elif current_heading.parent:\n                # if the current heading doesn't have a previous sibling it\n                # must be the first heading\n                np = current_heading.parent\n                for child in current_heading.children:\n                    cls._append_heading(child, np)\n            else:\n                # if the current heading doesn't have a parent, its children\n                # must be added as top level headings to the document\n                npl = l\n                for child in current_heading.children[::-1]:\n                    npl.insert(0, child, taint=False)\n            current_heading.children.remove_slice(0, len(current_heading.children), taint=False)\n\n        idx = current_heading.get_index_in_parent_list()\n        if idx is None:\n            raise HeadingDomError(u'Current heading is not properly linked in DOM')\n\n        offset = 1 if direction == Direction.FORWARD else -1\n        del l[idx]\n        l.insert(idx + offset, current_heading)\n\n        d.write()\n\n        vim.current.window.cursor = (\n            current_heading.start_vim + cursor_offset,\n            vim.current.window.cursor[1])\n\n        return True\n\n    @classmethod\n    @repeat\n    @apply_count\n    def move_heading_upward(cls, including_children=True):\n        if cls._move_heading(direction=Direction.BACKWARD, including_children=including_children):\n            if including_children:\n                return u'OrgMoveSubtreeUpward'\n            return u'OrgMoveHeadingUpward'\n\n    @classmethod\n    @repeat\n    @apply_count\n    def move_heading_downward(cls, including_children=True):\n        if cls._move_heading(direction=Direction.FORWARD, including_children=including_children):\n            if including_children:\n                return u'OrgMoveSubtreeDownward'\n            return u'OrgMoveHeadingDownward'\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n# EditStructure related default settings\n        settings.set(u'org_improve_split_heading', u'1')\n# EditStructure related keybindings\n        self.keybindings.append(Keybinding(u'<C-S-CR>',\n                                     Plug(u'OrgNewHeadingAboveNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].new_heading(below=False)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'New Heading &above', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'<localleader>hN', u'<Plug>OrgNewHeadingAboveNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'<localleader><CR>', u'<Plug>OrgNewHeadingAboveNormal', mode=MODE_NORMAL))\n\n        self.keybindings.append(Keybinding(u'<S-CR>',\n                                     Plug(u'OrgNewHeadingBelowNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].new_heading(below=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'New Heading &below', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'<localleader>hh', u'<Plug>OrgNewHeadingBelowNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'<localleader><CR>', u'<Plug>OrgNewHeadingBelowNormal', mode=MODE_NORMAL))\n\n        self.keybindings.append(Keybinding(u'<C-CR>', Plug(u'OrgNewHeadingBelowAfterChildrenNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].new_heading(below=True, end_of_last_child=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'New Heading below, after &children', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'<localleader>hn', u'<Plug>OrgNewHeadingBelowAfterChildrenNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'<CR>', u'<Plug>OrgNewHeadingBelowAfterChildrenNormal', mode=MODE_NORMAL))\n\n        self.keybindings.append(Keybinding(u'<C-S-CR>', Plug(u'OrgNewHeadingAboveInsert', u'<C-o>:<C-u>silent! %s ORGMODE.plugins[u\"EditStructure\"].new_heading(below=False, insert_mode=True)<CR>' % VIM_PY_CALL, mode=MODE_INSERT)))\n        self.keybindings.append(Keybinding(u'<S-CR>', Plug(u'OrgNewHeadingBelowInsert', u'<C-o>:<C-u>silent! %s ORGMODE.plugins[u\"EditStructure\"].new_heading(below=True, insert_mode=True)<CR>' % VIM_PY_CALL, mode=MODE_INSERT)))\n        self.keybindings.append(Keybinding(u'<C-CR>', Plug(u'OrgNewHeadingBelowAfterChildrenInsert', u'<C-o>:<C-u>silent! %s ORGMODE.plugins[u\"EditStructure\"].new_heading(insert_mode=True, end_of_last_child=True)<CR>' % VIM_PY_CALL, mode=MODE_INSERT)))\n\n        self.menu + Separator()\n\n        self.keybindings.append(Keybinding(u'm{', Plug(u'OrgMoveHeadingUpward',\n                                                 u'%s ORGMODE.plugins[u\"EditStructure\"].move_heading_upward(including_children=False)<CR>' % VIM_PY_CALL)))\n        self.keybindings.append(Keybinding(u'm[[',\n                                     Plug(u'OrgMoveSubtreeUpward', u'%s ORGMODE.plugins[u\"EditStructure\"].move_heading_upward()<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Move Subtree &Up', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'm}',\n                                     Plug(u'OrgMoveHeadingDownward', u'%s ORGMODE.plugins[u\"EditStructure\"].move_heading_downward(including_children=False)<CR>' % VIM_PY_CALL)))\n        self.keybindings.append(Keybinding(u'm]]',\n                                     Plug(u'OrgMoveSubtreeDownward', u'%s ORGMODE.plugins[u\"EditStructure\"].move_heading_downward()<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Move Subtree &Down', self.keybindings[-1])\n\n        self.menu + Separator()\n\n        self.menu + ActionEntry(u'&Copy Heading', u'yah', u'yah')\n        self.menu + ActionEntry(u'C&ut Heading', u'dah', u'dah')\n\n        self.menu + Separator()\n\n        self.menu + ActionEntry(u'&Copy Subtree', u'yar', u'yar')\n        self.menu + ActionEntry(u'C&ut Subtree', u'dar', u'dar')\n        self.menu + ActionEntry(u'&Paste Subtree', u'p', u'p')\n\n        self.menu + Separator()\n\n        self.keybindings.append(Keybinding(u'<ah', Plug(u'OrgPromoteHeadingNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].promote_heading(including_children=False)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Promote Heading', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'<<', Plug(u'OrgPromoteOnHeadingNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].promote_heading(including_children=False, on_heading=True)<CR>' % VIM_PY_CALL)))\n        self.keybindings.append(Keybinding(u'<{', u'<Plug>OrgPromoteHeadingNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'<ih', u'<Plug>OrgPromoteHeadingNormal', mode=MODE_NORMAL))\n\n        self.keybindings.append(Keybinding(u'<ar', Plug(u'OrgPromoteSubtreeNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].promote_heading()<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Promote Subtree', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'<[[', u'<Plug>OrgPromoteSubtreeNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'<ir', u'<Plug>OrgPromoteSubtreeNormal', mode=MODE_NORMAL))\n\n        self.keybindings.append(Keybinding(u'>ah', Plug(u'OrgDemoteHeadingNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].demote_heading(including_children=False)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Demote Heading', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'>>', Plug(u'OrgDemoteOnHeadingNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].demote_heading(including_children=False, on_heading=True)<CR>' % VIM_PY_CALL)))\n        self.keybindings.append(Keybinding(u'>}', u'<Plug>OrgDemoteHeadingNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'>ih', u'<Plug>OrgDemoteHeadingNormal', mode=MODE_NORMAL))\n\n        self.keybindings.append(Keybinding(u'>ar', Plug(u'OrgDemoteSubtreeNormal', u':silent! %s ORGMODE.plugins[u\"EditStructure\"].demote_heading()<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Demote Subtree', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'>]]', u'<Plug>OrgDemoteSubtreeNormal', mode=MODE_NORMAL))\n        self.keybindings.append(Keybinding(u'>ir', u'<Plug>OrgDemoteSubtreeNormal', mode=MODE_NORMAL))\n\n        # other keybindings\n        self.keybindings.append(Keybinding(u'<C-d>', Plug(u'OrgPromoteOnHeadingInsert', u'<C-o>:silent! %s ORGMODE.plugins[u\"EditStructure\"].promote_heading(including_children=False, on_heading=True, insert_mode=True)<CR>' % VIM_PY_CALL, mode=MODE_INSERT)))\n        self.keybindings.append(Keybinding(u'<C-t>', Plug(u'OrgDemoteOnHeadingInsert', u'<C-o>:silent! %s ORGMODE.plugins[u\"EditStructure\"].demote_heading(including_children=False, on_heading=True, insert_mode=True)<CR>' % VIM_PY_CALL, mode=MODE_INSERT)))\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Export.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport os\nimport subprocess\n\nimport vim\n\nfrom orgmode._vim import ORGMODE, echoe, echom\nfrom orgmode.menu import Submenu, ActionEntry, add_cmd_mapping_menu\nfrom orgmode.keybinding import Keybinding, Plug, Command\nfrom orgmode import settings\n\nfrom orgmode.py3compat.py_py3_string import *\n\nclass Export(object):\n    u\"\"\"\n    Export a orgmode file using emacs orgmode.\n\n    This is a *very simple* wrapper of the emacs/orgmode export.  emacs and\n    orgmode need to be installed. We simply call emacs with some options to\n    export the .org.\n\n    TODO: Offer export options in vim. Don't use the menu.\n    TODO: Maybe use a native implementation.\n    \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Export')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    @classmethod\n    def _get_init_script(cls):\n        init_script = settings.get(u'org_export_init_script', u'')\n        if init_script:\n            init_script = os.path.expandvars(os.path.expanduser(init_script))\n            if os.path.exists(init_script):\n                return init_script\n            else:\n                echoe(u'Unable to find init script %s' % init_script)\n\n    @classmethod\n    def _export(cls, format_):\n        \"\"\"Export current file to format.\n\n        Args:\n            format_: pdf or html\n\n        Returns:\n            return code\n        \"\"\"\n        emacsbin = os.path.expandvars(os.path.expanduser(\n            settings.get(u'org_export_emacs', u'/usr/bin/emacs')))\n        if not os.path.exists(emacsbin):\n            echoe(u'Unable to find emacs binary %s' % emacsbin)\n\n        # build the export command\n        cmd = [\n            emacsbin,\n            u'-nw',\n            u'--batch',\n            u'--visit=%s' % vim.eval(u'expand(\"%:p\")'),\n            u'--funcall=%s' % format_\n        ]\n        # source init script as well\n        init_script = cls._get_init_script()\n        if init_script:\n            cmd.extend(['--script', init_script])\n\n        # export\n        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        p.wait()\n\n        if p.returncode != 0 or settings.get(u'org_export_verbose') == 1:\n            echom('\\n'.join(map(lambda x: x.decode(), p.communicate())))\n        return p.returncode\n\n    @classmethod\n    def topdf(cls):\n        u\"\"\"Export the current buffer as pdf using emacs orgmode.\"\"\"\n        ret = cls._export(u'org-latex-export-to-pdf')\n        if ret != 0:\n            echoe(u'PDF export failed.')\n        else:\n            echom(u'Export successful: %s.%s' % (vim.eval(u'expand(\"%:r\")'), 'pdf'))\n\n    @classmethod\n    def tobeamer(cls):\n        u\"\"\"Export the current buffer as beamer pdf using emacs orgmode.\"\"\"\n        ret = cls._export(u'org-beamer-export-to-pdf')\n        if ret != 0:\n            echoe(u'PDF export failed.')\n        else:\n            echom(u'Export successful: %s.%s' % (vim.eval(u'expand(\"%:r\")'), 'pdf'))\n\n    @classmethod\n    def tohtml(cls):\n        u\"\"\"Export the current buffer as html using emacs orgmode.\"\"\"\n        ret = cls._export(u'org-html-export-to-html')\n        if ret != 0:\n            echoe(u'HTML export failed.')\n        else:\n            echom(u'Export successful: %s.%s' % (vim.eval(u'expand(\"%:r\")'), 'html'))\n\n    @classmethod\n    def tolatex(cls):\n        u\"\"\"Export the current buffer as latex using emacs orgmode.\"\"\"\n        ret = cls._export(u'org-latex-export-to-latex')\n        if ret != 0:\n            echoe(u'latex export failed.')\n        else:\n            echom(u'Export successful: %s.%s' % (vim.eval(u'expand(\"%:r\")'), 'tex'))\n\n    @classmethod\n    def tomarkdown(cls):\n        u\"\"\"Export the current buffer as markdown using emacs orgmode.\"\"\"\n        ret = cls._export(u'org-md-export-to-markdown')\n        if ret != 0:\n            echoe('Markdown export failed. Make sure org-md-export-to-markdown is loaded in emacs, see the manual for details.')\n        else:\n            echom(u'Export successful: %s.%s' % (vim.eval(u'expand(\"%:r\")'), 'md'))\n\n    def register(self):\n        u\"\"\"Registration and keybindings.\"\"\"\n\n        # path to emacs executable\n        settings.set(u'org_export_emacs', u'/usr/bin/emacs')\n        # verbose output for export\n        settings.set(u'org_export_verbose', 0)\n        # allow the user to define an initialization script\n        settings.set(u'org_export_init_script', u'')\n\n        # to PDF\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgExportToPDF',\n            function=u':%s ORGMODE.plugins[u\"Export\"].topdf()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>ep',\n            menu_desrc=u'To PDF (via Emacs)'\n        )\n        # to Beamer PDF\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgExportToBeamerPDF',\n            function=u':%s ORGMODE.plugins[u\"Export\"].tobeamer()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>eb',\n            menu_desrc=u'To Beamer PDF (via Emacs)'\n        )\n        # to latex\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgExportToLaTeX',\n            function=u':%s ORGMODE.plugins[u\"Export\"].tolatex()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>el',\n            menu_desrc=u'To LaTeX (via Emacs)'\n        )\n        # to HTML\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgExportToHTML',\n            function=u':%s ORGMODE.plugins[u\"Export\"].tohtml()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>eh',\n            menu_desrc=u'To HTML (via Emacs)'\n        )\n        # to Markdown\n        add_cmd_mapping_menu(\n            self,\n            name=u'OrgExportToMarkdown',\n            function=u':%s ORGMODE.plugins[u\"Export\"].tomarkdown()<CR>' % VIM_PY_CALL,\n            key_mapping=u'<localleader>em',\n            menu_desrc=u'To Markdown (via Emacs)'\n        )\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Hyperlinks.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport re\n\nimport vim\n\nfrom orgmode._vim import echom, ORGMODE, realign_tags\nfrom orgmode.menu import Submenu, Separator, ActionEntry\nfrom orgmode.keybinding import Keybinding, Plug, Command\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass Hyperlinks(object):\n    u\"\"\" Hyperlinks plugin \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Hyperlinks')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    uri_match = re.compile(\n        r'^\\[{2}(?P<uri>[^][]*)(\\]\\[(?P<description>[^][]*))?\\]{2}')\n\n    @classmethod\n    def _get_link(cls, cursor=None):\n        u\"\"\"\n        Get the link the cursor is on and return it's URI and description\n\n        :cursor: None or (Line, Column)\n        :returns: None if no link was found, otherwise {uri:URI,\n                description:DESCRIPTION, line:LINE, start:START, end:END}\n                or uri and description could be None if not set\n        \"\"\"\n        cursor = cursor if cursor else vim.current.window.cursor\n        line = u_decode(vim.current.buffer[cursor[0] - 1])\n\n        # if the cursor is on the last bracket, it's not recognized as a hyperlink\n        start = line.rfind(u'[[', 0, cursor[1])\n        if start == -1:\n            start = line.rfind(u'[[', 0, cursor[1] + 2)\n        end = line.find(u']]', cursor[1])\n        if end == -1:\n            end = line.find(u']]', cursor[1] - 1)\n\n        # extract link\n        if start != -1 and end != -1:\n            end += 2\n            match = Hyperlinks.uri_match.match(line[start:end])\n\n            res = {\n                u'line': line,\n                u'start': start,\n                u'end': end,\n                u'uri': None,\n                u'description': None}\n            if match:\n                res.update(match.groupdict())\n            # reverse character escaping(partly done due to matching)\n            res[u'uri'] = res[u'uri'].replace(u'\\\\\\\\', u'\\\\')\n            return res\n\n    @classmethod\n    def follow(cls, action=u'openLink', visual=u''):\n        u\"\"\" Follow hyperlink. If called on a regular string UTL determines the\n        outcome. Normally a file with that name will be opened.\n\n        :action: \"copy\" if the link should be copied to clipboard, otherwise\n                the link will be opened\n        :visual: \"visual\" if Universal Text Linking should be triggered in\n                visual mode\n\n        :returns: URI or None\n        \"\"\"\n        if not int(vim.eval(u'exists(\":Utl\")')):\n            echom(u'Universal Text Linking plugin not installed, unable to proceed.')\n            return\n\n        action = u'copyLink' \\\n            if (action and action.startswith(u'copy')) \\\n            else u'openLink'\n        visual = u'visual' if visual and visual.startswith(u'visual') else u''\n\n        link = Hyperlinks._get_link()\n\n        if link and link[u'uri'] is not None:\n            # call UTL with the URI\n            vim.command(u_encode(u'Utl %s %s %s' % (action, visual, link[u'uri'])))\n            return link[u'uri']\n        else:\n            # call UTL and let it decide what to do\n            vim.command(u_encode(u'Utl %s %s' % (action, visual)))\n\n    @classmethod\n    @realign_tags\n    def insert(cls, uri=None, description=None):\n        u\"\"\" Inserts a hyperlink. If no arguments are provided, an interactive\n        query will be started.\n\n        :uri: The URI that will be opened\n        :description: An optional description that will be displayed instead of\n                the URI\n\n        :returns: (URI, description)\n        \"\"\"\n        link = Hyperlinks._get_link()\n        if link:\n            if uri is None and link[u'uri'] is not None:\n                uri = link[u'uri']\n            if description is None and link[u'description'] is not None:\n                description = link[u'description']\n\n        if uri is None:\n            uri = vim.eval(u'input(\"Link: \", \"\", \"file\")')\n        elif link:\n            uri = vim.eval(u'input(\"Link: \", \"%s\", \"file\")' % link[u'uri'])\n        if uri is None:\n            return\n        else:\n            uri = u_decode(uri)\n\n        # character escaping\n        uri = uri.replace(u'\\\\', u'\\\\\\\\\\\\\\\\')\n        uri = uri.replace(u' ', u'\\\\ ')\n\n        if description is None:\n            description = u_decode(vim.eval(u'input(\"Description: \")'))\n        elif link:\n            description = vim.eval(\n                u'input(\"Description: \", \"%s\")' %\n                u_decode(link[u'description']))\n        if description is None:\n            return\n\n        cursor = vim.current.window.cursor\n        cl = u_decode(vim.current.buffer[cursor[0] - 1])\n        head = cl[:cursor[1] + 1] if not link else cl[:link[u'start']]\n        tail = cl[cursor[1] + 1:] if not link else cl[link[u'end']:]\n\n        separator = u''\n        if description:\n            separator = u']['\n\n        if uri or description:\n            vim.current.buffer[cursor[0] - 1] = \\\n                u_encode(u''.join((head, u'[[%s%s%s]]' % (uri, separator, description), tail)))\n        elif link:\n            vim.current.buffer[cursor[0] - 1] = \\\n                u_encode(u''.join((head, tail)))\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n        cmd = Command(\n            u'OrgHyperlinkFollow',\n            u'%s ORGMODE.plugins[u\"Hyperlinks\"].follow()' % VIM_PY_CALL)\n        self.commands.append(cmd)\n        self.keybindings.append(\n            Keybinding(u'gl', Plug(u'OrgHyperlinkFollow', self.commands[-1])))\n        self.menu + ActionEntry(u'&Follow Link', self.keybindings[-1])\n\n        cmd = Command(\n            u'OrgHyperlinkCopy',\n            u'%s ORGMODE.plugins[u\"Hyperlinks\"].follow(action=u\"copy\")' % VIM_PY_CALL)\n        self.commands.append(cmd)\n        self.keybindings.append(\n            Keybinding(u'gyl', Plug(u'OrgHyperlinkCopy', self.commands[-1])))\n        self.menu + ActionEntry(u'&Copy Link', self.keybindings[-1])\n\n        cmd = Command(\n            u'OrgHyperlinkInsert',\n            u'%s ORGMODE.plugins[u\"Hyperlinks\"].insert(<f-args>)' % VIM_PY_CALL,\n            arguments=u'*')\n        self.commands.append(cmd)\n        self.keybindings.append(\n            Keybinding(u'gil', Plug(u'OrgHyperlinkInsert', self.commands[-1])))\n        self.menu + ActionEntry(u'&Insert Link', self.keybindings[-1])\n\n        self.menu + Separator()\n\n        # find next link\n        cmd = Command(\n            u'OrgHyperlinkNextLink',\n            u\":if search('\\\\[\\\\{2}\\\\zs[^][]*\\\\(\\\\]\\\\[[^][]*\\\\)\\\\?\\\\ze\\\\]\\\\{2}', 's') == 0 | echo 'No further link found.' | endif\")\n        self.commands.append(cmd)\n        self.keybindings.append(\n            Keybinding(u'gn', Plug(u'OrgHyperlinkNextLink', self.commands[-1])))\n        self.menu + ActionEntry(u'&Next Link', self.keybindings[-1])\n\n        # find previous link\n        cmd = Command(\n            u'OrgHyperlinkPreviousLink',\n            u\":if search('\\\\[\\\\{2}\\\\zs[^][]*\\\\(\\\\]\\\\[[^][]*\\\\)\\\\?\\\\ze\\\\]\\\\{2}', 'bs') == 0 | echo 'No further link found.' | endif\")\n        self.commands.append(cmd)\n        self.keybindings.append(\n            Keybinding(u'go', Plug(u'OrgHyperlinkPreviousLink', self.commands[-1])))\n        self.menu + ActionEntry(u'&Previous Link', self.keybindings[-1])\n\n        self.menu + Separator()\n\n        # Descriptive Links\n        cmd = Command(u'OrgHyperlinkDescriptiveLinks', u':setlocal cole=2')\n        self.commands.append(cmd)\n        self.menu + ActionEntry(u'&Descriptive Links', self.commands[-1])\n\n        # Literal Links\n        cmd = Command(u'OrgHyperlinkLiteralLinks', u':setlocal cole=0')\n        self.commands.append(cmd)\n        self.menu + ActionEntry(u'&Literal Links', self.commands[-1])\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/LoggingWork.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode._vim import echo, echom, echoe, ORGMODE, apply_count, repeat\nfrom orgmode.menu import Submenu, Separator, ActionEntry\nfrom orgmode.keybinding import Keybinding, Plug, Command\n\nfrom orgmode.py3compat.py_py3_string import *\n\nclass LoggingWork(object):\n    u\"\"\" LoggingWork plugin \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'&Logging work')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    @classmethod\n    def action(cls):\n        u\"\"\" Some kind of action\n\n        :returns: TODO\n        \"\"\"\n        pass\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n        # an Action menu entry which binds \"keybinding\" to action \":action\"\n        self.commands.append(Command(u'OrgLoggingRecordDoneTime', u'%s ORGMODE.plugins[u\"LoggingWork\"].action()' % VIM_PY_CALL))\n        self.menu + ActionEntry(u'&Record DONE time', self.commands[-1])\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Misc.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode._vim import ORGMODE, apply_count\nfrom orgmode.menu import Submenu\nfrom orgmode.keybinding import Keybinding, Plug, MODE_VISUAL, MODE_OPERATOR\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass Misc(object):\n    u\"\"\" Miscellaneous functionality \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'Misc')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n    @classmethod\n    def jump_to_first_character(cls):\n        heading = ORGMODE.get_document().current_heading()\n        if not heading or heading.start_vim != vim.current.window.cursor[0]:\n            vim.eval(u_encode(u'feedkeys(\"^\", \"n\")'))\n            return\n\n        vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)\n\n    @classmethod\n    def edit_at_first_character(cls):\n        heading = ORGMODE.get_document().current_heading()\n        if not heading or heading.start_vim != vim.current.window.cursor[0]:\n            vim.eval(u_encode(u'feedkeys(\"I\", \"n\")'))\n            return\n\n        vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)\n        vim.command(u_encode(u'startinsert'))\n\n    # @repeat\n    @classmethod\n    @apply_count\n    def i_heading(cls, mode=u'visual', selection=u'inner', skip_children=False):\n        u\"\"\"\n        inner heading text object\n        \"\"\"\n        heading = ORGMODE.get_document().current_heading()\n        if heading:\n            if selection != u'inner':\n                heading = heading if not heading.parent else heading.parent\n\n            line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'<\")'))[1:3]]\n            line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'>\")'))[1:3]]\n\n            if mode != u'visual':\n                line_start = vim.current.window.cursor[0]\n                line_end = line_start\n\n            start = line_start\n            end = line_end\n            move_one_character_back = u'' if mode == u'visual' else u'h'\n\n            if heading.start_vim < line_start:\n                start = heading.start_vim\n            if heading.end_vim > line_end and not skip_children:\n                end = heading.end_vim\n            elif heading.end_of_last_child_vim > line_end and skip_children:\n                end = heading.end_of_last_child_vim\n\n            if mode != u'visual' and not vim.current.buffer[end - 1]:\n                end -= 1\n                move_one_character_back = u''\n\n            swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''\n\n            if selection == u'inner' and vim.current.window.cursor[0] != line_start:\n                h = ORGMODE.get_document().current_heading()\n                if h:\n                    heading = h\n\n            visualmode = u_decode(vim.eval(u'visualmode()')) if mode == u'visual' else u'v'\n\n            if line_start == start and line_start != heading.start_vim:\n                if col_start in (0, 1):\n                    vim.command(u_encode(u'normal! %dgg0%s%dgg$%s%s' % (start, visualmode, end, move_one_character_back, swap_cursor)))\n                else:\n                    vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, col_start - 1, visualmode, end, move_one_character_back, swap_cursor)))\n            else:\n                vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, heading.level + 1, visualmode, end, move_one_character_back, swap_cursor)))\n\n            if selection == u'inner':\n                if mode == u'visual':\n                    return u'OrgInnerHeadingVisual' if not skip_children else u'OrgInnerTreeVisual'\n                else:\n                    return u'OrgInnerHeadingOperator' if not skip_children else u'OrgInnerTreeOperator'\n            else:\n                if mode == u'visual':\n                    return u'OrgOuterHeadingVisual' if not skip_children else u'OrgOuterTreeVisual'\n                else:\n                    return u'OrgOuterHeadingOperator' if not skip_children else u'OrgOuterTreeOperator'\n        elif mode == u'visual':\n            vim.command(u_encode(u'normal! gv'))\n\n    # @repeat\n    @classmethod\n    @apply_count\n    def a_heading(cls, selection=u'inner', skip_children=False):\n        u\"\"\"\n        a heading text object\n        \"\"\"\n        heading = ORGMODE.get_document().current_heading()\n        if heading:\n            if selection != u'inner':\n                heading = heading if not heading.parent else heading.parent\n\n            line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'<\")'))[1:3]]\n            line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'>\")'))[1:3]]\n\n            start = line_start\n            end = line_end\n\n            if heading.start_vim < line_start:\n                start = heading.start_vim\n            if heading.end_vim > line_end and not skip_children:\n                end = heading.end_vim\n            elif heading.end_of_last_child_vim > line_end and skip_children:\n                end = heading.end_of_last_child_vim\n\n            swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''\n\n            vim.command(u_encode(u'normal! %dgg%s%dgg$%s' %    (start, vim.eval(u_encode(u'visualmode()')), end, swap_cursor)))\n            if selection == u'inner':\n                return u'OrgAInnerHeadingVisual' if not skip_children else u'OrgAInnerTreeVisual'\n            else:\n                return u'OrgAOuterHeadingVisual' if not skip_children else u'OrgAOuterTreeVisual'\n        else:\n            vim.command(u_encode(u'normal! gv'))\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n        self.keybindings.append(Keybinding(u'^',\n                                     Plug(u'OrgJumpToFirstCharacter', u'%s ORGMODE.plugins[u\"Misc\"].jump_to_first_character()<CR>' % VIM_PY_CALL)))\n        self.keybindings.append(Keybinding(u'I',\n                                     Plug(u'OrgEditAtFirstCharacter', u'%s ORGMODE.plugins[u\"Misc\"].edit_at_first_character()<CR>' % VIM_PY_CALL)))\n\n        self.keybindings.append(Keybinding(u'ih', Plug(u'OrgInnerHeadingVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading()<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'ah', Plug(u'OrgAInnerHeadingVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].a_heading()<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'Oh', Plug(u'OrgOuterHeadingVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(selection=u\"outer\")<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'OH', Plug(u'OrgAOuterHeadingVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].a_heading(selection=u\"outer\")<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n\n        self.keybindings.append(Keybinding(u'ih', Plug(u'OrgInnerHeadingOperator', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(mode=u\"operator\")<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'ah', u':normal Vah<CR>', mode=MODE_OPERATOR))\n        self.keybindings.append(Keybinding(u'Oh', Plug(u'OrgOuterHeadingOperator', ':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(mode=u\"operator\", selection=u\"outer\")<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'OH', u':normal VOH<CR>', mode=MODE_OPERATOR))\n\n        self.keybindings.append(Keybinding(u'ir', Plug(u'OrgInnerTreeVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'ar', Plug(u'OrgAInnerTreeVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].a_heading(skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'Or', Plug(u'OrgOuterTreeVisual', u'<:<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(selection=u\"outer\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'OR', Plug(u'OrgAOuterTreeVisual', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].a_heading(selection=u\"outer\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n\n        self.keybindings.append(Keybinding(u'ir', Plug(u'OrgInnerTreeOperator', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(mode=u\"operator\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'ar', u':normal Var<CR>', mode=MODE_OPERATOR))\n        self.keybindings.append(Keybinding(u'Or', Plug(u'OrgOuterTreeOperator', u':<C-u>%s ORGMODE.plugins[u\"Misc\"].i_heading(mode=u\"operator\", selection=u\"outer\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'OR', u':normal VOR<CR>', mode=MODE_OPERATOR))\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Navigator.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode._vim import echo, ORGMODE, apply_count\nfrom orgmode.menu import Submenu, ActionEntry\nfrom orgmode.keybinding import Keybinding, MODE_VISUAL, MODE_OPERATOR, Plug\nfrom orgmode.liborgmode.documents import Direction\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass Navigator(object):\n    u\"\"\" Implement navigation in org-mode documents \"\"\"\n\n    def __init__(self):\n        object.__init__(self)\n        self.menu = ORGMODE.orgmenu + Submenu(u'&Navigate Headings')\n        self.keybindings = []\n\n    @classmethod\n    @apply_count\n    def parent(cls, mode):\n        u\"\"\"\n        Focus parent heading\n\n        :returns: parent heading or None\n        \"\"\"\n        heading = ORGMODE.get_document().current_heading()\n        if not heading:\n            if mode == u'visual':\n                vim.command(u_encode(u'normal! gv'))\n            else:\n                echo(u'No heading found')\n            return\n\n        if not heading.parent:\n            if mode == u'visual':\n                vim.command(u_encode(u'normal! gv'))\n            else:\n                echo(u'No parent heading found')\n            return\n\n        p = heading.parent\n\n        if mode == u'visual':\n            cls._change_visual_selection(heading, p, direction=Direction.BACKWARD, parent=True)\n        else:\n            vim.current.window.cursor = (p.start_vim, p.level + 1)\n        return p\n\n    @classmethod\n    @apply_count\n    def parent_next_sibling(cls, mode):\n        u\"\"\"\n        Focus the parent's next sibling\n\n        :returns: parent's next sibling heading or None\n        \"\"\"\n        heading = ORGMODE.get_document().current_heading()\n        if not heading:\n            if mode == u'visual':\n                vim.command(u_encode(u'normal! gv'))\n            else:\n                echo(u'No heading found')\n            return\n\n        if not heading.parent or not heading.parent.next_sibling:\n            if mode == u'visual':\n                vim.command(u_encode(u'normal! gv'))\n            else:\n                echo(u'No parent heading found')\n            return\n\n        ns = heading.parent.next_sibling\n\n        if mode == u'visual':\n            cls._change_visual_selection(heading, ns, direction=Direction.FORWARD, parent=False)\n        elif mode == u'operator':\n            vim.current.window.cursor = (ns.start_vim, 0)\n        else:\n            vim.current.window.cursor = (ns.start_vim, ns.level + 1)\n        return ns\n\n    @classmethod\n    def _change_visual_selection(cls, current_heading, heading, direction=Direction.FORWARD, noheadingfound=False, parent=False):\n        current = vim.current.window.cursor[0]\n        line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'<\")'))[1:3]]\n        line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'>\")'))[1:3]]\n\n        f_start = heading.start_vim\n        f_end = heading.end_vim\n        swap_cursor = True\n\n        # << |visual start\n        # selection end >>\n        if current == line_start:\n            if (direction == Direction.FORWARD and line_end < f_start) or noheadingfound and not direction == Direction.BACKWARD:\n                swap_cursor = False\n\n            # focus heading HERE\n            # << |visual start\n            # selection end >>\n\n            # << |visual start\n            # focus heading HERE\n            # selection end >>\n            if f_start < line_start and direction == Direction.BACKWARD:\n                if current_heading.start_vim < line_start and not parent:\n                    line_start = current_heading.start_vim\n                else:\n                    line_start = f_start\n\n            elif (f_start < line_start or f_start < line_end) and not noheadingfound:\n                line_start = f_start\n\n            # << |visual start\n            # selection end >>\n            # focus heading HERE\n            else:\n                if direction == Direction.FORWARD:\n                    if line_end < f_start and not line_start == f_start - 1 and current_heading:\n                        # focus end of previous heading instead of beginning of next heading\n                        line_start = line_end\n                        line_end = f_start - 1\n                    else:\n                        # focus end of next heading\n                        line_start = line_end\n                        line_end = f_end\n                elif direction == Direction.BACKWARD:\n                    if line_end < f_end:\n                        pass\n                else:\n                    line_start = line_end\n                    line_end = f_end\n\n        # << visual start\n        # selection end| >>\n        else:\n            # focus heading HERE\n            # << visual start\n            # selection end| >>\n            if line_start > f_start and line_end > f_end and not parent:\n                line_end = f_end\n                swap_cursor = False\n\n            elif (line_start > f_start or line_start == f_start) and \\\n                line_end <= f_end and direction == Direction.BACKWARD:\n                line_end = line_start\n                line_start = f_start\n\n            # << visual start\n            # selection end and focus heading end HERE| >>\n\n            # << visual start\n            # focus heading HERE\n            # selection end| >>\n\n            # << visual start\n            # selection end| >>\n            # focus heading HERE\n            else:\n                if direction == Direction.FORWARD:\n                    if line_end < f_start - 1:\n                        # focus end of previous heading instead of beginning of next heading\n                        line_end = f_start - 1\n                    else:\n                        # focus end of next heading\n                        line_end = f_end\n                else:\n                    line_end = f_end\n                swap_cursor = False\n\n        move_col_start = u'%dl' % (col_start - 1) if (col_start - 1) > 0 and (col_start - 1) < 2000000000 else u''\n        move_col_end = u'%dl' % (col_end - 1) if (col_end - 1) > 0 and (col_end - 1) < 2000000000 else u''\n        swap = u'o' if swap_cursor else u''\n\n        vim.command(u_encode(u'normal! %dgg%s%s%dgg%s%s' % (line_start, move_col_start, vim.eval(u_encode(u'visualmode()')), line_end, move_col_end, swap)))\n\n    @classmethod\n    def _focus_heading(cls, mode, direction=Direction.FORWARD, skip_children=False):\n        u\"\"\"\n        Focus next or previous heading in the given direction\n\n        :direction: True for next heading, False for previous heading\n        :returns: next heading or None\n        \"\"\"\n        d = ORGMODE.get_document()\n        current_heading = d.current_heading()\n        heading = current_heading\n        focus_heading = None\n        # FIXME this is just a piece of really ugly and unmaintainable code. It\n        # should be rewritten\n        if not heading:\n            if direction == Direction.FORWARD and d.headings \\\n                and vim.current.window.cursor[0] < d.headings[0].start_vim:\n                # the cursor is in the meta information are, therefore focus\n                # first heading\n                focus_heading = d.headings[0]\n            if not (heading or focus_heading):\n                if mode == u'visual':\n                    # restore visual selection when no heading was found\n                    vim.command(u_encode(u'normal! gv'))\n                else:\n                    echo(u'No heading found')\n                return\n        elif direction == Direction.BACKWARD:\n            if vim.current.window.cursor[0] != heading.start_vim:\n                # the cursor is in the body of the current heading, therefore\n                # the current heading will be focused\n                if mode == u'visual':\n                    line_start, col_start = [int(i) for i in\n                              vim.eval(u_encode(u'getpos(\"\\'<\")'))[1:3]]\n                    line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos(\"\\'>\")'))[1:3]]\n                    if line_start >= heading.start_vim and line_end > heading.start_vim:\n                        focus_heading = heading\n                else:\n                    focus_heading = heading\n\n        # so far no heading has been found that the next focus should be on\n        if not focus_heading:\n            if not skip_children and direction == Direction.FORWARD and heading.children:\n                focus_heading = heading.children[0]\n            elif direction == Direction.FORWARD and heading.next_sibling:\n                focus_heading = heading.next_sibling\n            elif direction == Direction.BACKWARD and heading.previous_sibling:\n                focus_heading = heading.previous_sibling\n                if not skip_children:\n                    while focus_heading.children:\n                        focus_heading = focus_heading.children[-1]\n            else:\n                if direction == Direction.FORWARD:\n                    focus_heading = current_heading.next_heading\n                else:\n                    focus_heading = current_heading.previous_heading\n\n        noheadingfound = False\n        if not focus_heading:\n            if mode in (u'visual', u'operator'):\n                # the cursor seems to be on the last or first heading of this\n                # document and performs another next/previous operation\n                focus_heading = heading\n                noheadingfound = True\n            else:\n                if direction == Direction.FORWARD:\n                    echo(u'Already focussing last heading')\n                else:\n                    echo(u'Already focussing first heading')\n                return\n\n        if mode == u'visual':\n            cls._change_visual_selection(current_heading, focus_heading, direction=direction, noheadingfound=noheadingfound)\n        elif mode == u'operator':\n            if direction == Direction.FORWARD and vim.current.window.cursor[0] >= focus_heading.start_vim:\n                vim.current.window.cursor = (focus_heading.end_vim, len(u_decode(vim.current.buffer[focus_heading.end])))\n            else:\n                vim.current.window.cursor = (focus_heading.start_vim, 0)\n        else:\n            vim.current.window.cursor = (focus_heading.start_vim, focus_heading.level + 1)\n        if noheadingfound:\n            return\n        return focus_heading\n\n    @classmethod\n    @apply_count\n    def previous(cls, mode, skip_children=False):\n        u\"\"\"\n        Focus previous heading\n        \"\"\"\n        return cls._focus_heading(mode, direction=Direction.BACKWARD, skip_children=skip_children)\n\n    @classmethod\n    @apply_count\n    def next(cls, mode, skip_children=False):\n        u\"\"\"\n        Focus next heading\n        \"\"\"\n        return cls._focus_heading(mode, direction=Direction.FORWARD, skip_children=skip_children)\n\n    def register(self):\n        # normal mode\n        self.keybindings.append(Keybinding(u'g{', Plug('OrgJumpToParentNormal',\n                                                 u'%s ORGMODE.plugins[u\"Navigator\"].parent(mode=u\"normal\")<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Up', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'g}',\n                                     Plug('OrgJumpToParentsSiblingNormal', u'%s ORGMODE.plugins[u\"Navigator\"].parent_next_sibling(mode=u\"normal\")<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Down', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'{',\n                                     Plug(u'OrgJumpToPreviousNormal', u'%s ORGMODE.plugins[u\"Navigator\"].previous(mode=u\"normal\")<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Previous', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u'}', Plug(u'OrgJumpToNextNormal',\n                                                u'%s ORGMODE.plugins[u\"Navigator\"].next(mode=u\"normal\")<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Next', self.keybindings[-1])\n\n        # visual mode\n        self.keybindings.append(Keybinding(u'g{', Plug(u'OrgJumpToParentVisual', u'<Esc>:<C-u>%s ORGMODE.plugins[u\"Navigator\"].parent(mode=u\"visual\")<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'g}', Plug('OrgJumpToParentsSiblingVisual', u'<Esc>:<C-u>%s ORGMODE.plugins[u\"Navigator\"].parent_next_sibling(mode=u\"visual\")<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'{', Plug(u'OrgJumpToPreviousVisual', u'<Esc>:<C-u>%s ORGMODE.plugins[u\"Navigator\"].previous(mode=u\"visual\")<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u'}', Plug(u'OrgJumpToNextVisual', u'<Esc>:<C-u>%s ORGMODE.plugins[u\"Navigator\"].next(mode=u\"visual\")<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n\n        # operator-pending mode\n        self.keybindings.append(Keybinding(u'g{', Plug(u'OrgJumpToParentOperator', u':<C-u>%s ORGMODE.plugins[u\"Navigator\"].parent(mode=u\"operator\")<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'g}', Plug('OrgJumpToParentsSiblingOperator', u':<C-u>%s ORGMODE.plugins[u\"Navigator\"].parent_next_sibling(mode=u\"operator\")<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'{', Plug(u'OrgJumpToPreviousOperator', u':<C-u>%s ORGMODE.plugins[u\"Navigator\"].previous(mode=u\"operator\")<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u'}', Plug(u'OrgJumpToNextOperator', u':<C-u>%s ORGMODE.plugins[u\"Navigator\"].next(mode=u\"operator\")<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n\n        # section wise movement (skip children)\n        # normal mode\n        self.keybindings.append(Keybinding(u'[[',\n                                     Plug(u'OrgJumpToPreviousSkipChildrenNormal',\n               u'%s ORGMODE.plugins[u\"Navigator\"].previous(mode=u\"normal\", skip_children=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Ne&xt Same Level', self.keybindings[-1])\n        self.keybindings.append(Keybinding(u']]',\n                                     Plug(u'OrgJumpToNextSkipChildrenNormal',\n               u'%s ORGMODE.plugins[u\"Navigator\"].next(mode=u\"normal\", skip_children=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Pre&vious Same Level', self.keybindings[-1])\n\n        # visual mode\n        self.keybindings.append(Keybinding(u'[[', Plug(u'OrgJumpToPreviousSkipChildrenVisual', u'<Esc>:<C-u>%s ORGMODE.plugins[u\"Navigator\"].previous(mode=u\"visual\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n        self.keybindings.append(Keybinding(u']]', Plug(u'OrgJumpToNextSkipChildrenVisual', u'<Esc>:<C-u>%s ORGMODE.plugins[u\"Navigator\"].next(mode=u\"visual\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_VISUAL)))\n\n        # operator-pending mode\n        self.keybindings.append(Keybinding(u'[[', Plug(u'OrgJumpToPreviousSkipChildrenOperator', u':<C-u>%s ORGMODE.plugins[u\"Navigator\"].previous(mode=u\"operator\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n        self.keybindings.append(Keybinding(u']]', Plug(u'OrgJumpToNextSkipChildrenOperator', u':<C-u>%s ORGMODE.plugins[u\"Navigator\"].next(mode=u\"operator\", skip_children=True)<CR>' % VIM_PY_CALL, mode=MODE_OPERATOR)))\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/ShowHide.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode.liborgmode.headings import Heading\nfrom orgmode._vim import ORGMODE, apply_count\nfrom orgmode import settings\nfrom orgmode.menu import Submenu, ActionEntry\nfrom orgmode.keybinding import Keybinding, Plug, MODE_NORMAL\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.xrange_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass ShowHide(object):\n    u\"\"\" Show Hide plugin \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'&Show Hide')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n    @classmethod\n    def _fold_depth(cls, h):\n        \"\"\" Find the deepest level of open folds\n\n        :h:            Heading\n        :returns:    Tuple (int - level of open folds, boolean - found fold) or None if h is not a Heading\n        \"\"\"\n        if not isinstance(h, Heading):\n            return\n\n        if int(vim.eval(u_encode(u'foldclosed(%d)' % h.start_vim))) != -1:\n            return (h.number_of_parents, True)\n\n        res = [h.number_of_parents + 1]\n        found = False\n        for c in h.children:\n            d, f = cls._fold_depth(c)\n            res.append(d)\n            found |= f\n\n        return (max(res), found)\n\n    @classmethod\n    @apply_count\n    def toggle_folding(cls, reverse=False):\n        u\"\"\" Toggle folding similar to the way orgmode does\n\n        This is just a convenience function, don't hesitate to use the z*\n        keybindings vim offers to deal with folding!\n\n        :reverse:    If False open folding by one level otherwise close it by one.\n        \"\"\"\n        d = ORGMODE.get_document()\n        heading = d.current_heading()\n        if not heading:\n            vim.eval(u_encode(u'feedkeys(\"<Tab>\", \"n\")'))\n            return\n\n        cursor = vim.current.window.cursor[:]\n\n        if int(vim.eval(u_encode(u'foldclosed(%d)' % heading.start_vim))) != -1:\n            if not reverse:\n                # open closed fold\n                p = heading.number_of_parents\n                if not p:\n                    p = heading.level\n                vim.command(u_encode(u'normal! %dzo' % p))\n            else:\n                # reverse folding opens all folds under the cursor\n                vim.command(u_encode(u'%d,%dfoldopen!' % (heading.start_vim, heading.end_of_last_child_vim)))\n            vim.current.window.cursor = cursor\n            return heading\n\n        def open_fold(h):\n            if h.number_of_parents <= open_depth:\n                vim.command(u_encode(u'normal! %dgg%dzo' % (h.start_vim, open_depth)))\n            for c in h.children:\n                open_fold(c)\n\n        def close_fold(h):\n            for c in h.children:\n                close_fold(c)\n            if h.number_of_parents >= open_depth - 1 and \\\n                int(vim.eval(u_encode(u'foldclosed(%d)' % h.start_vim))) == -1:\n                vim.command(u_encode(u'normal! %dggzc' % (h.start_vim, )))\n\n        # find deepest fold\n        open_depth, found_fold = cls._fold_depth(heading)\n\n        if not reverse:\n            # recursively open folds\n            if found_fold:\n                for child in heading.children:\n                    open_fold(child)\n            else:\n                vim.command(u_encode(u'%d,%dfoldclose!' % (heading.start_vim, heading.end_of_last_child_vim)))\n\n                if heading.number_of_parents:\n                    # restore cursor position, it might have been changed by open_fold\n                    vim.current.window.cursor = cursor\n\n                    p = heading.number_of_parents\n                    if not p:\n                        p = heading.level\n                    # reopen fold again because the former closing of the fold closed all levels, including parents!\n                    vim.command(u_encode(u'normal! %dzo' % (p, )))\n        else:\n            # close the last level of folds\n            close_fold(heading)\n\n        # restore cursor position\n        vim.current.window.cursor = cursor\n        return heading\n\n    @classmethod\n    @apply_count\n    def global_toggle_folding(cls, reverse=False):\n        \"\"\" Toggle folding globally\n\n        :reverse:    If False open folding by one level otherwise close it by one.\n        \"\"\"\n        d = ORGMODE.get_document()\n        if reverse:\n            foldlevel = int(vim.eval(u_encode(u'&foldlevel')))\n            if foldlevel == 0:\n                # open all folds because the user tries to close folds beyond 0\n                vim.eval(u_encode(u'feedkeys(\"zR\", \"n\")'))\n            else:\n                # vim can reduce the foldlevel on its own\n                vim.eval(u_encode(u'feedkeys(\"zm\", \"n\")'))\n        else:\n            found = False\n            for h in d.headings:\n                res = cls._fold_depth(h)\n                if res:\n                    found = res[1]\n                if found:\n                    break\n            if not found:\n                # no fold found and the user tries to advance the fold level\n                # beyond maximum so close everything\n                vim.eval(u_encode(u'feedkeys(\"zM\", \"n\")'))\n            else:\n                # fold found, vim can increase the foldlevel on its own\n                vim.eval(u_encode(u'feedkeys(\"zr\", \"n\")'))\n\n        return d\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n        # register plug\n\n        self.keybindings.append(Keybinding(u'<Tab>',\n                                     Plug(u'OrgToggleFoldingNormal', u'%s ORGMODE.plugins[u\"ShowHide\"].toggle_folding()<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&Cycle Visibility', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<S-Tab>',\n                                     Plug(u'OrgToggleFoldingReverse', u'%s ORGMODE.plugins[u\"ShowHide\"].toggle_folding(reverse=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Cycle Visibility &Reverse', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<localleader>.',\n                                     Plug(u'OrgGlobalToggleFoldingNormal', u'%s ORGMODE.plugins[u\"ShowHide\"].global_toggle_folding()<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Cycle Visibility &Globally', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<localleader>,',\n                                     Plug(u'OrgGlobalToggleFoldingReverse',\n               u'%s ORGMODE.plugins[u\"ShowHide\"].global_toggle_folding(reverse=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'Cycle Visibility Reverse G&lobally', self.keybindings[-1])\n\n        for i in range(0, 10):\n            self.keybindings.append(Keybinding(u'<localleader>%d' % (i, ), u'zM:set fdl=%d<CR>' % i, mode=MODE_NORMAL))\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/TagsProperties.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nfrom orgmode._vim import ORGMODE, repeat\nfrom orgmode.menu import Submenu, ActionEntry\nfrom orgmode.keybinding import Keybinding, Plug, Command\nfrom orgmode import settings\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\nclass TagsProperties(object):\n    u\"\"\" TagsProperties plugin \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'&TAGS and Properties')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n        # commands for this plugin\n        self.commands = []\n\n    @classmethod\n    def complete_tags(cls):\n        u\"\"\" build a list of tags and store it in variable b:org_tag_completion\n        \"\"\"\n        d = ORGMODE.get_document()\n        heading = d.current_heading()\n        if not heading:\n            return\n\n        leading_portion = u_decode(vim.eval(u'a:ArgLead'))\n        cursor = int(vim.eval(u'a:CursorPos'))\n\n        # extract currently completed tag\n        idx_orig = leading_portion.rfind(u':', 0, cursor)\n        if idx_orig == -1:\n            idx = 0\n        else:\n            idx = idx_orig\n\n        current_tag = leading_portion[idx: cursor].lstrip(u':')\n        head = leading_portion[:idx + 1]\n        if idx_orig == -1:\n            head = u''\n        tail = leading_portion[cursor:]\n\n        # extract all tags of the current file\n        all_tags = set()\n        for h in d.all_headings():\n            for t in h.tags:\n                all_tags.add(t)\n\n        ignorecase = bool(int(settings.get(u'org_tag_completion_ignorecase', int(vim.eval(u'&ignorecase')))))\n        possible_tags = []\n        # TODO current tags never used...\n        current_tags = heading.tags\n        for t in all_tags:\n            if ignorecase:\n                if t.lower().startswith(current_tag.lower()):\n                    possible_tags.append(t)\n            elif t.startswith(current_tag):\n                possible_tags.append(t)\n\n        vim.command(u_encode(u'let b:org_complete_tags = [%s]' % u', '.join([u'\"%s%s:%s\"' % (head, i, tail) for i in possible_tags])))\n\n    @classmethod\n    @repeat\n    def set_tags(cls):\n        u\"\"\" Set tags for current heading\n        \"\"\"\n        d = ORGMODE.get_document()\n        heading = d.current_heading()\n        if not heading:\n            return\n\n        # retrieve tags\n        res = None\n        if heading.tags:\n            res = vim.eval(u'input(\"Tags: \", \":%s:\", \"customlist,Org_complete_tags\")' % u':'.join(heading.tags))\n        else:\n            res = vim.eval(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')\n\n        if res is None:\n            # user pressed <Esc> abort any further processing\n            return\n\n        # remove empty tags\n        heading.tags = [x for x in u_decode(res).strip().strip(u':').split(u':') if x.strip() != u'']\n\n        d.write()\n\n        return u'OrgSetTags'\n\n    @classmethod\n    def find_tags(cls):\n        \"\"\" Find tags in current file\n        \"\"\"\n        tags = vim.eval(u'input(\"Find Tags: \", \"\", \"customlist,Org_complete_tags\")')\n        if tags is None:\n            # user pressed <Esc> abort any further processing\n            return\n\n        tags = [x for x in u_decode(tags).strip().strip(u':').split(u':') if x.strip() != u'']\n        if tags:\n            searchstring = u'\\\\('\n            first = True\n            for t1 in tags:\n                if first:\n                    first = False\n                    searchstring += u'%s' % t1\n                else:\n                    searchstring += u'\\\\|%s' % t1\n\n                for t2 in tags:\n                    if t1 == t2:\n                        continue\n                    searchstring += u'\\\\(:[a-zA-Z:]*\\\\)\\\\?:%s' % t2\n            searchstring += u'\\\\)'\n\n            vim.command(u'/\\\\zs:%s:\\\\ze' % searchstring)\n        return u'OrgFindTags'\n\n    @classmethod\n    def realign_tags(cls):\n        u\"\"\"\n        Updates tags when user finished editing a heading\n        \"\"\"\n        d = ORGMODE.get_document(allow_dirty=True)\n        heading = d.find_current_heading()\n        if not heading:\n            return\n\n        if vim.current.window.cursor[0] == heading.start_vim:\n            heading.set_dirty_heading()\n            d.write_heading(heading, including_children=False)\n\n    @classmethod\n    def realign_all_tags(cls):\n        u\"\"\"\n        Updates tags when user finishes editing a heading\n        \"\"\"\n        d = ORGMODE.get_document()\n        for heading in d.all_headings():\n            heading.set_dirty_heading()\n\n        d.write()\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n        # an Action menu entry which binds \"keybinding\" to action \":action\"\n        settings.set(u'org_tag_column', vim.eval(u'&textwidth'))\n        settings.set(u'org_tag_completion_ignorecase', int(vim.eval(u'&ignorecase')))\n\n        cmd = Command(\n            u'OrgSetTags',\n            u'%s ORGMODE.plugins[u\"TagsProperties\"].set_tags()' % VIM_PY_CALL)\n        self.commands.append(cmd)\n        keybinding = Keybinding(\n            u'<localleader>st',\n            Plug(u'OrgSetTags', cmd))\n        self.keybindings.append(keybinding)\n        self.menu + ActionEntry(u'Set &Tags', keybinding)\n\n        cmd = Command(\n            u'OrgFindTags',\n            u'%s ORGMODE.plugins[u\"TagsProperties\"].find_tags()' % VIM_PY_CALL)\n        self.commands.append(cmd)\n        keybinding = Keybinding(\n            u'<localleader>ft',\n            Plug(u'OrgFindTags', cmd))\n        self.keybindings.append(keybinding)\n        self.menu + ActionEntry(u'&Find Tags', keybinding)\n\n        cmd = Command(\n            u'OrgTagsRealign',\n            u\"%s ORGMODE.plugins[u'TagsProperties'].realign_all_tags()\" % VIM_PY_CALL)\n        self.commands.append(cmd)\n\n        # workaround to align tags when user is leaving insert mode\n        vim.command(u_encode(u\"function Org_complete_tags(ArgLead, CmdLine, CursorPos)\\n\"\n+ sys.executable.split('/')[-1] + u\"\"\" << EOF\nORGMODE.plugins[u'TagsProperties'].complete_tags()\nEOF\nif exists('b:org_complete_tags')\n    let tmp = b:org_complete_tags\n    unlet b:org_complete_tags\n    return tmp\nelse\n    return []\nendif\nendfunction\"\"\"))\n\n        vim.command(u_encode(u\"\"\"function Org_realign_tags_on_insert_leave()\nif !exists('b:org_complete_tag_on_insertleave_au')\n    :au orgmode InsertLeave <buffer> %s ORGMODE.plugins[u'TagsProperties'].realign_tags()\n    let b:org_complete_tag_on_insertleave_au = 1\nendif\nendfunction\"\"\" % VIM_PY_CALL))\n\n        # this is for all org files opened after this file\n        vim.command(u_encode(u\"au orgmode FileType org call Org_realign_tags_on_insert_leave()\"))\n        # this is for the current file\n        vim.command(u_encode(u\"call Org_realign_tags_on_insert_leave()\"))\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/Todo.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\nimport re\nimport itertools as it\n\nfrom orgmode._vim import echom, ORGMODE, apply_count, repeat, realign_tags\nfrom orgmode import settings\nfrom orgmode.liborgmode.base import Direction\nfrom orgmode.menu import Submenu, ActionEntry\nfrom orgmode.keybinding import Keybinding, Plug\nfrom orgmode.exceptions import PluginError\n\n# temporary todo states for different orgmode buffers\nORGTODOSTATES = {}\n\nfrom orgmode.py3compat.xrange_compatibility import *\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\nfrom orgmode.py3compat.py_py3_string import *\n\n\ndef split_access_key(t, sub=None):\n    u\"\"\" Split access key\n\n    Args:\n        t (str): Todo state\n        sub: A value that will be returned instead of access key if there was\n            not access key\n\n    Returns:\n        tuple: Todo state and access key separated (TODO, ACCESS_KEY)\n\n    Example:\n        >>> split_access_key('TODO(t)')\n        >>> ('TODO', '(t)')\n        >>> split_access_key('WANT', sub='(hi)')\n        >>> ('WANT', '(hi)')\n    \"\"\"\n    if type(t) != unicode:\n        echom(\"String must be unicode\")\n        return (None, None)\n\n    idx = t.find(u'(')\n\n    v, k = (t, sub)\n    if idx != -1 and t[idx + 1:-1]:\n        v, k = (t[:idx], t[idx + 1:-1])\n    return (v, k)\n\n\nclass Todo(object):\n    u\"\"\"\n    Todo plugin.\n\n    Description taken from orgmode.org:\n\n    You can use TODO keywords to indicate different sequential states in the\n    process of working on an item, for example:\n\n    [\"TODO\", \"FEEDBACK\", \"VERIFY\", \"|\", \"DONE\", \"DELEGATED\"]\n\n    The vertical bar separates the TODO keywords (states that need action) from\n    the DONE states (which need no further action). If you don't provide the\n    separator bar, the last state is used as the DONE state. With this setup,\n    the command ``,d`` will cycle an entry from TODO to FEEDBACK, then to\n    VERIFY, and finally to DONE and DELEGATED.\n    \"\"\"\n\n    def __init__(self):\n        u\"\"\" Initialize plugin \"\"\"\n        object.__init__(self)\n        # menu entries this plugin should create\n        self.menu = ORGMODE.orgmenu + Submenu(u'&TODO Lists')\n\n        # key bindings for this plugin\n        # key bindings are also registered through the menu so only additional\n        # bindings should be put in this variable\n        self.keybindings = []\n\n    @classmethod\n    def _process_all_states(cls, all_states):\n        u\"\"\" verify if states defined by user is valid.\n        Return cleaned_todo and flattened if is. Raise Exception if not.\n        Valid checking:\n            * no two state share a same name\n        \"\"\"\n        # TODO Write tests. -- Ron89\n        cleaned_todos = [[\n            split_access_key(todo)[0] for todo in it.chain.from_iterable(x)]\n            for x in all_states] + [[None]]\n\n        flattened_todos = list(it.chain.from_iterable(cleaned_todos))\n        if len(flattened_todos) != len(set(flattened_todos)):\n            raise PluginError(u\"Duplicate names detected in TODO keyword list. Please examine `g/b:org_todo_keywords`\")\n        # TODO This is the case when there are 2 todo states with the same\n        # name. It should be handled by making a simple class to hold TODO\n        # states, which would avoid mixing 2 todo states with the same name\n        # since they would have a different reference (but same content),\n        # albeit this can fail because python optimizes short strings (i.e.\n        # they hold the same ref) so care should be taken in implementation\n        return (cleaned_todos, flattened_todos)\n\n    @classmethod\n    def _get_next_state(\n        cls, current_state, all_states, direction=Direction.FORWARD,\n        next_set=False):\n        u\"\"\" Get the next todo state\n\n        Args:\n            current_state (str): The current todo state\n            all_states (list): A list containing all todo states within\n                sublists. The todo states may contain access keys\n            direction: Direction of state or keyword set change (forward or\n                backward)\n            next_set: Advance to the next keyword set in defined direction.\n\n        Returns:\n            str or None: next todo state, or None if there is no next state.\n\n        Note: all_states should have the form of:\n            [(['TODO(t)'], ['DONE(d)']),\n            (['REPORT(r)', 'BUG(b)', 'KNOWNCAUSE(k)'], ['FIXED(f)']),\n            ([], ['CANCELED(c)'])]\n        \"\"\"\n        cleaned_todos, flattened_todos = cls._process_all_states(all_states)\n\n        # backward direction should really be -1 not 2\n        next_dir = -1 if direction == Direction.BACKWARD else 1\n        # work only with top level index\n        if next_set:\n            top_set = next((\n                todo_set[0] for todo_set in enumerate(cleaned_todos)\n                if current_state in todo_set[1]), -1)\n            ind = (top_set + next_dir) % len(cleaned_todos)\n            if ind != len(cleaned_todos) - 1:\n                echom(\"Using set: %s\" % str(all_states[ind]))\n            else:\n                echom(\"Keyword removed.\")\n            return cleaned_todos[ind][0]\n        # No next set, cycle around everything\n        else:\n            ind = next((\n                todo_iter[0] for todo_iter in enumerate(flattened_todos)\n                if todo_iter[1] == current_state), -1)\n            return flattened_todos[(ind + next_dir) % len(flattened_todos)]\n\n    @classmethod\n    @realign_tags\n    @repeat\n    @apply_count\n    def toggle_todo_state(\n        cls, direction=Direction.FORWARD, interactive=False, next_set=False):\n        u\"\"\" Toggle state of TODO item\n\n        :returns: The changed heading\n        \"\"\"\n        d = ORGMODE.get_document(allow_dirty=True)\n\n        # get heading\n        heading = d.find_current_heading()\n        if not heading:\n            vim.eval(u'feedkeys(\"^\", \"n\")')\n            return\n\n        todo_states = d.get_todo_states(strip_access_key=False)\n        # get todo states\n        if not todo_states:\n            echom(u'No todo keywords configured.')\n            return\n\n        current_state = heading.todo\n\n        # get new state interactively\n        if interactive:\n            # determine position of the interactive prompt\n            prompt_pos = settings.get(u'org_todo_prompt_position', u'botright')\n            if prompt_pos not in [u'botright', u'topleft']:\n                prompt_pos = u'botright'\n\n            # pass todo states to new window\n            ORGTODOSTATES[d.bufnr] = todo_states\n            settings.set(\n                u'org_current_state_%d' % d.bufnr,\n                current_state if current_state is not None else u'', overwrite=True)\n            todo_buffer_exists = bool(int(vim.eval(u_encode(\n                u'bufexists(\"org:todo/%d\")' % (d.bufnr, )))))\n            if todo_buffer_exists:\n                # if the buffer already exists, reuse it\n                vim.command(u_encode(\n                    u'%s sbuffer org:todo/%d' % (prompt_pos, d.bufnr, )))\n            else:\n                # create a new window\n                vim.command(u_encode(\n                    u'keepalt %s %dsplit org:todo/%d' % (prompt_pos, len(todo_states), d.bufnr)))\n        else:\n            new_state = Todo._get_next_state(\n                current_state, todo_states, direction=direction,\n                next_set=next_set)\n\n            cls.set_todo_state(new_state)\n\n        # plug\n        plug = u'OrgTodoForward'\n        if direction == Direction.BACKWARD:\n            plug = u'OrgTodoBackward'\n\n        return plug\n\n    @classmethod\n    def set_todo_state(cls, state):\n        u\"\"\" Set todo state for buffer.\n\n        :bufnr:        Number of buffer the todo state should be updated for\n        :state:        The new todo state\n        \"\"\"\n        lineno, colno = vim.current.window.cursor\n        d = ORGMODE.get_document(allow_dirty=True)\n        heading = d.find_current_heading()\n\n        if not heading:\n            return\n\n        current_state = heading.todo\n\n        # set new headline\n        heading.todo = state\n        d.write_heading(heading)\n\n        # move cursor along with the inserted state only when current position\n        # is in the heading; otherwite do nothing\n        if heading.start_vim == lineno and colno > heading.level:\n            if current_state is not None and \\\n                colno <= heading.level + len(current_state):\n                # the cursor is actually on the todo keyword\n                # move it back to the beginning of the keyword in that case\n                vim.current.window.cursor = (lineno, heading.level + 1)\n            else:\n                # the cursor is somewhere in the text, move it along\n                if current_state is None and state is None:\n                    offset = 0\n                elif current_state is None and state is not None:\n                    offset = len(state) + 1\n                elif current_state is not None and state is None:\n                    offset = -len(current_state) - 1\n                else:\n                    offset = len(state) - len(current_state)\n                vim.current.window.cursor = (lineno, colno + offset)\n\n    @classmethod\n    def init_org_todo(cls):\n        u\"\"\" Initialize org todo selection window.\n        \"\"\"\n        bufnr = int(re.findall(r'\\d+$',vim.current.buffer.name)[0])\n        all_states = ORGTODOSTATES.get(bufnr, None)\n\n        vim_commands = [\n            u'let g:org_sav_timeoutlen=&timeoutlen',\n            u'au orgmode BufEnter <buffer> :if ! exists(\"g:org_sav_timeoutlen\")|let g:org_sav_timeoutlen=&timeoutlen|set timeoutlen=1|endif',\n            u'au orgmode BufLeave <buffer> :if exists(\"g:org_sav_timeoutlen\")|let &timeoutlen=g:org_sav_timeoutlen|unlet g:org_sav_timeoutlen|endif',\n            u'setlocal nolist tabstop=16 buftype=nofile timeout timeoutlen=1 winfixheight',\n            u'setlocal statusline=Org\\\\ todo\\\\ (%s)' % vim.eval(u_encode(u'fnameescape(fnamemodify(bufname(%d), \":t\"))' % bufnr)),\n            u'nnoremap <silent> <buffer> <Esc> :%sbw<CR>' % vim.eval(u_encode(u'bufnr(\"%\")')),\n            u'nnoremap <silent> <buffer> <CR> :let g:org_state = fnameescape(expand(\"<cword>\"))<Bar>bw<Bar>exec \"%s ORGMODE.plugins[u\\'Todo\\'].set_todo_state(\\'\".g:org_state.\"\\')\"<Bar>unlet! g:org_state<CR>' % VIM_PY_CALL,\n            ]\n        # because timeoutlen can only be set globally it needs to be stored and\n        # restored later\n        # make window a scratch window and set the statusline differently\n        for cmd in vim_commands:\n            vim.command(u_encode(cmd))\n\n        if all_states is None:\n            vim.command(u_encode(u'bw'))\n            echom(u'No todo states available for buffer %s' % vim.current.buffer.name)\n\n        for idx, state in enumerate(all_states):\n            pairs = [split_access_key(x, sub=u' ') for x in it.chain(*state)]\n            line = u'\\t'.join(u''.join((u'[%s] ' % x[1], x[0])) for x in pairs)\n            vim.current.buffer.append(u_encode(line))\n            for todo, key in pairs:\n                # FIXME if double key is used for access modified this doesn't work\n                vim.command(u_encode(u'nnoremap <silent> <buffer> %s :bw<CR><c-w><c-p>%s ORGMODE.plugins[u\"Todo\"].set_todo_state(\"%s\")<CR>' % (key, VIM_PY_CALL, u_decode(todo))))\n\n        # position the cursor of the current todo item\n        vim.command(u_encode(u'normal! G'))\n        current_state = settings.unset(u'org_current_state_%d' % bufnr)\n        if current_state is not None and current_state != '':\n            for i, buf in enumerate(vim.current.buffer):\n                idx = buf.find(current_state)\n                if idx != -1:\n                    vim.current.window.cursor = (i + 1, idx)\n                    break\n            else:\n                vim.current.window.cursor = (2, 4)\n\n        # finally make buffer non modifiable\n        vim.command(u_encode(u'setfiletype orgtodo'))\n        vim.command(u_encode(u'setlocal nomodifiable'))\n\n        # remove temporary todo states for the current buffer\n        del ORGTODOSTATES[bufnr]\n\n    def register(self):\n        u\"\"\"\n        Registration of plugin. Key bindings and other initialization should be done.\n        \"\"\"\n        self.keybindings.append(Keybinding(u'<localleader>ct', Plug(\n            u'OrgTodoToggleNonInteractive',\n            u'%s ORGMODE.plugins[u\"Todo\"].toggle_todo_state(interactive=False)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&TODO/DONE/-', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<localleader>d', Plug(\n            u'OrgTodoToggleInteractive',\n            u'%s ORGMODE.plugins[u\"Todo\"].toggle_todo_state(interactive=True)<CR>' % VIM_PY_CALL)))\n        self.menu + ActionEntry(u'&TODO/DONE/- (interactive)', self.keybindings[-1])\n\n        # add submenu\n        submenu = self.menu + Submenu(u'Select &keyword')\n\n        self.keybindings.append(Keybinding(u'<S-Right>', Plug(\n            u'OrgTodoForward',\n            u'%s ORGMODE.plugins[u\"Todo\"].toggle_todo_state()<CR>' % VIM_PY_CALL)))\n        submenu + ActionEntry(u'&Next keyword', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<S-Left>', Plug(\n            u'OrgTodoBackward',\n            u'%s ORGMODE.plugins[u\"Todo\"].toggle_todo_state(direction=2)<CR>' % VIM_PY_CALL)))\n        submenu + ActionEntry(u'&Previous keyword', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<C-S-Right>', Plug(\n            u'OrgTodoSetForward',\n            u'%s ORGMODE.plugins[u\"Todo\"].toggle_todo_state(next_set=True)<CR>' % VIM_PY_CALL)))\n        submenu + ActionEntry(u'Next keyword &set', self.keybindings[-1])\n\n        self.keybindings.append(Keybinding(u'<C-S-Left>', Plug(\n            u'OrgTodoSetBackward',\n            u'%s ORGMODE.plugins[u\"Todo\"].toggle_todo_state(direction=2, next_set=True)<CR>' % VIM_PY_CALL)))\n        submenu + ActionEntry(u'Previous &keyword set', self.keybindings[-1])\n\n        settings.set(u'org_todo_keywords', [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')])\n\n        settings.set(u'org_todo_prompt_position', u'botright')\n\n        vim.command(u_encode(u'au orgmode BufReadCmd org:todo/* %s ORGMODE.plugins[u\"Todo\"].init_org_todo()' % VIM_PY_CALL))\n"
  },
  {
    "path": "ftplugin/orgmode/plugins/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "ftplugin/orgmode/py3compat/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "ftplugin/orgmode/py3compat/encode_compatibility.py",
    "content": "import sys\nif sys.version_info < (3,):\n    def u_encode(string):\n        return string.encode('utf8')\n    def u_decode(string):\n        return string.decode('utf8')\nelse:\n    def u_encode(string):\n        return string\n    def u_decode(string):\n        return string\n"
  },
  {
    "path": "ftplugin/orgmode/py3compat/py_py3_string.py",
    "content": "import sys\nfrom string import Formatter\n\n\nif sys.version_info < (3,):\n    VIM_PY_CALL = u':py'\nelse:\n    VIM_PY_CALL = u':py3'\n\n\nclass NoneAsEmptyFormatter(Formatter):\n    def get_value(self, key, args, kwargs):\n        v = super().get_value(key, args, kwargs)\n        return '' if v is None else v\n\n\nfmt = NoneAsEmptyFormatter()\n"
  },
  {
    "path": "ftplugin/orgmode/py3compat/unicode_compatibility.py",
    "content": "try:\n    unicode\nexcept NameError:\n    basestring = unicode = str\n"
  },
  {
    "path": "ftplugin/orgmode/py3compat/xrange_compatibility.py",
    "content": "try:\n    from __builtin__ import xrange as range\nexcept:\n    pass\n"
  },
  {
    "path": "ftplugin/orgmode/settings.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport vim\n\nimport sys\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\nSCOPE_ALL = 1\n\n# for all vim-orgmode buffers\nSCOPE_GLOBAL = 2\n\n# just for the current buffer - has priority before the global settings\nSCOPE_BUFFER = 4\n\nVARIABLE_LEADER = {SCOPE_GLOBAL: u'g', SCOPE_BUFFER: u'b'}\n\nu\"\"\" Evaluate and store settings \"\"\"\n\n\ndef get(setting, default=None, scope=SCOPE_ALL):\n    u\"\"\" Evaluate setting in scope of the current buffer,\n    globally and also from the contents of the current buffer\n\n    WARNING: Only string values are converted to unicode. If a different value\n    is received, e.g. a list or dict, no conversion is done.\n\n    :setting: name of the variable to evaluate\n    :default: default value in case the variable is empty\n\n    :returns: variable value\n    \"\"\"\n    # TODO first read setting from org file which take precedence over vim\n    # variable settings\n    if (scope & SCOPE_ALL | SCOPE_BUFFER) and \\\n            int(vim.eval(u_encode(u'exists(\"b:%s\")' % setting))):\n        res = vim.eval(u_encode(u\"b:%s\" % setting))\n        if type(res) in (unicode, str):\n            return u_decode(res)\n        return res\n\n    elif (scope & SCOPE_ALL | SCOPE_GLOBAL) and \\\n            int(vim.eval(u_encode(u'exists(\"g:%s\")' % setting))):\n        res = vim.eval(u_encode(u\"g:%s\" % setting))\n        if type(res) in (unicode, str):\n            return u_decode(res)\n        return res\n    return default\n\n\ndef set(setting, value, scope=SCOPE_GLOBAL, overwrite=False):\n    u\"\"\" Store setting in the defined scope\n\n    WARNING: For the return value, only string are converted to unicode. If a\n    different value is received by vim.eval, e.g. a list or dict, no conversion\n    is done.\n\n    :setting:   name of the setting\n    :value:     the actual value, repr is called on the value to create a string\n                representation\n    :scope:     the scope o the setting/variable\n    :overwrite: overwrite existing settings (probably user defined settings)\n\n    :returns: the new value in case of overwrite==False the current value\n    \"\"\"\n    if (not overwrite) and (\n            int(vim.eval(u_encode(u'exists(\"%s:%s\")' % \\\n            (VARIABLE_LEADER[scope], setting))))):\n        res = vim.eval(\n                u_encode(u'%s:%s' % (VARIABLE_LEADER[scope], setting)))\n        if type(res) in (unicode, str):\n            return u_decode(res)\n        return res\n    v = repr(value)\n    if type(value) == unicode and sys.version_info < (3,):\n        # strip leading u of unicode string representations\n        v = v[1:]\n\n    cmd = u'let %s:%s = %s' % (VARIABLE_LEADER[scope], setting, v)\n    vim.command(u_encode(cmd))\n    return value\n\n\ndef unset(setting, scope=SCOPE_GLOBAL):\n    u\"\"\" Unset setting in the defined scope\n    :setting: name of the setting\n    :scope:   the scope o the setting/variable\n\n    :returns: last value of setting\n    \"\"\"\n    value = get(setting, scope=scope)\n    cmd = u'unlet! %s:%s' % (VARIABLE_LEADER[scope], setting)\n    vim.command(u_encode(cmd))\n    return value\n"
  },
  {
    "path": "ftplugin/orgmode/vimbuffer.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\n    vimbuffer\n    ~~~~~~~~~~\n\n    VimBuffer and VimBufferContent are the interface between liborgmode and\n    vim.\n\n    VimBuffer extends the liborgmode.document.Document().\n    Document() is just a general implementation for loading an org file. It\n    has no interface to an actual file or vim buffer. This is the task of\n    vimbuffer.VimBuffer(). It is the interfaces to vim. The main tasks for\n    VimBuffer are to provide read and write access to a real vim buffer.\n\n    VimBufferContent is a helper class for VimBuffer. Basically, it hides the\n    details of encoding - everything read from or written to VimBufferContent\n    is UTF-8.\n\"\"\"\n\ntry:\n    from collections import UserList\nexcept:\n    from UserList import UserList\n\nimport vim\n\nfrom orgmode import settings\nfrom orgmode.exceptions import BufferNotFound, BufferNotInSync\nfrom orgmode.liborgmode.documents import Document, MultiPurposeList, Direction\nfrom orgmode.liborgmode.headings import Heading\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\n\nclass VimBuffer(Document):\n    def __init__(self, bufnr=0):\n        u\"\"\"\n        :bufnr:        0: current buffer, every other number refers to another buffer\n        \"\"\"\n        Document.__init__(self)\n        self._bufnr          = vim.current.buffer.number if bufnr == 0 else bufnr\n        self._changedtick    = -1\n        self._cached_heading = None\n        if self._bufnr == vim.current.buffer.number:\n            self._content = VimBufferContent(vim.current.buffer)\n        else:\n            _buffer = None\n            for b in vim.buffers:\n                if self._bufnr == b.number:\n                    _buffer = b\n                    break\n\n            if not _buffer:\n                raise BufferNotFound(u'Unable to locate buffer number #%d' % self._bufnr)\n            self._content = VimBufferContent(_buffer)\n\n        self.update_changedtick()\n        self._orig_changedtick = self._changedtick\n\n    @property\n    def tabstop(self):\n        return int(vim.eval(u_encode(u'&ts')))\n\n    @property\n    def tag_column(self):\n        return int(settings.get(u'org_tag_column', u'77'))\n\n    @property\n    def is_insync(self):\n        if self._changedtick == self._orig_changedtick:\n            self.update_changedtick()\n        return self._changedtick == self._orig_changedtick\n\n    @property\n    def bufnr(self):\n        u\"\"\"\n        :returns:    The buffer's number for the current document\n        \"\"\"\n        return self._bufnr\n\n    @property\n    def changedtick(self):\n        u\"\"\" Number of changes in vimbuffer \"\"\"\n        return self._changedtick\n\n    @changedtick.setter\n    def changedtick(self, value):\n        self._changedtick = value\n\n    def get_todo_states(self, strip_access_key=True):\n        u\"\"\" Returns a list containing a tuple of two lists of allowed todo\n        states split by todo and done states. Multiple todo-done state\n        sequences can be defined.\n\n        :returns:    [([todo states], [done states]), ..]\n        \"\"\"\n        states = settings.get(u'org_todo_keywords', [])\n        # TODO this function gets called too many times when change of state of\n        # one todo is triggered, check with:\n        # print(states)\n        # this should be changed by saving todo states into some var and only\n        # if new states are set hook should be called to register them again\n        # into a property\n        # TODO move this to documents.py, it is all tangled up like this, no\n        # structure...\n        if type(states) not in (list, tuple):\n            return []\n\n        def parse_states(s, stop=0):\n            res = []\n            if not s:\n                return res\n            if type(s[0]) in (unicode, str):\n                r = []\n                for i in s:\n                    _i = i\n                    if type(_i) == str:\n                        _i = u_decode(_i)\n                    if type(_i) == unicode and _i:\n                        if strip_access_key and u'(' in _i:\n                            _i = _i[:_i.index(u'(')]\n                            if _i:\n                                r.append(_i)\n                        else:\n                            r.append(_i)\n                if not u'|' in r:\n                    if not stop:\n                        res.append((r[:-1], [r[-1]]))\n                    else:\n                        res = (r[:-1], [r[-1]])\n                else:\n                    seperator_pos = r.index(u'|')\n                    if not stop:\n                        res.append((r[0:seperator_pos], r[seperator_pos + 1:]))\n                    else:\n                        res = (r[0:seperator_pos], r[seperator_pos + 1:])\n            elif type(s) in (list, tuple) and not stop:\n                for i in s:\n                    r = parse_states(i, stop=1)\n                    if r:\n                        res.append(r)\n            return res\n\n        return parse_states(states)\n\n    def update_changedtick(self):\n        if self.bufnr == vim.current.buffer.number:\n            self._changedtick = int(vim.eval(u_encode(u'b:changedtick')))\n        else:\n            vim.command(u_encode(u'unlet! g:org_changedtick | let g:org_lz = &lz | let g:org_hidden = &hidden | set lz hidden'))\n            # TODO is this likely to fail? maybe some error hangling should be added\n            vim.command(u_encode(u'keepalt buffer %d | let g:org_changedtick = b:changedtick | buffer %d' % \\\n                    (self.bufnr, vim.current.buffer.number)))\n            vim.command(u_encode(u'let &lz = g:org_lz | let &hidden = g:org_hidden | unlet! g:org_lz g:org_hidden | redraw'))\n            self._changedtick = int(vim.eval(u_encode(u'g:org_changedtick')))\n\n    def write(self):\n        u\"\"\" write the changes to the vim buffer\n\n        :returns:    True if something was written, otherwise False\n        \"\"\"\n        if not self.is_dirty:\n            return False\n\n        self.update_changedtick()\n        if not self.is_insync:\n            raise BufferNotInSync(u'Buffer is not in sync with vim!')\n\n        # write meta information\n        if self.is_dirty_meta_information:\n            meta_end = 0 if self._orig_meta_information_len is None else self._orig_meta_information_len\n            self._content[:meta_end] = self.meta_information\n            self._orig_meta_information_len = len(self.meta_information)\n\n        # remove deleted headings\n        already_deleted = []\n        for h in sorted(self._deleted_headings, key=lambda x: x._orig_start, reverse=True):\n            if h._orig_start is not None and h._orig_start not in already_deleted:\n                # this is a heading that actually exists on the buffer and it\n                # needs to be removed\n                del self._content[h._orig_start:h._orig_start + h._orig_len]\n                already_deleted.append(h._orig_start)\n        del self._deleted_headings[:]\n        del already_deleted\n\n        # update changed headings and add new headings\n        for h in self.all_headings():\n            if h.is_dirty:\n                vim.current.buffer.append(\"\") # workaround for neovim bug\n                if h._orig_start is not None:\n                    # this is a heading that existed before and was changed. It\n                    # needs to be replaced\n                    if h.is_dirty_heading:\n                        self._content[h.start:h.start + 1] = [unicode(h)]\n                    if h.is_dirty_body:\n                        self._content[h.start + 1:h.start + h._orig_len] = h.body\n                else:\n                    # this is a new heading. It needs to be inserted\n                    self._content[h.start:h.start] = [unicode(h)] + h.body\n                del vim.current.buffer[-1] # restore workaround for neovim bug\n                h._dirty_heading = False\n                h._dirty_body = False\n            # for all headings the length and start offset needs to be updated\n            h._orig_start = h.start\n            h._orig_len = len(h)\n\n        self._dirty_meta_information = False\n        self._dirty_document = False\n\n        self.update_changedtick()\n        self._orig_changedtick = self._changedtick\n        return True\n\n    def write_heading(self, heading, including_children=True):\n        \"\"\" WARNING: use this function only when you know what you are doing!\n        This function writes a heading to the vim buffer. It offers performance\n        advantages over the regular write() function. This advantage is\n        combined with no sanity checks! Whenever you use this function, make\n        sure the heading you are writing contains the right offsets\n        (Heading._orig_start, Heading._orig_len).\n\n        Usage example:\n            # Retrieve a potentially dirty document\n            d = ORGMODE.get_document(allow_dirty=True)\n            # Don't rely on the DOM, retrieve the heading afresh\n            h = d.find_heading(direction=Direction.FORWARD, position=100)\n            # Update tags\n            h.tags = ['tag1', 'tag2']\n            # Write the heading\n            d.write_heading(h)\n\n        This function can't be used to delete a heading!\n\n        :heading:                Write this heading with to the vim buffer\n        :including_children:    Also include children in the update\n\n        :returns                The written heading\n        \"\"\"\n        if including_children and heading.children:\n            for child in heading.children[::-1]:\n                self.write_heading(child, including_children)\n\n        if heading.is_dirty:\n            if heading._orig_start is not None:\n                # this is a heading that existed before and was changed. It\n                # needs to be replaced\n                if heading.is_dirty_heading:\n                    self._content[heading._orig_start:heading._orig_start + 1] = [unicode(heading)]\n                if heading.is_dirty_body:\n                    self._content[heading._orig_start + 1:heading._orig_start + heading._orig_len] = heading.body\n            else:\n                # this is a new heading. It needs to be inserted\n                raise ValueError('Heading must contain the attribute _orig_start! %s' % heading)\n            heading._dirty_heading = False\n            heading._dirty_body = False\n        # for all headings the length offset needs to be updated\n        heading._orig_len = len(heading)\n\n        return heading\n\n    def write_checkbox(self, checkbox, including_children=True):\n        if including_children and checkbox.children:\n            for child in checkbox.children[::-1]:\n                self.write_checkbox(child, including_children)\n\n        if checkbox.is_dirty:\n            if checkbox._orig_start is not None:\n                # this is a heading that existed before and was changed. It\n                # needs to be replaced\n                # print \"checkbox is dirty? \" + str(checkbox.is_dirty_checkbox)\n                # print checkbox\n                if checkbox.is_dirty_checkbox:\n                    self._content[checkbox._orig_start:checkbox._orig_start + 1] = [unicode(checkbox)]\n                if checkbox.is_dirty_body:\n                    self._content[checkbox._orig_start + 1:checkbox._orig_start + checkbox._orig_len] = checkbox.body\n            else:\n                # this is a new checkbox. It needs to be inserted\n                raise ValueError('Checkbox must contain the attribute _orig_start! %s' % checkbox)\n            checkbox._dirty_checkbox = False\n            checkbox._dirty_body = False\n        # for all headings the length offset needs to be updated\n        checkbox._orig_len = len(checkbox)\n\n        return checkbox\n\n    def write_checkboxes(self, checkboxes):\n        pass\n\n    def previous_heading(self, position=None):\n        u\"\"\" Find the next heading (search forward) and return the related object\n        :returns:    Heading object or None\n        \"\"\"\n        h = self.current_heading(position=position)\n        if h:\n            return h.previous_heading\n\n    def current_heading(self, position=None):\n        u\"\"\" Find the current heading (search backward) and return the related object\n        :returns:    Heading object or None\n        \"\"\"\n        if position is None:\n            position = vim.current.window.cursor[0] - 1\n\n        if not self.headings:\n            return\n\n        def binaryFindInDocument():\n            hi = len(self.headings)\n            lo = 0\n            while lo < hi:\n                mid = (lo+hi)//2\n                h = self.headings[mid]\n                if h.end_of_last_child < position:\n                    lo = mid + 1\n                elif h.start > position:\n                    hi = mid\n                else:\n                    return binaryFindHeading(h)\n\n        def binaryFindHeading(heading):\n            if not heading.children or heading.end >= position:\n                return heading\n\n            hi = len(heading.children)\n            lo = 0\n            while lo < hi:\n                mid = (lo+hi)//2\n                h = heading.children[mid]\n                if h.end_of_last_child < position:\n                    lo = mid + 1\n                elif h.start > position:\n                    hi = mid\n                else:\n                    return binaryFindHeading(h)\n\n        # look at the cache to find the heading\n        h_tmp = self._cached_heading\n        if h_tmp is not None:\n            if h_tmp.end_of_last_child > position and \\\n                    h_tmp.start < position:\n                if h_tmp.end < position:\n                    self._cached_heading = binaryFindHeading(h_tmp)\n                return self._cached_heading\n\n        self._cached_heading = binaryFindInDocument()\n        return self._cached_heading\n\n    def next_heading(self, position=None):\n        u\"\"\" Find the next heading (search forward) and return the related object\n        :returns:    Heading object or None\n        \"\"\"\n        h = self.current_heading(position=position)\n        if h:\n            return h.next_heading\n\n    def find_current_heading(self, position=None, heading=Heading):\n        u\"\"\" Find the next heading backwards from the position of the cursor.\n        The difference to the function current_heading is that the returned\n        object is not built into the DOM. In case the DOM doesn't exist or is\n        out of sync this function is much faster in fetching the current\n        heading.\n\n        :position:    The position to start the search from\n\n        :heading:    The base class for the returned heading\n\n        :returns:    Heading object or None\n        \"\"\"\n        return self.find_heading(vim.current.window.cursor[0] - 1 \\\n                if position is None else position, \\\n                direction=Direction.BACKWARD, heading=heading, \\\n                connect_with_document=False)\n\n\nclass VimBufferContent(MultiPurposeList):\n    u\"\"\" Vim Buffer Content is a UTF-8 wrapper around a vim buffer. When\n    retrieving or setting items in the buffer an automatic conversion is\n    performed.\n\n    This ensures UTF-8 usage on the side of liborgmode and the vim plugin\n    vim-orgmode.\n    \"\"\"\n\n    def __init__(self, vimbuffer, on_change=None):\n        MultiPurposeList.__init__(self, on_change=on_change)\n\n        # replace data with vimbuffer to make operations change the actual\n        # buffer\n        self.data = vimbuffer\n\n    def __contains__(self, item):\n        i = item\n        if type(i) is unicode:\n            i = u_encode(item)\n        return MultiPurposeList.__contains__(self, i)\n\n    def __getitem__(self, i):\n        if isinstance(i, slice):\n            return [u_decode(item) if type(item) is str else item \\\n                    for item in MultiPurposeList.__getitem__(self, i)]\n        else:\n            item = MultiPurposeList.__getitem__(self, i)\n            if type(item) is str:\n                return u_decode(item)\n            return item\n\n    def __setitem__(self, i, item):\n        if isinstance(i, slice):\n            o = []\n            o_tmp = item\n            if type(o_tmp) not in (list, tuple) and not isinstance(o_tmp, UserList):\n                o_tmp = list(o_tmp)\n            for item in o_tmp:\n                if type(item) == unicode:\n                    o.append(u_encode(item))\n                else:\n                    o.append(item)\n            MultiPurposeList.__setitem__(self, i, o)\n        else:\n            _i = item\n            if type(_i) is unicode:\n                _i = u_encode(item)\n\n            # TODO: fix this bug properly, it is really strange that it fails on\n            # python3 without it. Problem is that when _i = ['* '] it fails in\n            # UserList.__setitem__() but if it is changed in debuggr in __setitem__\n            # like item[0] = '* ' it works, hence this is some quirk with unicode\n            # stuff but very likely vim 7.4 BUG too.\n            if isinstance(_i, UserList) and sys.version_info > (3, ):\n                _i = [s.encode('utf8').decode('utf8') for s in _i]\n\n            MultiPurposeList.__setitem__(self, i, _i)\n\n    def __add__(self, other):\n        raise NotImplementedError()\n        # TODO: implement me\n        if isinstance(other, UserList):\n            return self.__class__(self.data + other.data)\n        elif isinstance(other, type(self.data)):\n            return self.__class__(self.data + other)\n        else:\n            return self.__class__(self.data + list(other))\n\n    def __radd__(self, other):\n        raise NotImplementedError()\n        # TODO: implement me\n        if isinstance(other, UserList):\n            return self.__class__(other.data + self.data)\n        elif isinstance(other, type(self.data)):\n            return self.__class__(other + self.data)\n        else:\n            return self.__class__(list(other) + self.data)\n\n    def __iadd__(self, other):\n        o = []\n        o_tmp = other\n        if type(o_tmp) not in (list, tuple) and not isinstance(o_tmp, UserList):\n            o_tmp = list(o_tmp)\n        for i in o_tmp:\n            if type(i) is unicode:\n                o.append(u_encode(i))\n            else:\n                o.append(i)\n\n        return MultiPurposeList.__iadd__(self, o)\n\n    def append(self, item):\n        i = item\n        if type(item) is str:\n            i = u_encode(item)\n        MultiPurposeList.append(self, i)\n\n    def insert(self, i, item):\n        _i = item\n        if type(_i) is str:\n            _i = u_encode(item)\n        MultiPurposeList.insert(self, i, _i)\n\n    def index(self, item, *args):\n        i = item\n        if type(i) is unicode:\n            i = u_encode(item)\n        MultiPurposeList.index(self, i, *args)\n\n    def pop(self, i=-1):\n        return u_decode(MultiPurposeList.pop(self, i))\n\n    def extend(self, other):\n        o = []\n        o_tmp = other\n        if type(o_tmp) not in (list, tuple) and not isinstance(o_tmp, UserList):\n            o_tmp = list(o_tmp)\n        for i in o_tmp:\n            if type(i) is unicode:\n                o.append(u_encode(i))\n            else:\n                o.append(i)\n        MultiPurposeList.extend(self, o)\n"
  },
  {
    "path": "indent/org.vim",
    "content": "\" Delete the next line to avoid the special indention of items\nif !exists(\"g:org_indent\")\n  let g:org_indent = 0\nendif\n\nsetlocal foldtext=GetOrgFoldtext()\nsetlocal fillchars-=fold:-\nsetlocal fillchars+=fold:\\ \nsetlocal foldexpr=GetOrgFolding()\nsetlocal foldmethod=expr\nsetlocal indentexpr=GetOrgIndent()\nsetlocal nolisp\nsetlocal nosmartindent\nsetlocal autoindent\n\nif has('python3')\n\tlet s:py_env = 'python3 << EOF'\nelse\n\tlet s:py_env = 'python << EOF'\nendif\n\nfunction! GetOrgIndent()\n\tif g:org_indent == 0\n\t\treturn -1\n\tendif\n\nexe s:py_env\nfrom orgmode._vim import indent_orgmode\nindent_orgmode()\nEOF\n\n\tif exists('b:indent_level')\n\t\tlet l:tmp = b:indent_level\n\t\tunlet b:indent_level\n\t\treturn l:tmp\n\telse\n\t\treturn -1\n\tendif\nendfunction\n\nfunction! GetOrgFolding()\n\tlet l:mode = mode()\n\tif l:mode == 'i'\n\t\t\" the cache size is limited to 3, because vim queries the current and\n\t\t\" both surrounding lines when the user is typing in insert mode. The\n\t\t\" cache is shared between GetOrgFolding and GetOrgFoldtext\n\t\tif ! exists('b:org_folding_cache')\n\t\t\tlet b:org_folding_cache = {}\n\t\tendif\n\n\t\tif has_key(b:org_folding_cache, v:lnum)\n\t\t\tif match(b:org_folding_cache[v:lnum], '^>') == 0 &&\n\t\t\t\t\t\t\\ match(getline(v:lnum), '^\\*\\+\\s') != 0\n\t\t\t\t\" when the user pastes text or presses enter, it happens that\n\t\t\t\t\" the cache starts to confuse vim's folding abilities\n\t\t\t\t\" these entries can safely be removed\n\t\t\t\tunlet b:org_folding_cache[v:lnum]\n\n\t\t\t\t\" the fold text cache is probably also damaged, delete it as\n\t\t\t\t\" well\n\t\t\t\tunlet! b:org_foldtext_cache\n\t\t\telse\n\t\t\t\treturn b:org_folding_cache[v:lnum]\n\t\t\tendif\n\t\tendif\n\n\t\texe s:py_env\nfrom orgmode._vim import fold_orgmode\nfold_orgmode(allow_dirty=True)\nEOF\n\telse\n\n\t\texe s:py_env\nfrom orgmode._vim import fold_orgmode\nfold_orgmode()\nEOF\n\tendif\n\n\tif exists('b:fold_expr')\n\t\tlet l:tmp = b:fold_expr\n\t\tunlet b:fold_expr\n\t\tif l:mode == 'i'\n\t\t\tif ! has_key(b:org_folding_cache, v:lnum)\n\t\t\t\tif len(b:org_folding_cache) > 3\n\t\t\t\t\tlet b:org_folding_cache = {}\n\t\t\t\tendif\n\t\t\t\tlet b:org_folding_cache[v:lnum] = l:tmp\n\t\t\tendif\n\t\tendif\n\t\treturn l:tmp\n\telse\n\t\treturn -1\n\tendif\nendfunction\n\nfunction! SetOrgFoldtext(text)\n\tlet b:foldtext = a:text\nendfunction\n\nfunction! GetOrgFoldtext()\n\tlet l:mode = mode()\n\tif l:mode == 'i'\n\t\t\" add a separate cache for fold text\n\t\tif ! exists('b:org_foldtext_cache') ||\n\t\t\t\t\t\\ ! has_key(b:org_foldtext_cache, 'timestamp') ||\n\t\t\t\t\t\\ b:org_foldtext_cache['timestamp'] > (localtime() + 10)\n\t\t\tlet b:org_foldtext_cache = {'timestamp': localtime()}\n\t\tendif\n\n\t\tif has_key(b:org_foldtext_cache, v:foldstart)\n\t\t\treturn b:org_foldtext_cache[v:foldstart]\n\t\tendif\n\t\texe s:py_env\nfrom orgmode._vim import fold_text\nfold_text(allow_dirty=True)\nEOF\n\telse\n\t\tunlet! b:org_foldtext_cache\n\t\texec s:py_env\nfrom orgmode._vim import fold_text\nfold_text()\nEOF\n\tendif\n\n\tif exists('b:foldtext')\n\t\tlet l:tmp = b:foldtext\n\t\tunlet b:foldtext\n\t\tif l:mode == 'i'\n\t\t\tlet b:org_foldtext_cache[v:foldstart] = l:tmp\n\t\tendif\n\t\treturn l:tmp\n\tendif\nendfunction\n"
  },
  {
    "path": "syntax/org.vim",
    "content": "if exists(\"b:current_syntax\")\n    finish\nendif\n\n\" Support org authoring markup as closely as possible\n\" (we're adding two markdown-like variants for =code= and blockquotes)\n\" -----------------------------------------------------------------------------\n\"\n\" Do we use aggressive conceal?\nif exists(\"b:org_aggressive_conceal\")\n    let s:conceal_aggressively=b:org_aggressive_conceal\nelseif exists(\"g:org_aggressive_conceal\")\n    let s:conceal_aggressively=g:org_aggressive_conceal\nelse\n    let s:conceal_aggressively=0\nendif\n\n\" Inline markup {{{1\n\" *bold*, /italic/, _underline_, +strike-through+, =code=, ~verbatim~\n\" Note:\n\" - /italic/ is rendered as reverse in most terms (works fine in gVim, though)\n\" - the non-standard `code' markup is also supported\n\" - =code= and ~verbatim~ are also supported as block-level markup, see below.\n\" Ref: http://orgmode.org/manual/Emphasis-and-monospace.html\n\"syntax match org_bold /\\*[^ ]*\\*/\n\n\" FIXME: Always make org_bold syntax define before org_heading syntax\n\"        to make sure that org_heading syntax got higher priority(help :syn-priority) than org_bold.\n\"        If there is any other good solution, please help fix it.\n\"  \\\\\\\\*sinuate*\nif (s:conceal_aggressively == 1)\n   syntax region org_bold      matchgroup=org_border_bold start=\"[^ \\\\]\\zs\\*\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs\\*\\|\\(^\\|[^\\\\]\\)\\@<=\\*\\S\\@=\"     end=\"[^ \\\\]\\zs\\*\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs\\*\\|[^\\\\]\\zs\\*\\S\\@=\"  concealends oneline\n   syntax region org_italic    matchgroup=org_border_ital start=\"[^ \\\\]\\zs\\/\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs\\/\\|\\(^\\|[^\\\\]\\)\\@<=\\/\\S\\@=\"     end=\"[^ \\\\]\\zs\\/\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs\\/\\|[^\\\\]\\zs\\/\\S\\@=\"  concealends oneline\n   syntax region org_underline matchgroup=org_border_undl start=\"[^ \\\\]\\zs_\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs_\\|\\(^\\|[^\\\\]\\)\\@<=_\\S\\@=\"        end=\"[^ \\\\]\\zs_\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs_\\|[^\\\\]\\zs_\\S\\@=\"     concealends oneline\n   syntax region org_code      matchgroup=org_border_code start=\"[^ \\\\]\\zs=\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs=\\|\\(^\\|[^\\\\]\\)\\@<==\\S\\@=\"        end=\"[^ \\\\]\\zs=\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs=\\|[^\\\\]\\zs=\\S\\@=\"     concealends oneline\n   syntax region org_code      matchgroup=org_border_code start=\"[^ \\\\]\\zs`\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs`\\|\\(^\\|[^\\\\]\\)\\@<=`\\S\\@=\"        end=\"[^ \\\\]\\zs'\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs'\\|[^\\\\]\\zs'\\S\\@=\"     concealends oneline\n   syntax region org_verbatim  matchgroup=org_border_verb start=\"[^ \\\\]\\zs\\~\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs\\~\\|\\(^\\|[^\\\\]\\)\\@<=\\~\\S\\@=\"     end=\"[^ \\\\]\\zs\\~\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs\\~\\|[^\\\\]\\zs\\~\\S\\@=\"  concealends oneline\n   syntax region org_strikethrough  matchgroup=org_border_strike start=\"[^ \\\\]\\zs+\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs+\\|\\(^\\|[^\\\\]\\)\\@<=+\\S\\@=\"     end=\"[^ \\\\]\\zs+\\|\\(\\(^\\|[^\\\\]\\)\\zs\\(\\\\\\\\\\)\\+\\)\\zs+\\|[^\\\\]\\zs+\\S\\@=\"  concealends oneline\nelse\n    syntax region org_bold      start=\"\\S\\zs\\*\\|\\*\\S\\@=\"     end=\"\\S\\zs\\*\\|\\*\\S\\@=\"  keepend oneline\n    syntax region org_italic    start=\"\\S\\zs\\/\\|\\/\\S\\@=\"     end=\"\\S\\zs\\/\\|\\/\\S\\@=\"  keepend oneline\n    syntax region org_underline start=\"\\S\\zs_\\|_\\S\\@=\"       end=\"\\S\\zs_\\|_\\S\\@=\"    keepend oneline\n    syntax region org_code      start=\"\\S\\zs=\\|=\\S\\@=\"       end=\"\\S\\zs=\\|=\\S\\@=\"    keepend oneline\n    syntax region org_code      start=\"\\S\\zs`\\|`\\S\\@=\"       end=\"\\S\\zs'\\|'\\S\\@=\"    keepend oneline\n    syntax region org_verbatim  start=\"\\S\\zs\\~\\|\\~\\S\\@=\"     end=\"\\S\\zs\\~\\|\\~\\S\\@=\"  keepend oneline\n    syntax region org_strikethrough  start=\"\\S\\zs+\\|+\\S\\@=\"     end=\"\\S\\zs+\\|+\\S\\@=\"  keepend oneline\nendif\n\nhi def org_bold      term=bold      cterm=bold      gui=bold\nhi def org_italic    term=italic    cterm=italic    gui=italic\nhi def org_underline term=underline cterm=underline gui=underline\nhi def org_strikethrough term=strikethrough cterm=strikethrough gui=strikethrough\n\nif (s:conceal_aggressively == 1)\n    hi link org_border_bold org_bold\n    hi link org_border_ital org_italic\n    hi link org_border_undl org_underline\nendif\n\n\" Headings: {{{1\n\" Load Settings: {{{2\nif !exists('g:org_heading_highlight_colors')\n\tlet g:org_heading_highlight_colors = ['Title', 'Constant', 'Identifier', 'Statement', 'PreProc', 'Type', 'Special']\nendif\n\nif !exists('g:org_heading_highlight_levels')\n\tlet g:org_heading_highlight_levels = len(g:org_heading_highlight_colors)\nendif\n\nif !exists('g:org_heading_shade_leading_stars')\n\tlet g:org_heading_shade_leading_stars = 1\nendif\n\n\" Enable Syntax HL: {{{2\nunlet! s:i s:j s:contains\nlet s:i = 1\nlet s:j = len(g:org_heading_highlight_colors)\nlet s:contains = ' contains=org_timestamp,org_timestamp_inactive,org_subtask_percent,org_subtask_number,org_subtask_percent_100,org_subtask_number_all,org_list_checkbox,org_bold,org_italic,org_underline,org_code,org_verbatim'\nif g:org_heading_shade_leading_stars == 1\n\tlet s:contains = s:contains . ',org_shade_stars'\n\tsyntax match org_shade_stars /^\\*\\{2,\\}/me=e-1 contained\n\thi def link org_shade_stars Ignore\nelse\n\thi clear org_shade_stars\nendif\n\nwhile s:i <= g:org_heading_highlight_levels\n\texec 'syntax match org_heading' . s:i . ' /^\\*\\{' . s:i . '\\}\\s.*/' . s:contains\n\texec 'hi def link org_heading' . s:i . ' ' . g:org_heading_highlight_colors[(s:i - 1) % s:j]\n\tlet s:i += 1\nendwhile\nunlet! s:i s:j s:contains\n\n\" Todo Keywords: {{{1\n\" Load Settings: {{{2\nif !exists('g:org_todo_keywords')\n\tlet g:org_todo_keywords = ['TODO', '|', 'DONE']\nendif\n\nif !exists('g:org_todo_keyword_faces')\n\tlet g:org_todo_keyword_faces = []\nendif\n\n\" Enable Syntax HL: {{{2\nlet s:todo_headings = ''\nlet s:i = 1\nwhile s:i <= g:org_heading_highlight_levels\n\tif s:todo_headings == ''\n\t\tlet s:todo_headings = 'containedin=org_heading' . s:i\n\telse\n\t\tlet s:todo_headings = s:todo_headings . ',org_heading' . s:i\n\tendif\n\tlet s:i += 1\nendwhile\nunlet! s:i\n\nif !exists('g:loaded_org_syntax')\n\tlet g:loaded_org_syntax = 1\n\n\tfunction! OrgExtendHighlightingGroup(base_group, new_group, settings)\n\t\tlet l:base_hi = ''\n\t\tredir => l:base_hi\n\t\tsilent execute 'highlight ' . a:base_group\n\t\tredir END\n\t\tlet l:group_hi = substitute(split(l:base_hi, '\\n')[0], '^' . a:base_group . '\\s\\+xxx', '', '')\n\t\texecute 'highlight ' . a:new_group . l:group_hi . ' ' . a:settings\n\tendfunction\n\n\tfunction! OrgInterpretFaces(faces)\n\t\tlet l:res_faces = ''\n\t\tif type(a:faces) == 3\n\t\t\tlet l:style = []\n\t\t\tfor l:f in a:faces\n\t\t\t\tlet l:_f = [l:f]\n\t\t\t\tif type(l:f) == 3\n\t\t\t\t\tlet l:_f = l:f\n\t\t\t\tendif\n\t\t\t\tfor l:g in l:_f\n\t\t\t\t\tif type(l:g) == 1 && l:g =~ '^:'\n\t\t\t\t\t\tif l:g !~ '[\\t ]'\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\tendif\n\t\t\t\t\t\tlet l:k_v = split(l:g)\n\t\t\t\t\t\tif l:k_v[0] == ':foreground'\n\t\t\t\t\t\t\tlet l:gui_color = ''\n\t\t\t\t\t\t\tlet l:found_gui_color = 0\n\t\t\t\t\t\t\tfor l:color in split(l:k_v[1], ',')\n\t\t\t\t\t\t\t\tif l:color =~ '^#'\n\t\t\t\t\t\t\t\t\tlet l:found_gui_color = 1\n\t\t\t\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' guifg=' . l:color\n\t\t\t\t\t\t\t\telseif l:color != ''\n\t\t\t\t\t\t\t\t\tlet l:gui_color = l:color\n\t\t\t\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' ctermfg=' . l:color\n\t\t\t\t\t\t\t\tendif\n\t\t\t\t\t\t\tendfor\n\t\t\t\t\t\t\tif ! l:found_gui_color && l:gui_color != ''\n\t\t\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' guifg=' . l:gui_color\n\t\t\t\t\t\t\tendif\n\t\t\t\t\t\telseif l:k_v[0] == ':background'\n\t\t\t\t\t\t\tlet l:gui_color = ''\n\t\t\t\t\t\t\tlet l:found_gui_color = 0\n\t\t\t\t\t\t\tfor l:color in split(l:k_v[1], ',')\n\t\t\t\t\t\t\t\tif l:color =~ '^#'\n\t\t\t\t\t\t\t\t\tlet l:found_gui_color = 1\n\t\t\t\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' guibg=' . l:color\n\t\t\t\t\t\t\t\telseif l:color != ''\n\t\t\t\t\t\t\t\t\tlet l:gui_color = l:color\n\t\t\t\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' ctermbg=' . l:color\n\t\t\t\t\t\t\t\tendif\n\t\t\t\t\t\t\tendfor\n\t\t\t\t\t\t\tif ! l:found_gui_color && l:gui_color != ''\n\t\t\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' guibg=' . l:gui_color\n\t\t\t\t\t\t\tendif\n\t\t\t\t\t\telseif l:k_v[0] == ':weight' || l:k_v[0] == ':slant' || l:k_v[0] == ':decoration'\n\t\t\t\t\t\t\tif index(l:style, l:k_v[1]) == -1\n\t\t\t\t\t\t\t\tcall add(l:style, l:k_v[1])\n\t\t\t\t\t\t\tendif\n\t\t\t\t\t\tendif\n\t\t\t\t\telseif type(l:g) == 1\n\t\t\t\t\t\t\" TODO emacs interprets the color and automatically determines\n\t\t\t\t\t\t\" whether it should be set as foreground or background color\n\t\t\t\t\t\tlet l:res_faces = l:res_faces . ' ctermfg=' . l:k_v[1] . ' guifg=' . l:k_v[1]\n\t\t\t\t\tendif\n\t\t\t\tendfor\n\t\t\tendfor\n\t\t\tlet l:s = ''\n\t\t\tfor l:i in l:style\n\t\t\t\tif l:s == ''\n\t\t\t\t\tlet l:s = l:i\n\t\t\t\telse\n\t\t\t\t\tlet l:s = l:s . ','. l:i\n\t\t\t\tendif\n\t\t\tendfor\n\t\t\tif l:s != ''\n\t\t\t\tlet l:res_faces = l:res_faces . ' term=' . l:s . ' cterm=' . l:s . ' gui=' . l:s\n\t\t\tendif\n\t\telseif type(a:faces) == 1\n\t\t\t\" TODO emacs interprets the color and automatically determines\n\t\t\t\" whether it should be set as foreground or background color\n\t\t\tlet l:res_faces = l:res_faces . ' ctermfg=' . a:faces . ' guifg=' . a:faces\n\t\tendif\n\t\treturn l:res_faces\n\tendfunction\n\n\tfunction! s:ReadTodoKeywords(keywords, todo_headings)\n\t\tlet l:default_group = 'Todo'\n\t\tfor l:i in a:keywords\n\t\t\tif type(l:i) == 3\n\t\t\t\tcall s:ReadTodoKeywords(l:i, a:todo_headings)\n\t\t\t\tcontinue\n\t\t\tendif\n\t\t\tif l:i == '|'\n\t\t\t\tlet l:default_group = 'Question'\n\t\t\t\tcontinue\n\t\t\tendif\n\t\t\t\" strip access key\n\t\t\tlet l:_i = substitute(l:i, \"\\(.*$\", \"\", \"\")\n\t\t\tlet l:safename = substitute(l:_i, \"\\\\W\", \"\\\\=('u' . char2nr(submatch(0)))\", \"g\")\n\n\t\t\tlet l:group = l:default_group\n\t\t\tfor l:j in g:org_todo_keyword_faces\n\t\t\t\tif l:j[0] == l:_i\n\t\t\t\t\tlet l:group = 'org_todo_keyword_face_' . l:safename\n\t\t\t\t\tcall OrgExtendHighlightingGroup(l:default_group, l:group, OrgInterpretFaces(l:j[1]))\n\t\t\t\t\tbreak\n\t\t\t\tendif\n\t\t\tendfor\n\t\t\tsilent! exec 'syntax match org_todo_keyword_' . l:safename . ' /\\*\\{1,\\}\\s\\{1,\\}\\zs' . l:_i .'\\(\\s\\|$\\)/ ' . a:todo_headings . ' contains=@NoSpell'\n\t\t\tsilent! exec 'hi def link org_todo_keyword_' . l:safename . ' ' . l:group\n\t\tendfor\n\tendfunction\nendif\n\ncall s:ReadTodoKeywords(g:org_todo_keywords, s:todo_headings)\nunlet! s:todo_headings\n\n\" Timestamps: {{{1\n\"<2003-09-16 Tue>\n\"<2003-09-16 Sáb>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k>\\)/\n\"<2003-09-16 Tue 12:00>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d>\\)/\n\"<2003-09-16 Tue 12:00-12:30>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d-\\d\\d:\\d\\d>\\)/\n\n\"<2003-09-16 Tue>--<2003-09-16 Tue>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k>--<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k>\\)/\n\"<2003-09-16 Tue 12:00>--<2003-09-16 Tue 12:00>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d>--<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d>\\)/\n\nsyn match org_timestamp /\\(<%%(diary-float.\\+>\\)/\n\n\"[2003-09-16 Tue]\nsyn match org_timestamp_inactive /\\(\\[\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k\\]\\)/\n\"[2003-09-16 Tue 12:00]\nsyn match org_timestamp_inactive /\\(\\[\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d\\]\\)/\n\n\"[2003-09-16 Tue]--[2003-09-16 Tue]\nsyn match org_timestamp_inactive /\\(\\[\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k\\]--\\[\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k\\]\\)/\n\"[2003-09-16 Tue 12:00]--[2003-09-16 Tue 12:00]\nsyn match org_timestamp_inactive /\\(\\[\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d\\]--\\[\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d\\]\\)/\n\nsyn match org_timestamp_inactive /\\(\\[%%(diary-float.\\+\\]\\)/\n\nhi def link org_timestamp PreProc\nhi def link org_timestamp_inactive Comment\n\n\" Deadline And Schedule: {{{1\nsyn match org_deadline_scheduled /^\\s*\\(DEADLINE\\|SCHEDULED\\):/\nhi def link org_deadline_scheduled PreProc\n\n\" Tables: {{{1\nsyn match org_table /^\\s*|.*/ contains=org_timestamp,org_timestamp_inactive,hyperlink,org_table_separator,org_table_horizontal_line\nsyn match org_table_separator /\\(^\\s*|[-+]\\+|\\?\\||\\)/ contained\nhi def link org_table_separator Type\n\n\" Hyperlinks: {{{1\nsyntax match hyperlink\t\"\\[\\{2}[^][]*\\(\\]\\[[^][]*\\)\\?\\]\\{2}\" contains=hyperlinkBracketsLeft,hyperlinkURL,hyperlinkBracketsRight containedin=ALL\nif (s:conceal_aggressively == 1)\n    syntax match hyperlinkBracketsLeft\tcontained \"\\[\\{2}#\\?\"     conceal\nelse\n    syntax match hyperlinkBracketsLeft\tcontained \"\\[\\{2}\"     conceal\nendif\nsyntax match hyperlinkURL\t\t\t\t    contained \"[^][]*\\]\\[\" conceal\nsyntax match hyperlinkBracketsRight\tcontained \"\\]\\{2}\"     conceal\nhi def link hyperlink Underlined\n\n\" Comments: {{{1\nsyntax match org_comment /^#.*/\nhi def link org_comment Comment\n\n\" References: {{{1\nsyntax match reference '\\\\ref{.*}' transparent contains=referenceStart,referenceEnd\nsyntax match referenceStart '\\\\ref{*' contained conceal cchar=[\nsyntax match referenceEnd '\\(\\\\ref{\\w\\+\\)\\@<=\\zs}' contained conceal cchar=]\n\n\" Bullet Lists: {{{1\n\" Ordered Lists:\n\" 1. list item\n\" 1) list item\n\" a. list item\n\" a) list item\nsyn match org_list_ordered \"^\\s*\\(\\a\\|\\d\\+\\)[.)]\\(\\s\\|$\\)\" nextgroup=org_list_item\nhi def link org_list_ordered Identifier\n\n\" Unordered Lists:\n\" - list item\n\" * list item\n\" + list item\n\" + and - don't need a whitespace prefix\nsyn match org_list_unordered \"^\\(\\s*[-+]\\|\\s\\+\\*\\)\\(\\s\\|$\\)\" nextgroup=org_list_item\nhi def link org_list_unordered Identifier\n\n\" Definition Lists:\n\" - Term :: expl.\n\" 1) Term :: expl.\nsyntax match org_list_def /.*\\s\\+::/ contained\nhi def link org_list_def PreProc\n\nsyntax match org_list_item /.*$/ contained contains=org_subtask_percent,org_subtask_number,org_subtask_percent_100,org_subtask_number_all,org_list_checkbox,org_bold,org_italic,org_underline,org_code,org_verbatim,org_timestamp,org_timestamp_inactive,org_list_def\nsyntax match org_list_checkbox /\\[[ X-]]/ contained\nhi def link org_list_bullet Identifier\nhi def link org_list_checkbox     PreProc\n\n\" Block Delimiters: {{{1\nsyntax case ignore\nsyntax match  org_block_delimiter /^#+BEGIN_.*/\nsyntax match  org_block_delimiter /^#+END_.*/\nsyntax match  org_key_identifier  /^#+[^ ]*:/\nsyntax match  org_title           /^#+TITLE:.*/  contains=org_key_identifier\nhi def link org_block_delimiter Comment\nhi def link org_key_identifier  Comment\nhi def link org_title           Title\n\n\" Block Markup: {{{1\n\" we consider all BEGIN/END sections as 'verbatim' blocks (inc. 'quote', 'verse', 'center')\n\" except 'example' and 'src' which are treated as 'code' blocks.\n\" Note: the non-standard '>' prefix is supported for quotation lines.\n\" Note: the '^:.*\" rule must be defined before the ':PROPERTIES:' one below.\n\" TODO: http://vim.wikia.com/wiki/Different_syntax_highlighting_within_regions_of_a_file\nsyntax match  org_verbatim /^\\s*>.*/\nsyntax match  org_code     /^\\s*:.*/\n\nsyntax region org_verbatim start=\"^\\s*#+BEGIN_.*\"      end=\"^\\s*#+END_.*\"      keepend contains=org_block_delimiter\nsyntax region org_code     start=\"^\\s*#+BEGIN_SRC\"     end=\"^\\s*#+END_SRC\"     keepend contains=org_block_delimiter\nsyntax region org_code     start=\"^\\s*#+BEGIN_EXAMPLE\" end=\"^\\s*#+END_EXAMPLE\" keepend contains=org_block_delimiter\n\nhi def link org_code     String\nhi def link org_verbatim String\n\nif (s:conceal_aggressively==1)\n    hi link org_border_code     org_code\n    hi link org_border_verb     org_verbatim\nendif\n\n\" Properties: {{{1\nsyn region Error matchgroup=org_properties_delimiter start=/^\\s*:PROPERTIES:\\s*$/ end=/^\\s*:END:\\s*$/ contains=org_property keepend\nsyn match org_property /^\\s*:[^\\t :]\\+:\\s\\+[^\\t ]/ contained contains=org_property_value\nsyn match org_property_value /:\\s\\zs.*/ contained\nhi def link org_properties_delimiter PreProc\nhi def link org_property             Statement\nhi def link org_property_value       Constant\n\" Break down subtasks\nsyntax match org_subtask_number /\\[\\d*\\/\\d*]/ contained\nsyntax match org_subtask_percent /\\[\\d*%\\]/ contained\nsyntax match org_subtask_number_all /\\[\\(\\d\\+\\)\\/\\1\\]/ contained\nsyntax match org_subtask_percent_100 /\\[100%\\]/ contained\n\nhi def link org_subtask_number String\nhi def link org_subtask_percent String\nhi def link org_subtask_percent_100 Identifier\nhi def link org_subtask_number_all Identifier\n\n\" Plugin SyntaxRange: {{{1\n\" This only works if you have SyntaxRange installed:\n\" https://github.com/vim-scripts/SyntaxRange\n\n\" BEGIN_SRC\nif exists('g:loaded_SyntaxRange')\n  call SyntaxRange#Include('#+BEGIN_SRC vim', '#+END_SRC', 'vim', 'comment')\n  call SyntaxRange#Include('#+BEGIN_SRC python', '#+END_SRC', 'python', 'comment')\n  call SyntaxRange#Include('#+BEGIN_SRC c', '#+END_SRC', 'c', 'comment')\n  \" cpp must be below c, otherwise you get c syntax hl for cpp files\n  call SyntaxRange#Include('#+BEGIN_SRC cpp', '#+END_SRC', 'cpp', 'comment')\n  call SyntaxRange#Include('#+BEGIN_SRC haskell', '#+END_SRC', 'haskell', 'comment')\n  call SyntaxRange#Include('#+BEGIN_SRC ocaml', '#+END_SRC', 'ocaml', 'comment')\n  call SyntaxRange#Include('#+BEGIN_SRC ruby', '#+END_SRC', 'ruby', 'comment')\n  call SyntaxRange#Include('#+BEGIN_SRC rust', '#+END_SRC', 'rust', 'comment')\n  \" call SyntaxRange#Include('#+BEGIN_SRC lua', '#+END_SRC', 'lua', 'comment')\n  \" call SyntaxRange#Include('#+BEGIN_SRC lisp', '#+END_SRC', 'lisp', 'comment')\n\n  \" LaTeX\n  call SyntaxRange#Include('\\\\begin[.*]{.*}', '\\\\end{.*}', 'tex')\n  call SyntaxRange#Include('\\\\begin{.*}', '\\\\end{.*}', 'tex')\n  call SyntaxRange#Include('\\\\\\[', '\\\\\\]', 'tex')\n  call SyntaxRange#Include('\\$[^$]', '\\$', 'tex')\nendif\n\nlet b:current_syntax = \"org\"\n\" vi: ft=vim:tw=80:sw=4:ts=4:fdm=marker\n"
  },
  {
    "path": "syntax/orgagenda.vim",
    "content": "\" TODO do we really need a separate syntax file for the agenda?\n\"      - Most of the stuff here is also in syntax.org\n\"      - DRY!\n\nif exists(\"b:current_syntax\")\n    finish\nendif\n\nsyn match org_todo_key /\\[\\zs[^]]*\\ze\\]/\nhi def link org_todo_key Identifier\n\n\" Multi-colored tags in agenda\nsyn match org_tag_1 /:[a-iA-I][^: ]*:/hs=s+1,me=e-1\nsyn match org_tag_2 /:[j-rJ-R][^: ]*:/hs=s+1,me=e-1\nsyn match org_tag_3 /:[s-zS-Z0][^: ]*:/hs=s+1,me=e-1\nsyn match org_tag_4 /:[1-9_][^: ]*:/hs=s+1,me=e-1\nsyn match org_tag_5 /:[\\W][^: ]*:/hs=s+1,me=e-1\nhi def link org_tag_1 Title\nhi def link org_tag_2 Constant\nhi def link org_tag_3 Statement\nhi def link org_tag_4 Type\nhi def link org_tag_5 Special\n\nlet s:todo_headings = ''\nlet s:i = 1\nwhile s:i <= g:org_heading_highlight_levels\n\tif s:todo_headings == ''\n\t\tlet s:todo_headings = 'containedin=org_heading' . s:i\n\telse\n\t\tlet s:todo_headings = s:todo_headings . ',org_heading' . s:i\n\tendif\n\tlet s:i += 1\nendwhile\nunlet! s:i\n\nif !exists('g:loaded_orgagenda_syntax')\n\tlet g:loaded_orgagenda_syntax = 1\n\tfunction! s:ReadTodoKeywords(keywords, todo_headings)\n\t\tlet l:default_group = 'Todo'\n\t\tfor l:i in a:keywords\n\t\t\tif type(l:i) == 3\n\t\t\t\tcall s:ReadTodoKeywords(l:i, a:todo_headings)\n\t\t\t\tcontinue\n\t\t\tendif\n\t\t\tif l:i == '|'\n\t\t\t\tlet l:default_group = 'Question'\n\t\t\t\tcontinue\n\t\t\tendif\n\t\t\t\" strip access key\n\t\t\tlet l:_i = substitute(l:i, \"\\(.*$\", \"\", \"\")\n\n\t\t\tlet l:group = l:default_group\n\t\t\tfor l:j in g:org_todo_keyword_faces\n\t\t\t\tif l:j[0] == l:_i\n\t\t\t\t\tlet l:group = 'orgtodo_todo_keyword_face_' . l:_i\n\t\t\t\t\tcall OrgExtendHighlightingGroup(l:default_group, l:group, OrgInterpretFaces(l:j[1]))\n\t\t\t\t\tbreak\n\t\t\t\tendif\n\t\t\tendfor\n\t\t\tsilent! exec 'syntax match orgtodo_todo_keyword_' . l:_i . ' /' . l:_i .'/ ' . a:todo_headings\n\t\t\tsilent! exec 'hi def link orgtodo_todo_keyword_' . l:_i . ' ' . l:group\n\t\tendfor\n\tendfunction\nendif\n\ncall s:ReadTodoKeywords(g:org_todo_keywords, s:todo_headings)\nunlet! s:todo_headings\n\n\" Timestamps\n\"<2003-09-16 Tue>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k>\\)/\n\"<2003-09-16 Tue 12:00>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d>\\)/\n\"<2003-09-16 Tue 12:00-12:30>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d-\\d\\d:\\d\\d>\\)/\n\"<2003-09-16 Tue>--<2003-09-16 Tue>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k>--<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k>\\)/\n\"<2003-09-16 Tue 12:00>--<2003-09-16 Tue 12:00>\nsyn match org_timestamp /\\(<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d>--<\\d\\d\\d\\d-\\d\\d-\\d\\d \\k\\k\\k \\d\\d:\\d\\d>\\)/\nsyn match org_timestamp /\\(<%%(diary-float.\\+>\\)/\nhi def link org_timestamp PreProc\n\n\" special words\nsyn match today /TODAY$/\nhi def link today PreProc\n\nsyn match week_agenda /^Week Agenda:$/\nhi def link week_agenda PreProc\n\n\" Hyperlinks\nsyntax match hyperlink\t\"\\[\\{2}[^][]*\\(\\]\\[[^][]*\\)\\?\\]\\{2}\" contains=hyperlinkBracketsLeft,hyperlinkURL,hyperlinkBracketsRight containedin=ALL\nsyntax match hyperlinkBracketsLeft\t\tcontained \"\\[\\{2}\" conceal\nsyntax match hyperlinkURL\t\t\t\tcontained \"[^][]*\\]\\[\" conceal\nsyntax match hyperlinkBracketsRight\t\tcontained \"\\]\\{2}\" conceal\nhi def link hyperlink Underlined\n\nlet b:current_syntax = \"orgagenda\"\n"
  },
  {
    "path": "syntax/orgtodo.vim",
    "content": "if exists(\"b:current_syntax\")\n    finish\nendif\n\nsyn match org_todo_key /\\[\\zs[^]]*\\ze\\]/\nhi def link org_todo_key Identifier\n\nlet s:todo_headings = ''\nlet s:i = 1\nwhile s:i <= g:org_heading_highlight_levels\n\tif s:todo_headings == ''\n\t\tlet s:todo_headings = 'containedin=org_heading' . s:i\n\telse\n\t\tlet s:todo_headings = s:todo_headings . ',org_heading' . s:i\n\tendif\n\tlet s:i += 1\nendwhile\nunlet! s:i\n\nif !exists('g:loaded_orgtodo_syntax')\n\tlet g:loaded_orgtodo_syntax = 1\n\tfunction! s:ReadTodoKeywords(keywords, todo_headings)\n\t\tlet l:default_group = 'Todo'\n\t\tfor l:i in a:keywords\n\t\t\tif type(l:i) == 3\n\t\t\t\tcall s:ReadTodoKeywords(l:i, a:todo_headings)\n\t\t\t\tcontinue\n\t\t\tendif\n\t\t\tif l:i == '|'\n\t\t\t\tlet l:default_group = 'Question'\n\t\t\t\tcontinue\n\t\t\tendif\n\t\t\t\" strip access key\n\t\t\tlet l:_i = substitute(l:i, \"\\(.*$\", \"\", \"\")\n\n\t\t\tlet l:group = l:default_group\n\t\t\tfor l:j in g:org_todo_keyword_faces\n\t\t\t\tif l:j[0] == l:_i\n\t\t\t\t\tlet l:group = 'orgtodo_todo_keyword_face_' . l:_i\n\t\t\t\t\tcall OrgExtendHighlightingGroup(l:default_group, l:group, OrgInterpretFaces(l:j[1]))\n\t\t\t\t\tbreak\n\t\t\t\tendif\n\t\t\tendfor\n\t\t\tsilent! exec 'syntax match orgtodo_todo_keyword_' . l:_i . ' /' . l:_i .'/ ' . a:todo_headings . ' contains=@NoSpell'\n\t\t\tsilent! exec 'hi def link orgtodo_todo_keyword_' . l:_i . ' ' . l:group\n\t\tendfor\n\tendfunction\nendif\n\ncall s:ReadTodoKeywords(g:org_todo_keywords, s:todo_headings)\nunlet! s:todo_headings\n\nlet b:current_syntax = \"orgtodo\"\n"
  },
  {
    "path": "tests/orgmode_testfile.org",
    "content": "\n* bold, italics and underline syntax matching\n** Should match:\n\n*foo*  *foo* \n*Really, quite long sentence*.\n_foo_  _foo_ \n_really, quite long sentence._.\n\n *Übermensch á* *eä* *ý€* \n _Ÿ ï_\n\n *sdf   l.*\n *sdfsdf   ,.* \n *foo_ sdf /*  \n /sdf sdf sdf ./\n\n  /google.com/\n\n *[sdf]*\n*a* /a/ =b= ~b~ `d`\n\n*abc* /abc/ =bde= ~bde~ `def`\n *=*a*=*\n** Should not match\nhttp://google.com/\n //google.com/\n * sdf* _ sdf_  \n *sdfsdf   sdf,*\n *foo *\n foo_not underlined_bar\n\n *.sdf*[\n [*.sdf*\n [*sdf*]\n *=*a*=\n\n"
  },
  {
    "path": "tests/run_tests.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport unittest\n\nimport test_vimbuffer\n\nimport test_libagendafilter\nimport test_libcheckbox\nimport test_libbase\nimport test_libheading\nimport test_liborgdate\nimport test_liborgdate_utf8\nimport test_liborgdate_parsing\nimport test_liborgdatetime\nimport test_liborgtimerange\n\nimport test_plugin_date\nimport test_plugin_edit_structure\nimport test_plugin_edit_checkbox\nimport test_plugin_misc\nimport test_plugin_navigator\nimport test_plugin_show_hide\nimport test_plugin_tags_properties\nimport test_plugin_todo\nimport test_plugin_mappings\n\nif __name__ == '__main__':\n    tests = unittest.TestSuite()\n\n    tests.addTests(test_vimbuffer.suite())\n\n    # lib\n    tests.addTests(test_libbase.suite())\n    tests.addTests(test_libcheckbox.suite())\n    tests.addTests(test_libagendafilter.suite())\n    tests.addTests(test_libheading.suite())\n    tests.addTests(test_liborgdate.suite())\n    tests.addTests(test_liborgdate_utf8.suite())\n    tests.addTests(test_liborgdate_parsing.suite())\n    tests.addTests(test_liborgdatetime.suite())\n    tests.addTests(test_liborgtimerange.suite())\n\n    # plugins\n    tests.addTests(test_plugin_date.suite())\n    tests.addTests(test_plugin_edit_structure.suite())\n    tests.addTests(test_plugin_edit_checkbox.suite())\n    tests.addTests(test_plugin_misc.suite())\n    tests.addTests(test_plugin_navigator.suite())\n    tests.addTests(test_plugin_show_hide.suite())\n    tests.addTests(test_plugin_tags_properties.suite())\n    tests.addTests(test_plugin_todo.suite())\n    tests.addTests(test_plugin_mappings.suite())\n\n    runner = unittest.TextTestRunner()\n    runner.run(tests)\n"
  },
  {
    "path": "tests/test_libagendafilter.py",
    "content": "# -*- coding: utf-8 -*-\n\n\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport unittest\nfrom datetime import date\nfrom datetime import timedelta\n\nfrom orgmode.liborgmode.headings import Heading\nfrom orgmode.liborgmode.orgdate import OrgDate\nfrom orgmode.liborgmode.agendafilter import contains_active_todo\nfrom orgmode.liborgmode.agendafilter import contains_active_date\nfrom orgmode.liborgmode.orgdate import OrgDateTime\nfrom orgmode.liborgmode.agendafilter import is_within_week\nfrom orgmode.liborgmode.agendafilter import is_within_week_and_active_todo\nfrom orgmode.liborgmode.agendafilter import filter_items\n\nimport vim\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ncounter = 0\n\nclass AgendaFilterTestCase(unittest.TestCase):\n    u\"\"\"Tests all the functionality of the Agenda filter module.\"\"\"\n\n    def setUp(self):\n        global counter\n        counter += 1\n\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u\"v:count\"): u_encode(u'0')\n                }\n        vim.current.buffer[:] = [u_encode(i) for i in u\"\"\"\n* TODO Heading 1\n  some text\n\"\"\".split(u'\\n')]\n\n    def test_contains_active_todo(self):\n        heading = Heading(title=u'Refactor the code', todo='TODO')\n        self.assertTrue(contains_active_todo(heading))\n\n        heading = Heading(title=u'Refactor the code', todo='DONE')\n        self.assertFalse(contains_active_todo(heading))\n\n        heading = Heading(title=u'Refactor the code', todo=None)\n        self.assertFalse(contains_active_todo(heading))\n\n    def test_contains_active_date(self):\n        heading = Heading(title=u'Refactor the code', active_date=None)\n        self.assertFalse(contains_active_date(heading))\n\n        odate = OrgDate(True, 2011, 11, 1)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertTrue(contains_active_date(heading))\n\n    def test_is_within_week_with_orgdate(self):\n        # to far in the future\n        tmpdate = date.today() + timedelta(days=8)\n        odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertFalse(is_within_week(heading))\n\n        # within a week\n        tmpdate = date.today() + timedelta(days=5)\n        odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertTrue(is_within_week(heading))\n\n        # in the past\n        tmpdate = date.today() - timedelta(days=105)\n        odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertTrue(is_within_week(heading))\n\n    def test_is_within_week_with_orgdatetime(self):\n        # to far in the future\n        tmp = date.today() + timedelta(days=1000)\n        odate = OrgDateTime(True, tmp.year, tmp.month, tmp.day, 10, 10)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertFalse(is_within_week(heading))\n\n        # within a week\n        tmpdate = date.today() + timedelta(days=5)\n        odate = OrgDateTime(True, tmpdate.year, tmpdate.month, tmpdate.day, 1, 0)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertTrue(is_within_week(heading))\n\n        # in the past\n        tmpdate = date.today() - timedelta(days=5)\n        odate = OrgDateTime(True, tmpdate.year, tmpdate.month, tmpdate.day, 1, 0)\n        heading = Heading(title=u'Refactor the code', active_date=odate)\n        self.assertTrue(is_within_week(heading))\n\n    def test_filter_items(self):\n        # only headings with date and todo should be returned\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = \\\n                [u_encode(u'TODO'), u_encode(u'STARTED'), u_encode(u'|'), u_encode(u'DONE')]\n        tmpdate = date.today()\n        odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day)\n        tmp_head = Heading(title=u'Refactor the code', todo=u'TODO', active_date=odate)\n        tmp_head_01 = Heading(title=u'Refactor the code', todo=u'STARTED', active_date=odate)\n        # TODO add more tests\n        headings = [tmp_head, tmp_head_01]\n        filtered = list(filter_items(headings,\n                [contains_active_date, contains_active_todo]))\n\n        self.assertEqual(len(filtered), 2)\n        self.assertEqual(filtered, headings)\n\n        # try a longer list\n        headings = headings * 3\n        filtered = list(filter_items(headings,\n                [contains_active_date, contains_active_todo]))\n\n        self.assertEqual(len(filtered), 6)\n        self.assertEqual(filtered, headings)\n\n        # date does not contain all needed fields thus gets ignored\n        tmpdate = date.today()\n        odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day)\n        tmp_head = Heading(title=u'Refactor the code', active_date=odate)\n        headings = [tmp_head]\n        filtered = list(filter_items(headings, [contains_active_date,\n                contains_active_todo]))\n        self.assertEqual([], filtered)\n\n    def test_filter_items_with_some_todos_and_dates(self):\n        u\"\"\"\n        Only the headings with todo and dates should be returned.\n        \"\"\"\n        tmp = [u\"* TODO OrgMode Demo und Tests\"\n                u\"<2011-08-22 Mon>\"]\n        headings = [Heading.parse_heading_from_data(tmp, [u'TODO'])]\n        filtered = list(filter_items(headings,\n                               [is_within_week_and_active_todo]))\n        self.assertEqual(len(filtered), 1)\n        self.assertEqual(headings, filtered)\n\n        tmp = [Heading.parse_heading_from_data([u\"** DONE something <2011-08-10 Wed>\"], [u'TODO']),\n                Heading.parse_heading_from_data([u\"*** TODO rsitenaoritns more <2011-08-25 Thu>\"], [u'TODO']),\n                Heading.parse_heading_from_data([u\"*** DONE some more <2011-08-25 Thu>\"], [u'TODO']),\n                Heading.parse_heading_from_data([u\"*** TODO some more <2011-08-25 Thu>\"], [u'TODO']),\n                Heading.parse_heading_from_data([u\"** DONE something2 <2011-08-10 Wed>\"], [u'TODO'])\n        ]\n        for h in tmp:\n            headings.append(h)\n\n        filtered = list(filter_items(headings,\n                               [is_within_week_and_active_todo]))\n        self.assertEqual(len(filtered), 3)\n        self.assertEqual(filtered, [headings[0], headings[2], headings[4]])\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(AgendaFilterTestCase)\n"
  },
  {
    "path": "tests/test_libbase.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nfrom orgmode.liborgmode.base import Direction, get_domobj_range\nfrom orgmode.liborgmode.headings import Heading\n\n\nclass LibBaseTestCase(unittest.TestCase):\n\n    def setUp(self):\n        self.case1 = \"\"\"\n* head1\n heading body\n for testing\n* head2\n** head3\n        \"\"\".split(\"\\n\")\n\n    def test_base_functions(self):\n        # direction FORWARD\n        (start, end) = get_domobj_range(content=self.case1, position=1, identify_fun=Heading.identify_heading)\n        self.assertEqual((start, end), (1, 3))\n        (start, end) = get_domobj_range(content=self.case1, position=3, direction=Direction.BACKWARD, \\\n                                        identify_fun=Heading.identify_heading)\n        self.assertEqual((start, end), (1, 3))\n\ndef suite():\n    return unittest.TestLoader() \\\n                   .loadTestsFromTestCase(\n                           LibBaseTestCase)\n"
  },
  {
    "path": "tests/test_libcheckbox.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\nfrom orgmode.liborgmode.checkboxes import Checkbox\nfrom orgmode._vim import ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ndef set_vim_buffer(buf=None, cursor=(2, 0), bufnr=0):\n    if buf is None:\n        buf = []\n    vim.current.buffer[:] = buf\n    vim.current.window.cursor = cursor\n    vim.current.buffer.number = bufnr\n\n\nclass CheckboxTestCase(unittest.TestCase):\n\n    def setUp(self):\n        counter = 0\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_improve_split_heading\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_improve_split_heading\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u'&ts'): u_encode(u'8'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0')}\n\n        self.c1 = \"\"\"\n* heading1 [/]\n  - [-] checkbox1 [%]\n        - [X] checkbox2\n        - [ ] checkbox3\n  - [X] checkbox4\n\"\"\".split(\"\\n\")\n\n        self.c2 = \"\"\"\n* heading1\n  - [ ] checkbox1\n  - [ ] checkbox2\n        - [ ] checkbox3\n              - [ ] checkbox4\n                    - [ ] checkbox5\n   - [ ] checkbox6\n\"\"\".split(\"\\n\")\n\n    def test_init(self):\n        # test initialize Checkbox\n        c = Checkbox(level=1, title=\"checkbox1\")\n        self.assertEqual(str(c), \" - [ ] checkbox1\")\n        c = Checkbox(level=3, title=\"checkbox2\", status=\"[X]\")\n        self.assertEqual(str(c), \"   - [X] checkbox2\")\n\n    def test_basic(self):\n        bufnr = 1\n        set_vim_buffer(buf=self.c1, bufnr=bufnr)\n        h = ORGMODE.get_document(bufnr=bufnr).current_heading()\n        h.init_checkboxes()\n\n        c = h.current_checkbox(position=2)\n        self.assertEqual(str(c), self.c1[2])\n        self.assertFalse(c.are_children_all(Checkbox.STATUS_ON))\n        self.assertTrue(c.is_child_one(Checkbox.STATUS_OFF))\n        self.assertFalse(c.are_siblings_all(Checkbox.STATUS_ON))\n\n        for child in c.all_children():\n            pass\n        for sibling in c.all_siblings():\n            pass\n        c = h.current_checkbox(position=3)\n        new_checkbox = c.copy()\n        self.assertEqual(str(c), self.c1[3])\n        c.get_parent_list()\n        c.get_index_in_parent_list()\n\n    def test_identify(self):\n        # test identify_checkbox\n        self.assertEqual(Checkbox.identify_checkbox(self.c1[2]), 2)\n        self.assertEqual(Checkbox.identify_checkbox(self.c1[3]), 8)\n        # check for corner case\n        self.assertEqual(Checkbox.identify_checkbox(\" - [ ]\"), 1)\n\n    def test_toggle(self):\n        bufnr = 2\n        # test init_checkboxes\n        set_vim_buffer(buf=self.c1, bufnr=bufnr)\n        h = ORGMODE.get_document(bufnr=bufnr).current_heading()\n        h.init_checkboxes()\n\n        # toggle checkbox\n        c = h.current_checkbox(position=4)\n        c.toggle()\n        self.assertEqual(str(c), \"        - [X] checkbox3\")\n        c.toggle()\n        self.assertEqual(str(c), \"        - [ ] checkbox3\")\n\n        (total, on) = c.all_siblings_status()\n        self.assertEqual((total, on), (2, 1))\n\n    def test_subtasks(self):\n        bufnr = 3\n        set_vim_buffer(buf=self.c1, bufnr=bufnr)\n        h = ORGMODE.get_document(bufnr=bufnr).current_heading()\n        h.init_checkboxes()\n        c = h.current_checkbox(position=3)\n        c.toggle()\n        c = h.current_checkbox(position=2)\n        (total, on) = c.all_siblings_status()\n        c.update_subtasks(total=total, on=on)\n        self.assertEqual(str(c), \"  - [-] checkbox1 [50%]\")\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(CheckboxTestCase)\n"
  },
  {
    "path": "tests/test_libheading.py",
    "content": "﻿# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nfrom orgmode.liborgmode.headings import Heading\nfrom orgmode.liborgmode.orgdate import OrgDate\nfrom orgmode.liborgmode.orgdate import OrgDateTime\n\n\nclass TestHeadingRecognizeDatesInHeading(unittest.TestCase):\n\n    def setUp(self):\n        self.allowed_todo_states = [\"TODO\"]\n\n        tmp = [\"* This heading is earlier  <2011-08-24 Wed>\"]\n        self.h1 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states)\n\n        tmp = [\"* This heading is later <2011-08-25 Thu>\"]\n        self.h2 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states)\n\n        tmp = [\"* This heading is later <2011-08-25 Thu 10:20>\"]\n        self.h2_datetime = Heading.parse_heading_from_data(tmp, self.allowed_todo_states)\n\n        tmp = [\"* This heading is later <2011-08-26 Fri 10:20>\"]\n        self.h3 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states)\n\n        tmp = [\"* This heading has no date and should be later than the rest\"]\n        self.h_no_date = Heading.parse_heading_from_data(tmp,\n                self.allowed_todo_states)\n\n    def test_heading_parsing_no_date(self):\n        \"\"\"\"\"\n        'text' doesn't contain any valid date.\n        \"\"\"\n        text = [\"* TODO This is a test :hallo:\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertEqual(None, h.active_date)\n\n        text = [\"* TODO This is a test <2011-08-25>\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertEqual(None, h.active_date)\n\n        text = [\"* TODO This is a test <2011-08-25 Wednesday>\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertEqual(None, h.active_date)\n\n        text = [\"* TODO This is a test <20110825>\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertEqual(None, h.active_date)\n\n    def test_heading_parsing_with_date(self):\n        \"\"\"\"\"\n        'text' does contain valid dates.\n        \"\"\"\n        # orgdate\n        text = [\"* TODO This is a test <2011-08-24 Wed> :hallo:\"]\n        odate = OrgDate(True, 2011, 8, 24)\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertEqual(odate, h.active_date)\n\n        # orgdatetime\n        text = [\"* TODO This is a test <2011-08-25 Thu 10:10> :hallo:\"]\n        odate = OrgDateTime(True, 2011, 8, 25, 10, 10)\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertEqual(odate, h.active_date)\n\n    def test_heading_parsing_with_date_and_body(self):\n        \"\"\"\"\"\n        'text' contains valid dates (in the body).\n        \"\"\"\n        # orgdatetime\n        text = [\"* TODO This is a test <2011-08-25 Thu 10:10> :hallo:\",\n                \"some body text\",\n                \"some body text\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertTrue(isinstance(h.active_date, OrgDateTime))\n        self.assertEqual(\"<2011-08-25 Thu 10:10>\", str(h.active_date))\n\n        text = [\"* TODO This is a test  :hallo:\",\n                \"some body text\",\n                \"some body text<2011-08-25 Thu 10:10>\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        self.assertTrue(isinstance(h.active_date, OrgDateTime))\n        self.assertEqual(\"<2011-08-25 Thu 10:10>\", str(h.active_date))\n\n        text = [\"* TODO This is a test  :hallo:\",\n                \"some body text <2011-08-24 Wed>\",\n                \"some body text<2011-08-25 Thu 10:10>\"]\n        h = Heading.parse_heading_from_data(text, self.allowed_todo_states)\n        odate = OrgDate(True, 2011, 8, 24)\n        self.assertEqual(odate, h.active_date)\n\n    def test_less_than_for_dates_in_heading(self):\n        self.assertTrue(self.h1 < self.h2)\n        self.assertTrue(self.h1 < self.h3)\n        self.assertTrue(self.h1 < self.h_no_date)\n        self.assertTrue(self.h2 < self.h_no_date)\n        self.assertTrue(self.h2 < self.h3)\n        self.assertTrue(self.h3 < self.h_no_date)\n\n        self.assertFalse(self.h2 < self.h1)\n        self.assertFalse(self.h3 < self.h2)\n\n    def test_less_equal_for_dates_in_heading(self):\n        self.assertTrue(self.h1 <= self.h2)\n        self.assertTrue(self.h1 <= self.h_no_date)\n        self.assertTrue(self.h2 <= self.h_no_date)\n        self.assertTrue(self.h2 <= self.h2_datetime)\n        self.assertTrue(self.h2 <= self.h3)\n\n    def test_greate_than_for_dates_in_heading(self):\n        self.assertTrue(self.h2 > self.h1)\n        self.assertTrue(self.h_no_date > self.h1)\n        self.assertTrue(self.h_no_date > self.h2)\n\n        self.assertFalse(self.h2 > self.h2_datetime)\n\n    def test_greate_equal_for_dates_in_heading(self):\n        self.assertTrue(self.h2 >= self.h1)\n        self.assertTrue(self.h_no_date >= self.h1)\n        self.assertTrue(self.h_no_date >= self.h2)\n        self.assertTrue(self.h2 >= self.h2_datetime)\n\n    def test_sorting_of_headings(self):\n        \"\"\"Headings should be sortable.\"\"\"\n        self.assertEqual([self.h1, self.h2], sorted([self.h2, self.h1]))\n\n        self.assertEqual([self.h1, self.h2_datetime],\n                sorted([self.h2_datetime, self.h1]))\n\n        self.assertEqual([self.h2_datetime, self.h2],\n                sorted([self.h2_datetime, self.h2]))\n\n        self.assertEqual([self.h1, self.h2], sorted([self.h1, self.h2]))\n\n        self.assertEqual([self.h1, self.h_no_date],\n                sorted([self.h1, self.h_no_date]))\n\n        self.assertEqual([self.h1, self.h_no_date],\n                sorted([self.h_no_date, self.h1]))\n\n        self.assertEqual([self.h1, self.h2, self.h_no_date],\n                sorted([self.h2, self.h_no_date, self.h1]))\n\n        self.assertEqual(\n                [self.h1, self.h2_datetime, self.h2, self.h3, self.h_no_date],\n                sorted([self.h2_datetime, self.h3, self.h2, self.h_no_date, self.h1]))\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(\n            TestHeadingRecognizeDatesInHeading)\n"
  },
  {
    "path": "tests/test_liborgdate.py",
    "content": "# -*- coding: utf-8 -*-\n\n\nimport sys\nimport unittest\nfrom datetime import date\n\nsys.path.append(u'../ftplugin')\nfrom orgmode.liborgmode.orgdate import OrgDate\n\nfrom orgmode.py3compat.unicode_compatibility import *\n\nclass OrgDateTestCase(unittest.TestCase):\n    u\"\"\"\n    Tests all the functionality of the OrgDate\n    \"\"\"\n\n    def setUp(self):\n        self.date = date(2011, 8, 29)\n        self.year = 2011\n        self.month = 8\n        self.day = 29\n        self.text = u'<2011-08-29 Mon>'\n        self.textinactive = u'[2011-08-29 Mon]'\n\n    def test_OrgDate_ctor_active(self):\n        u\"\"\"OrdDate should be created.\"\"\"\n        today = date.today()\n        od = OrgDate(True, today.year, today.month, today.day)\n        self.assertTrue(isinstance(od, OrgDate))\n        self.assertTrue(od.active)\n\n    def test_OrgDate_ctor_inactive(self):\n        u\"\"\"OrdDate should be created.\"\"\"\n        today = date.today()\n        od = OrgDate(False, today.year, today.month, today.day)\n        self.assertTrue(isinstance(od, OrgDate))\n        self.assertFalse(od.active)\n\n    def test_OrdDate_str_active(self):\n        u\"\"\"Representation of OrgDates\"\"\"\n        od = OrgDate(True, self.year, self.month, self.day)\n        self.assertEqual(self.text, unicode(od))\n\n    def test_OrdDate_str_inactive(self):\n        od = OrgDate(False, self.year, self.month, self.day)\n        self.assertEqual(self.textinactive, unicode(od))\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(OrgDateTestCase)\n"
  },
  {
    "path": "tests/test_liborgdate_parsing.py",
    "content": "# -*- coding: utf-8 -*-\n\n\nimport sys\nimport unittest\n\nsys.path.append(u'../ftplugin')\nfrom orgmode.liborgmode.orgdate import get_orgdate\nfrom orgmode.liborgmode.orgdate import OrgDate\nfrom orgmode.liborgmode.orgdate import OrgDateTime\nfrom orgmode.liborgmode.orgdate import OrgTimeRange\n\nfrom orgmode.py3compat.unicode_compatibility import *\n\nclass OrgDateParsingTestCase(unittest.TestCase):\n    u\"\"\"\n    Tests the functionality of the parsing function of OrgDate.\n\n    Mostly function get_orgdate().\n    \"\"\"\n\n    def setUp(self):\n        self.text = u'<2011-08-29 Mon>'\n        self.textinactive = u'[2011-08-29 Mon]'\n\n    def test_get_orgdate_parsing_active(self):\n        u\"\"\"\n        get_orgdate should recognize all orgdates in a given text\n        \"\"\"\n        result = get_orgdate(self.text)\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertTrue(isinstance(get_orgdate(u\"<2011-08-30 Tue>\"), OrgDate))\n        self.assertEqual(get_orgdate(u\"<2011-08-30 Tue>\").year, 2011)\n        self.assertEqual(get_orgdate(u\"<2011-08-30 Tue>\").month, 8)\n        self.assertEqual(get_orgdate(u\"<2011-08-30 Tue>\").day, 30)\n        self.assertTrue(get_orgdate(u\"<2011-08-30 Tue>\").active)\n\n        datestr = u\"This date <2011-08-30 Tue> is embedded\"\n        self.assertTrue(isinstance(get_orgdate(datestr), OrgDate))\n\n\n    def test_get_orgdatetime_parsing_active(self):\n        u\"\"\"\n        get_orgdate should recognize all orgdatetimes in a given text\n        \"\"\"\n        result = get_orgdate(u\"<2011-09-12 Mon 10:20>\")\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgDateTime))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 9)\n        self.assertEqual(result.day, 12)\n        self.assertEqual(result.hour, 10)\n        self.assertEqual(result.minute, 20)\n        self.assertTrue(result.active)\n\n        result = get_orgdate(u\"some datetime <2011-09-12 Mon 10:20> stuff\")\n        self.assertTrue(isinstance(result, OrgDateTime))\n\n\n    def test_get_orgtimerange_parsing_active(self):\n        u\"\"\"\n        get_orgdate should recognize all orgtimeranges in a given text\n        \"\"\"\n        daterangestr = u\"<2011-09-12 Mon>--<2011-09-13 Tue>\"\n        result = get_orgdate(daterangestr)\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgTimeRange))\n        self.assertEqual(unicode(result), daterangestr)\n        self.assertTrue(result.active)\n\n        daterangestr = u\"<2011-09-12 Mon 10:20>--<2011-09-13 Tue 13:20>\"\n        result = get_orgdate(daterangestr)\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgTimeRange))\n        self.assertEqual(unicode(result), daterangestr)\n        self.assertTrue(result.active)\n\n        daterangestr = u\"<2011-09-12 Mon 10:20-13:20>\"\n        result = get_orgdate(daterangestr)\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgTimeRange))\n        self.assertEqual(unicode(result), daterangestr)\n        self.assertTrue(result.active)\n\n    def test_get_orgdate_parsing_inactive(self):\n        u\"\"\"\n        get_orgdate should recognize all inactive orgdates in a given text\n        \"\"\"\n        result = get_orgdate(self.textinactive)\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertTrue(isinstance(get_orgdate(u\"[2011-08-30 Tue]\"), OrgDate))\n        self.assertEqual(get_orgdate(u\"[2011-08-30 Tue]\").year, 2011)\n        self.assertEqual(get_orgdate(u\"[2011-08-30 Tue]\").month, 8)\n        self.assertEqual(get_orgdate(u\"[2011-08-30 Tue]\").day, 30)\n        self.assertFalse(get_orgdate(u\"[2011-08-30 Tue]\").active)\n\n        datestr = u\"This date [2011-08-30 Tue] is embedded\"\n        self.assertTrue(isinstance(get_orgdate(datestr), OrgDate))\n\n    def test_get_orgdatetime_parsing_passive(self):\n        u\"\"\"\n        get_orgdate should recognize all orgdatetimes in a given text\n        \"\"\"\n        result = get_orgdate(u\"[2011-09-12 Mon 10:20]\")\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgDateTime))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 9)\n        self.assertEqual(result.day, 12)\n        self.assertEqual(result.hour, 10)\n        self.assertEqual(result.minute, 20)\n        self.assertFalse(result.active)\n\n        result = get_orgdate(u\"some datetime [2011-09-12 Mon 10:20] stuff\")\n        self.assertTrue(isinstance(result, OrgDateTime))\n\n    def test_get_orgdate_parsing_with_list_of_texts(self):\n        u\"\"\"\n        get_orgdate should return the first date in the list.\n        \"\"\"\n        datelist = [u\"<2011-08-29 Mon>\"]\n        result = get_orgdate(datelist)\n        self.assertNotEquals(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 8)\n        self.assertEqual(result.day, 29)\n\n        datelist = [u\"<2011-08-29 Mon>\",\n                u\"<2012-03-30 Fri>\"]\n        result = get_orgdate(datelist)\n        self.assertNotEquals(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 8)\n        self.assertEqual(result.day, 29)\n\n        datelist = [u\"some <2011-08-29 Mon>text\",\n                u\"<2012-03-30 Fri> is here\"]\n        result = get_orgdate(datelist)\n        self.assertNotEquals(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 8)\n        self.assertEqual(result.day, 29)\n\n        datelist = [u\"here is no date\",\n                u\"some <2011-08-29 Mon>text\",\n                u\"<2012-03-30 Fri> is here\"]\n        result = get_orgdate(datelist)\n        self.assertNotEquals(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 8)\n        self.assertEqual(result.day, 29)\n\n        datelist = [u\"here is no date\",\n                u\"some <2011-08-29 Mon 20:10> text\",\n                u\"<2012-03-30 Fri> is here\"]\n        result = get_orgdate(datelist)\n        self.assertNotEquals(result, None)\n        self.assertTrue(isinstance(result, OrgDateTime))\n        self.assertEqual(result.year, 2011)\n        self.assertEqual(result.month, 8)\n        self.assertEqual(result.day, 29)\n        self.assertEqual(result.hour, 20)\n        self.assertEqual(result.minute, 10)\n\n    def test_get_orgdate_parsing_with_invalid_input(self):\n        self.assertEquals(get_orgdate(u\"NONSENSE\"), None)\n        self.assertEquals(get_orgdate(u\"No D<2011- Date 08-29 Mon>\"), None)\n        self.assertEquals(get_orgdate(u\"2011-08-r9 Mon]\"), None)\n        self.assertEquals(get_orgdate(u\"<2011-08-29 Mon\"), None)\n        self.assertEquals(get_orgdate(u\"<2011-08-29 Mon]\"), None)\n        self.assertEquals(get_orgdate(u\"2011-08-29 Mon\"), None)\n        self.assertEquals(get_orgdate(u\"2011-08-29\"), None)\n        self.assertEquals(get_orgdate(u\"2011-08-29 mon\"), None)\n        self.assertEquals(get_orgdate(u\"<2011-08-29 mon>\"), None)\n\n        self.assertEquals(get_orgdate(u\"wrong date embedded <2011-08-29 mon>\"), None)\n        self.assertEquals(get_orgdate(u\"wrong date <2011-08-29 mon>embedded \"), None)\n\n    def test_get_orgdate_parsing_with_invalid_dates(self):\n        u\"\"\"\n        Something like <2011-14-29 Mon> (invalid dates, they don't exist)\n        should not be parsed\n        \"\"\"\n        datestr = u\"<2011-14-30 Tue>\"\n        self.assertEqual(get_orgdate(datestr), None)\n\n        datestr = u\"<2012-03-40 Tue>\"\n        self.assertEqual(get_orgdate(datestr), None)\n\n        datestr = u\"<2012-03-40 Tue 24:70>\"\n        self.assertEqual(get_orgdate(datestr), None)\n\n    def test_get_orgdate_parsing_with_utf8(self):\n        u\"\"\"\n        get_orgdate should recognize all orgdates within a given utf-8 text\n        \"\"\"\n        result = get_orgdate(u'<2016-05-07 Sáb>')\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgDate))\n        self.assertEqual(result.year, 2016)\n        self.assertEqual(result.month, 5)\n        self.assertEqual(result.day, 7)\n        self.assertTrue(result.active)\n\n        datestr = u\"This date <2016-05-07 Sáb> is embedded\"\n        self.assertTrue(isinstance(get_orgdate(datestr), OrgDate))\n\n        result = get_orgdate(u'[2016-05-07 Sáb]')\n        self.assertFalse(result.active)\n\n        datestr = u\"This date [2016-05-07 Sáb] is embedded\"\n        self.assertTrue(isinstance(get_orgdate(datestr), OrgDate))\n\n    def test_get_orgdatetime_parsing_with_utf8(self):\n        u\"\"\"\n        get_orgdate should recognize all orgdatetimes in a given utf-8 text\n        \"\"\"\n        result = get_orgdate(u\"<2016-05-07 Sáb 10:20>\")\n        self.assertNotEqual(result, None)\n        self.assertTrue(isinstance(result, OrgDateTime))\n        self.assertEqual(result.year, 2016)\n        self.assertEqual(result.month, 5)\n        self.assertEqual(result.day, 7)\n        self.assertEqual(result.hour, 10)\n        self.assertEqual(result.minute, 20)\n        self.assertTrue(result.active)\n\n        result = get_orgdate(u\"some datetime <2016-05-07 Sáb 10:20> stuff\")\n        self.assertTrue(isinstance(result, OrgDateTime))\n\n        result = get_orgdate(u\"[2016-05-07 Sáb 10:20]\")\n        self.assertFalse(result.active)\n\n        result = get_orgdate(u\"some datetime [2016-05-07 Sáb 10:20] stuff\")\n        self.assertTrue(isinstance(result, OrgDateTime))\n\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(OrgDateParsingTestCase)\n"
  },
  {
    "path": "tests/test_liborgdate_utf8.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport sys\nimport unittest\nimport locale\nimport threading\n\nfrom datetime import date\nfrom contextlib import contextmanager\n\nfrom orgmode.py3compat.unicode_compatibility import *\n\nsys.path.append(u'../ftplugin')\nfrom orgmode.liborgmode.orgdate import OrgDate\n\nclass OrgDateUtf8TestCase(unittest.TestCase):\n    u\"\"\"\n    Tests OrgDate with utf-8 enabled locales\n    \"\"\"\n    LOCALE_LOCK = threading.Lock()\n    UTF8_LOCALE = \"fr_FR.utf-8\"\n\n    @contextmanager\n    def setlocale(self, name):\n        with self.LOCALE_LOCK:\n            saved = locale.setlocale(locale.LC_ALL)\n            try:\n                yield locale.setlocale(locale.LC_ALL, name)\n            finally:\n                locale.setlocale(locale.LC_ALL, saved)\n\n    def setUp(self):\n        self.year = 2016\n        self.month = 5\n        self.day = 7\n        self.text = u'<2016-05-07 sam.>'\n        self.textinactive = u'[2016-05-07 sam.]'\n\n    def test_OrdDate_str_unicode_active(self):\n        with self.setlocale(self.UTF8_LOCALE):\n            od = OrgDate(True, self.year, self.month, self.day)\n            self.assertEqual(self.text, unicode(od))\n\n    def test_OrdDate_str_unicode_inactive(self):\n        with self.setlocale(self.UTF8_LOCALE):\n            od = OrgDate(False, self.year, self.month, self.day)\n            self.assertEqual(self.textinactive, unicode(od))\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(OrgDateUtf8TestCase)\n"
  },
  {
    "path": "tests/test_liborgdatetime.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport sys\nimport unittest\nfrom datetime import datetime\n\nsys.path.append(u'../ftplugin')\nfrom orgmode.liborgmode.orgdate import OrgDateTime\n\nfrom orgmode.py3compat.unicode_compatibility import *\n\nclass OrgDateTimeTestCase(unittest.TestCase):\n    u\"\"\"\n    Tests all the functionality of the OrgDateTime\n    \"\"\"\n\n    def test_OrgDateTime_ctor_active(self):\n        u\"\"\"OrdDateTime should be created.\"\"\"\n        today = datetime.today()\n        odt = OrgDateTime(True, today.year, today.month, today.day, today.hour,\n                today.minute)\n        self.assertTrue(isinstance(odt, OrgDateTime))\n        self.assertTrue(odt.active)\n\n    def test_OrgDateTime_ctor_inactive(self):\n        u\"\"\"OrdDateTime should be created.\"\"\"\n        today = datetime.today()\n        odt = OrgDateTime(False, today.year, today.month, today.day, today.hour,\n                today.minute)\n        self.assertTrue(isinstance(odt, OrgDateTime))\n        self.assertFalse(odt.active)\n\n    def test_OrdDateTime_str_active(self):\n        u\"\"\"Representation of OrgDateTime\"\"\"\n        t = 2011, 9, 8, 10, 20\n        odt = OrgDateTime(False, t[0], t[1], t[2], t[3], t[4])\n        self.assertEqual(u\"[2011-09-08 Thu 10:20]\", unicode(odt))\n\n    def test_OrdDateTime_str_inactive(self):\n        u\"\"\"Representation of OrgDateTime\"\"\"\n        t = 2011, 9, 8, 10, 20\n        odt = OrgDateTime(True, t[0], t[1], t[2], t[3], t[4])\n        self.assertEqual(u\"<2011-09-08 Thu 10:20>\", unicode(odt))\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(OrgDateTimeTestCase)\n"
  },
  {
    "path": "tests/test_liborgtimerange.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport sys\nimport unittest\nfrom datetime import date\nfrom datetime import datetime\n\nsys.path.append(u'../ftplugin')\nfrom orgmode.liborgmode.orgdate import OrgTimeRange\n\n\nclass OrgTimeRangeTestCase(unittest.TestCase):\n\n    def setUp(self):\n        self.date = date(2011, 8, 29)\n        self.year = 2011\n        self.month = 8\n        self.day = 29\n        self.text = '<2011-08-29 Mon>'\n        self.textinactive = '[2011-08-29 Mon]'\n\n    def test_OrgTimeRange_ctor_active(self):\n        u\"\"\"\n        timerange should be created.\n        \"\"\"\n        start = date(2011, 9 , 12)\n        end = date(2011, 9 , 13)\n        timerange = OrgTimeRange(True, start, end)\n        self.assertTrue(isinstance(timerange, OrgTimeRange))\n        self.assertTrue(timerange.active)\n\n    def test_OrgTimeRange_ctor_inactive(self):\n        u\"\"\"\n        timerange should be created.\n        \"\"\"\n        start = date(2011, 9 , 12)\n        end = date(2011, 9 , 13)\n        timerange = OrgTimeRange(False, start, end)\n        self.assertTrue(isinstance(timerange, OrgTimeRange))\n        self.assertFalse(timerange.active)\n\n    def test_OrdDate_str_active(self):\n        u\"\"\"Representation of OrgDates\"\"\"\n        start = date(2011, 9 , 12)\n        end = date(2011, 9 , 13)\n        timerange = OrgTimeRange(True, start, end)\n        expected = \"<2011-09-12 Mon>--<2011-09-13 Tue>\"\n        self.assertEqual(str(timerange), expected)\n\n        start = datetime(2011, 9 , 12, 20, 00)\n        end = datetime(2011, 9 , 13, 21, 59)\n        timerange = OrgTimeRange(True, start, end)\n        expected = \"<2011-09-12 Mon 20:00>--<2011-09-13 Tue 21:59>\"\n        self.assertEqual(str(timerange), expected)\n\n        start = datetime(2011, 9 , 12, 20, 00)\n        end = datetime(2011, 9 , 12, 21, 00)\n        timerange = OrgTimeRange(True, start, end)\n        expected = \"<2011-09-12 Mon 20:00-21:00>\"\n        self.assertEqual(str(timerange), expected)\n\n    def test_OrdDate_str_inactive(self):\n        u\"\"\"Representation of OrgDates\"\"\"\n        start = date(2011, 9 , 12)\n        end = date(2011, 9 , 13)\n        timerange = OrgTimeRange(False, start, end)\n        expected = \"[2011-09-12 Mon]--[2011-09-13 Tue]\"\n        self.assertEqual(str(timerange), expected)\n\n        start = datetime(2011, 9 , 12, 20, 00)\n        end = datetime(2011, 9 , 13, 21, 59)\n        timerange = OrgTimeRange(False, start, end)\n        expected = \"[2011-09-12 Mon 20:00]--[2011-09-13 Tue 21:59]\"\n        self.assertEqual(str(timerange), expected)\n\n        start = datetime(2011, 9 , 12, 20, 00)\n        end = datetime(2011, 9 , 12, 21, 00)\n        timerange = OrgTimeRange(False, start, end)\n        expected = \"[2011-09-12 Mon 20:00-21:00]\"\n        self.assertEqual(str(timerange), expected)\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(OrgTimeRangeTestCase)\n"
  },
  {
    "path": "tests/test_plugin_date.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom __future__ import print_function\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nfrom datetime import date\nfrom datetime import datetime\n\nfrom orgmode.plugins.Date import Date\n\n\nclass DateTestCase(unittest.TestCase):\n    u\"\"\"Tests all the functionality of the Date plugin.\n\n    Also see:\n    http://orgmode.org/manual/The-date_002ftime-prompt.html#The-date_002ftime-prompt\n    \"\"\"\n\n    def setUp(self):\n        self.d = date(2011, 5, 22)\n\n    def test_modify_time_with_None(self):\n        # no modification should happen\n        res = Date._modify_time(self.d, None)\n        self.assertEquals(self.d, res)\n\n    def test_modify_time_with_dot(self):\n        # no modification should happen\n        res = Date._modify_time(self.d, u'.')\n        self.assertEquals(self.d, res)\n\n    def test_modify_time_with_given_relative_days(self):\n        # modifier and expected result\n        test_data = [(u'+0d', self.d),\n                (u'+1d', date(2011, 5, 23)),\n                (u'+2d', date(2011, 5, 24)),\n                (u'+7d', date(2011, 5, 29)),\n                (u'+9d', date(2011, 5, 31)),\n                (u'+10d', date(2011, 6, 1)),\n                (u'7d', self.d)]  # wrong format: plus is missing\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(self.d, modifier))\n\n    def test_modify_time_with_given_relative_days_without_d(self):\n        # modifier and expected result\n        test_data = [(u'+0', self.d),\n                (u'+1', date(2011, 5, 23)),\n                (u'+2', date(2011, 5, 24)),\n                (u'+7', date(2011, 5, 29)),\n                (u'+9', date(2011, 5, 31)),\n                (u'+10', date(2011, 6, 1))]\n\n        for modifier, expected in test_data:\n            result = Date._modify_time(self.d, modifier)\n            self.assertEquals(expected, result)\n\n    def test_modify_time_with_given_relative_weeks(self):\n        # modifier and expected result\n        test_data = [(u'+1w', date(2011, 5, 29)),\n                (u'+2w', date(2011, 6, 5)),\n                (u'+3w', date(2011, 6, 12)),\n                (u'+3w', date(2011, 6, 12)),\n                (u'+0w', self.d),\n                (u'3w', self.d),  # wrong format\n                (u'+w', self.d)]  # wrong format\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(self.d, modifier))\n\n    def test_modify_time_with_given_relative_months(self):\n        test_data = [(u'+0m', self.d),\n                (u'+1m', date(2011, 6, 22)),\n                (u'+2m', date(2011, 7, 22))]\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(self.d, modifier))\n\n    def test_modify_time_with_given_relative_years(self):\n        test_data = [(u'+1y', date(2012, 5, 22)),\n                (u'+10y', date(2021, 5, 22)),\n                (u'+0y', self.d)]\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(self.d, modifier))\n\n\n    def test_modify_time_with_given_weekday(self):\n        # use custom day instead of self.d to ease testing\n        cust_day = date(2011, 5, 25)  # it's a Wednesday\n        #print(cust_day.weekday())  # 2\n        test_data = [(u'Thu', date(2011, 5, 26)),\n                (u'thu', date(2011, 5, 26)),\n                (u'tHU', date(2011, 5, 26)),\n                (u'THU', date(2011, 5, 26)),\n                (u'Fri', date(2011, 5, 27)),\n                (u'sat', date(2011, 5, 28)),\n                (u'sun', date(2011, 5, 29)),\n                (u'mon', date(2011, 5, 30)),\n                (u'tue', date(2011, 5, 31)),\n                (u'wed', date(2011, 6, 1))]\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(cust_day, modifier))\n\n    def test_modify_time_with_month_and_day(self):\n        cust_date = date(2006, 6, 13)\n        test_data = [(u'sep 15', date(2006, 9, 15)),\n                (u'Sep 15', date(2006, 9, 15)),\n                (u'SEP 15', date(2006, 9, 15)),\n                (u'feb 15', date(2007, 2, 15)),\n                (u'jan 1', date(2007, 1, 1)),\n                (u'7/5', date(2006, 7, 5)),\n                (u'2/5', date(2007, 2, 5)),]\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(cust_date, modifier))\n\n    def test_modify_time_with_time(self):\n        cust_date = date(2006, 6, 13)\n        test_data = [(u'12:45', datetime(2006, 6, 13, 12, 45)),\n                (u'1:45', datetime(2006, 6, 13, 1, 45)),\n                (u'1:05', datetime(2006, 6, 13, 1, 5)),]\n\n        for modifier, expected in test_data:\n            res = Date._modify_time(cust_date, modifier)\n            self.assertTrue(isinstance(res, datetime))\n            self.assertEquals(expected, res)\n\n    def test_modify_time_with_full_dates(self):\n        result = Date._modify_time(self.d, u'2011-01-12')\n        expected = date(2011, 1, 12)\n        self.assertEquals(expected, result)\n\n        reults = Date._modify_time(self.d, u'2015-03-12')\n        expected = date(2015, 3, 12)\n        self.assertEquals(expected, reults)\n\n        cust_date = date(2006, 6, 13)\n        test_data = [(u'3-2-5', date(2003, 2, 5)),\n                (u'12-2-28', date(2012, 2, 28)),\n                (u'2/5/3', date(2003, 2, 5)),\n                (u'sep 12 9', date(2009, 9, 12)),\n                (u'jan 2 99', date(2099, 1, 2)),]\n\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(cust_date, modifier))\n\n    def test_modify_time_with_only_days(self):\n        cust_date = date(2006, 6, 13)\n        test_data = [(u'14', date(2006, 6, 14)),\n                (u'12', date(2006, 7, 12)),\n                (u'1', date(2006, 7, 1)),\n                (u'29', date(2006, 6, 29)),]\n        for modifier, expected in test_data:\n            self.assertEquals(expected, Date._modify_time(cust_date, modifier))\n\n    def test_modify_time_with_day_and_time(self):\n        cust_date = date(2006, 6, 13)\n        test_data = [(u'+1 10:20', datetime(2006, 6, 14, 10, 20)),\n                (u'+1w 10:20', datetime(2006, 6, 20, 10, 20)),\n                (u'+2 10:30', datetime(2006, 6, 15, 10, 30)),\n                (u'+2d 10:30', datetime(2006, 6, 15, 10, 30))]\n        for modifier, expected in test_data:\n            result = Date._modify_time(cust_date, modifier)\n            self.assertEquals(expected, result)\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(DateTestCase)\n"
  },
  {
    "path": "tests/test_plugin_edit_checkbox.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode._vim import ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\nPLUGIN_NAME = u'EditCheckbox'\n\nbufnr = 10\n\ndef set_vim_buffer(buf=None, cursor=(2, 0), bufnr=0):\n    if buf is None:\n        buf = []\n    vim.current.buffer[:] = buf\n    vim.current.window.cursor = cursor\n    vim.current.buffer.number = bufnr\n\n\ncounter = 0\nclass EditCheckboxTestCase(unittest.TestCase):\n    def setUp(self):\n        if PLUGIN_NAME not in ORGMODE.plugins:\n            ORGMODE.register_plugin(PLUGIN_NAME)\n        self.editcheckbox = ORGMODE.plugins[PLUGIN_NAME]\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_improve_split_heading\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_improve_split_heading\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u'&ts'): u_encode(u'8'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0'),\n                # jump to insert mode after adding heading/checkbox\n                u_encode(u'exists(\"g:org_prefer_insert_mode\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_prefer_insert_mode\")'): u_encode(u'0')}\n\n        self.c1 = u\"\"\"\n* heading1 [%]\n  - [ ] checkbox1 [/]\n        - [ ] checkbox2\n        - [ ] checkbox3\n              - [ ] checkbox4\n  - [ ] checkbox5\n        - [ ] checkbox6\n              - [ ] checkbox7\n              - [ ] checkbox8\n\"\"\".split(u'\\n')\n\n        self.c2 = u\"\"\"\n* a checkbox list [%]\n  - checkbox [0%]\n        - [ ] test1\n        - [ ] test2\n        - [ ] test3\n\"\"\".split(u'\\n')\n\n        self.c3 = u\"\"\"\n* heading\n  1. [ ] another main task [%]\n         - [ ] sub task 1\n         - [ ] sub task 2\n  2. [ ] another main task\n\"\"\".split(u'\\n')\n\n        self.c4 = u\"\"\"\n* heading\n\"\"\".split(u'\\n')\n\n        self.c5 = u\"\"\"\n* heading1\n  1. item\n  9. item\n  }. item\n  a. item\n  z. item\n  A. item\n  Z. item\n  aa. item\n\"\"\".split(\"\\n\")\n\n    def test_toggle(self):\n        global bufnr\n        bufnr += 1\n        # test on self.c1\n        set_vim_buffer(buf=self.c1, cursor=(6, 0), bufnr=bufnr)\n        # update_checkboxes_status\n        self.editcheckbox.update_checkboxes_status()\n        self.assertEqual(vim.current.buffer[1], u\"* heading1 [0%]\")\n        # toggle\n        self.editcheckbox.toggle()\n        self.assertEqual(vim.current.buffer[5], u\"              - [X] checkbox4\")\n\n        bufnr += 1\n        set_vim_buffer(buf=self.c1, cursor=(9, 0), bufnr=bufnr)\n        # toggle and check checkbox status\n        self.editcheckbox.toggle()\n        self.assertEqual(vim.current.buffer[8], u\"              - [X] checkbox7\")\n        self.assertEqual(vim.current.buffer[7], u\"        - [-] checkbox6\")\n        self.assertEqual(vim.current.buffer[6], u\"  - [-] checkbox5\")\n\n        # new_checkbox\n        bufnr += 1\n        set_vim_buffer(buf=self.c1, cursor=(9, 0), bufnr=bufnr)\n        vim.current.window.cursor = (9, 0)\n        self.assertEqual(vim.current.buffer[9], u'              - [ ] checkbox8')\n        self.editcheckbox.new_checkbox(below=True)\n        # vim's buffer behave just opposite to Python's list when inserting a\n        # new item.  The new entry is appended in vim put prepended in Python!\n        self.assertEqual(vim.current.buffer[10], u'              - [ ] checkbox8')\n        self.assertEqual(vim.current.buffer[9], u'              - [ ] ')\n        self.editcheckbox.update_checkboxes_status()\n\n    def test_no_status_checkbox(self):\n        global bufnr\n        bufnr += 1\n        # test on self.c2\n        set_vim_buffer(buf=self.c2, bufnr=bufnr)\n        self.assertEqual(vim.current.buffer[2], u\"  - checkbox [0%]\")\n        # toggle\n        vim.current.window.cursor = (4, 0)\n        self.editcheckbox.toggle()\n        self.assertEqual(vim.current.buffer[3], u\"        - [X] test1\")\n\n        # self.editcheckbox.update_checkboxes_status()\n        # see if the no status checkbox update its status\n        self.assertEqual(vim.current.buffer[2], u\"  - checkbox [33%]\")\n\n    def test_number_list(self):\n        global bufnr\n        bufnr += 1\n        set_vim_buffer(buf=self.c3, bufnr=bufnr)\n        vim.current.window.cursor = (6, 0)\n        self.editcheckbox.toggle()\n        self.assertEqual(vim.current.buffer[5], u\"  2. [X] another main task\")\n\n    def test_new_checkbox(self):\n        global bufnr\n        bufnr += 1\n        set_vim_buffer(buf=self.c4, bufnr=bufnr)\n        vim.current.window.cursor = (2, 1)\n        self.editcheckbox.new_checkbox(below=True)\n        self.assertEqual(vim.current.buffer[2], u\"  - [ ] \")\n\n    def test_item_decrement(self):\n        global bufnr\n        bufnr += 1\n        set_vim_buffer(buf=self.c5, bufnr=bufnr)\n\n        vim.current.window.cursor = (3, 1)\n        self.editcheckbox.new_checkbox(below=False, plain=True)\n        self.assertEqual(vim.current.buffer[2], u\"  0. \")\n        self.assertEqual(vim.current.buffer[3], u\"  1. item\")\n\n        vim.current.window.cursor = (3, 1)\n        self.editcheckbox.new_checkbox(below=False, plain=True)\n        self.assertEqual(vim.current.buffer[1], u\"* heading1\")\n        self.assertEqual(vim.current.buffer[2], u\"  0. \")\n        self.assertEqual(vim.current.buffer[3], u\"  1. item\")\n\n        vim.current.window.cursor = (5, 1)\n        self.editcheckbox.new_checkbox(below=False, plain=True)\n        self.assertEqual(vim.current.buffer[4], u\"  8. \")\n        self.assertEqual(vim.current.buffer[5], u\"  9. item\")\n\n        vim.current.window.cursor = (8, 1)\n        self.editcheckbox.new_checkbox(below=False, plain=True)\n        # no further decrement than a\n        self.assertEqual(vim.current.buffer[6], u\"  }. item\")\n        self.assertEqual(vim.current.buffer[7], u\"  a. item\")\n        self.assertEqual(vim.current.buffer[8], u\"  z. item\")\n\n    def test_item_decrementA(self):\n        global bufnr\n        bufnr += 1\n        set_vim_buffer(buf=self.c5, bufnr=bufnr)\n        vim.current.window.cursor = (8, 1)\n        self.editcheckbox.new_checkbox(below=False, plain=True)\n        # decrement from A to z\n        self.assertEqual(vim.current.buffer[7], u\"  z. \")\n        self.assertEqual(vim.current.buffer[8], u\"  A. item\")\n\n    def test_item_increment(self):\n        global bufnr\n        bufnr += 1\n        set_vim_buffer(buf=self.c5, bufnr=bufnr)\n\n        vim.current.window.cursor = (3, 1)\n        self.editcheckbox.new_checkbox(below=True, plain=True)\n        self.assertEqual(vim.current.buffer[2], u\"  1. item\")\n        self.assertEqual(vim.current.buffer[3], u\"  2. \")\n\n        vim.current.window.cursor = (5, 1)\n        self.editcheckbox.new_checkbox(below=True, plain=True)\n        self.assertEqual(vim.current.buffer[4], u\"  9. item\")\n        self.assertEqual(vim.current.buffer[5], u\"  }. item\")\n        self.assertEqual(vim.current.buffer[6], u\"  10. \")\n\n    def test_item_incrementz(self):\n        global bufnr\n        bufnr += 1\n        set_vim_buffer(buf=self.c5, bufnr=bufnr)\n\n        vim.current.window.cursor = (6, 1)\n        self.editcheckbox.new_checkbox(below=True, plain=True)\n        self.assertEqual(vim.current.buffer[5], u\"  a. item\")\n        self.assertEqual(vim.current.buffer[6], u\"  b. \")\n\n        vim.current.window.cursor = (8, 1)\n        self.editcheckbox.new_checkbox(below=True, plain=True)\n        self.assertEqual(vim.current.buffer[7], u\"  z. item\")\n        self.assertEqual(vim.current.buffer[8], u\"  A. \")\n\n        vim.current.window.cursor = (11, 1)\n        self.editcheckbox.new_checkbox(below=True, plain=True)\n        self.assertEqual(vim.current.buffer[10], u\"  Z. item\")\n        self.assertEqual(vim.current.buffer[11], u\"  aa. item\")\n        self.assertEqual(vim.current.buffer[12], u\"\")\n\n        vim.current.window.cursor = (12, 1)\n        self.editcheckbox.new_checkbox(below=True, plain=True)\n        self.assertEqual(vim.current.buffer[11], u\"  aa. item\")\n        self.assertEqual(vim.current.buffer[12], u\"\")\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(EditCheckboxTestCase)\n"
  },
  {
    "path": "tests/test_plugin_edit_structure.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode._vim import ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ncounter = 0\nclass EditStructureTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_improve_split_heading\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_improve_split_heading\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u'&ts'): u_encode(u'8'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0'),\n                # jump to insert mode after adding heading/checkbox\n                u_encode(u'exists(\"g:org_prefer_insert_mode\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_prefer_insert_mode\")'): u_encode(u'0')}\n        if not u'EditStructure' in ORGMODE.plugins:\n            ORGMODE.register_plugin(u'EditStructure')\n        self.editstructure = ORGMODE.plugins[u'EditStructure']\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n')]\n\n    def test_new_heading_below_normal_behavior(self):\n        vim.current.window.cursor = (1, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True), None)\n        self.assertEqual(vim.current.buffer[0], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n\n    def test_new_heading_above_normal_behavior(self):\n        vim.current.window.cursor = (1, 1)\n        self.assertNotEqual(self.editstructure.new_heading(below=False), None)\n        self.assertEqual(vim.current.buffer[0], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n\n    def test_new_heading_below(self):\n        vim.current.window.cursor = (2, 0)\n        vim.current.buffer[5] = u_encode(u'** Überschrift 1.1 :Tag:')\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=False), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 6gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[4], u_encode(u'Bla bla'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[6], u_encode(u'** Überschrift 1.1 :Tag:'))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_new_heading_below_insert_mode(self):\n        vim.current.window.cursor = (2, 1)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 3gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[2], u_encode(u'* Überschrift 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'Bla bla'))\n        self.assertEqual(vim.current.buffer[6], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_new_heading_below_split_text_at_the_end(self):\n        vim.current.buffer[1] = u_encode(u'* Überschriftx1')\n        vim.current.window.cursor = (2, 14)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 3gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[2], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'Bla bla'))\n        self.assertEqual(vim.current.buffer[6], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_new_heading_below_split_text_at_the_end_insert_parts(self):\n        vim.current.window.cursor = (2, 14)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 3gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[2], u_encode(u'* 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'Bla bla'))\n        self.assertEqual(vim.current.buffer[6], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_new_heading_below_in_the_middle(self):\n        vim.current.window.cursor = (10, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 13gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[11], u_encode(u''))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'** '))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n\n    def test_new_heading_below_in_the_middle2(self):\n        vim.current.window.cursor = (13, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 16gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[14], u_encode(u'Bla Bla bla bla'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'**** '))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n\n    def test_new_heading_below_in_the_middle3(self):\n        vim.current.window.cursor = (16, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 17gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** '))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_new_heading_below_at_the_end(self):\n        vim.current.window.cursor = (18, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 21gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[19], u_encode(u''))\n        self.assertEqual(vim.current.buffer[20], u_encode(u'* '))\n        self.assertEqual(len(vim.current.buffer), 21)\n\n    def test_new_heading_above(self):\n        vim.current.window.cursor = (2, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=False, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 2gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[0], u_encode(u''))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[2], u_encode(u'* Überschrift 1'))\n\n    def test_new_heading_above_in_the_middle(self):\n        vim.current.window.cursor = (10, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=False, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 10gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[8], u_encode(u'Bla Bla bla'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'** '))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'** Überschrift 1.2'))\n\n    def test_new_heading_above_in_the_middle2(self):\n        vim.current.window.cursor = (13, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=False, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 13gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[11], u_encode(u''))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'**** '))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n\n    def test_new_heading_above_in_the_middle3(self):\n        vim.current.window.cursor = (16, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=False, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 16gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[14], u_encode(u'Bla Bla bla bla'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'*** '))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n\n    def test_new_heading_above_at_the_end(self):\n        vim.current.window.cursor = (18, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=False, insert_mode=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 18gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'* Überschrift 2'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[18], u_encode(u'* Überschrift 3'))\n\n    def test_new_heading_below_split_heading_title(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1  :Tag:\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n')]\n        vim.current.window.cursor = (2, 6)\n        self.assertNotEqual(self.editstructure.new_heading(insert_mode=True), None)\n        self.assertEqual(vim.current.buffer[0], u_encode(u''))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Über\t\t\t\t\t\t\t\t\t:Tag:'))\n        self.assertEqual(vim.current.buffer[2], u_encode(u'* schrift 1'))\n        self.assertEqual(vim.current.buffer[3], u_encode(u'Text 1'))\n\n    def test_new_heading_below_split_heading_title_with_todo(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* TODO Überschrift 1  :Tag:\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n')]\n        vim.current.window.cursor = (2, 5)\n        self.assertNotEqual(self.editstructure.new_heading(insert_mode=True), None)\n        self.assertEqual(vim.current.buffer[0], u_encode(u''))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* TODO\t\t\t\t\t\t\t\t\t:Tag:'))\n        self.assertEqual(vim.current.buffer[2], u_encode(u'* Überschrift 1'))\n        self.assertEqual(vim.current.buffer[3], u_encode(u'Text 1'))\n\n    def test_demote_heading(self):\n        vim.current.window.cursor = (13, 0)\n        self.assertNotEqual(self.editstructure.demote_heading(), None)\n        self.assertEqual(vim.current.buffer[10], u_encode(u'Text 3'))\n        self.assertEqual(vim.current.buffer[11], u_encode(u''))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'***** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u''))\n        # actually the indentation comes through vim, just the heading is updated\n        self.assertEqual(vim.current.buffer[14], u_encode(u'Bla Bla bla bla'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.window.cursor, (13, 1))\n\n    def test_demote_newly_created_level_one_heading(self):\n        vim.current.window.cursor = (2, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True), None)\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'* '))\n        self.assertEqual(vim.current.buffer[6], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n        vim.current.window.cursor = (6, 2)\n        self.assertNotEqual(self.editstructure.demote_heading(), None)\n        self.assertEqual(vim.current.buffer[5], u_encode(u'** '))\n        self.assertEqual(vim.current.buffer[6], u_encode(u'*** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[10], u_encode(u'*** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'***** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'**** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_demote_newly_created_level_two_heading(self):\n        vim.current.window.cursor = (10, 0)\n        self.assertNotEqual(self.editstructure.new_heading(below=True), None)\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'** '))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n        vim.current.window.cursor = (13, 3)\n        self.assertNotEqual(self.editstructure.demote_heading(including_children=False, on_heading=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'exe \"normal 13gg\"|startinsert!'))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'*** '))\n        self.assertEqual(vim.current.buffer[13], u_encode(u'**** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[17], u_encode(u'* Überschrift 2'))\n\n    def test_demote_last_heading(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 2\n* Überschrift 3\"\"\".split('\\n')]\n        vim.current.window.cursor = (3, 0)\n        h = ORGMODE.get_document().current_heading()\n        self.assertNotEqual(self.editstructure.demote_heading(), None)\n        self.assertEqual(h.end, 2)\n        self.assertFalse(vim.CMDHISTORY)\n        self.assertEqual(vim.current.buffer[2], u_encode(u'** Überschrift 3'))\n        self.assertEqual(vim.current.window.cursor, (3, 1))\n\n    def test_promote_heading(self):\n        vim.current.window.cursor = (13, 0)\n        self.assertNotEqual(self.editstructure.promote_heading(), None)\n        self.assertEqual(vim.current.buffer[10], u_encode(u'Text 3'))\n        self.assertEqual(vim.current.buffer[11], u_encode(u''))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'*** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[13], u_encode(u''))\n        # actually the indentation comes through vim, just the heading is updated\n        self.assertEqual(vim.current.buffer[14], u_encode(u'Bla Bla bla bla'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'*** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.window.cursor, (13, -1))\n\n    def test_promote_level_one_heading(self):\n        vim.current.window.cursor = (2, 0)\n        self.assertEqual(self.editstructure.promote_heading(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 0)\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_demote_parent_heading(self):\n        vim.current.window.cursor = (2, 0)\n        self.assertNotEqual(self.editstructure.demote_heading(), None)\n        self.assertEqual(vim.current.buffer[1], u_encode(u'** Überschrift 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'*** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'*** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'***** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'**** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'* Überschrift 2'))\n        self.assertEqual(vim.current.window.cursor, (2, 1))\n\n    def test_promote_parent_heading(self):\n        vim.current.window.cursor = (10, 0)\n        self.assertNotEqual(self.editstructure.promote_heading(), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal 10ggV16gg='))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'* Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'*** Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'* Überschrift 2'))\n        self.assertEqual(vim.current.window.cursor, (10, -1))\n\n    # run tests with count\n    def test_demote_parent_heading_count(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u\"v:count\"] = u_encode(u'3')\n        self.assertNotEqual(self.editstructure.demote_heading(), None)\n        self.assertEqual(vim.current.buffer[1], u_encode(u'**** Überschrift 1'))\n        self.assertEqual(vim.current.buffer[5], u_encode(u'***** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'***** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'******* Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'****** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'* Überschrift 2'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'* Überschrift 2'))\n        self.assertEqual(vim.current.window.cursor, (2, 3))\n\n    def test_promote_parent_heading(self):\n        vim.current.window.cursor = (13, 0)\n        vim.EVALRESULTS[u\"v:count\"] = u_encode(u'3')\n        self.assertNotEqual(self.editstructure.promote_heading(), None)\n        self.assertEqual(vim.current.buffer[5], u_encode(u'** Überschrift 1.1'))\n        self.assertEqual(vim.current.buffer[9], u_encode(u'** Überschrift 1.2'))\n        self.assertEqual(vim.current.buffer[12], u_encode(u'* Überschrift 1.2.1.falsch'))\n        self.assertEqual(vim.current.buffer[15], u_encode(u'** Überschrift 1.2.1'))\n        self.assertEqual(vim.current.buffer[16], u_encode(u'* Überschrift 2'))\n        self.assertEqual(vim.current.window.cursor, (13, -3))\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(EditStructureTestCase)\n"
  },
  {
    "path": "tests/test_plugin_mappings.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom __future__ import print_function\n\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport unittest\nimport orgmode.settings\nfrom orgmode.exceptions import PluginError\nfrom orgmode._vim import ORGMODE\nfrom orgmode.keybinding import MODE_ALL, Plug\n\nimport vim\n\nfrom orgmode.py3compat.encode_compatibility import *\n\nORG_PLUGINS = ['ShowHide', '|', 'Navigator', 'EditStructure', '|', 'Hyperlinks', '|', 'Todo', 'TagsProperties', 'Date', 'Agenda', 'Misc', '|', 'Export']\n\n\nclass MappingTestCase(unittest.TestCase):\n    u\"\"\"Tests all plugins for overlapping mappings.\"\"\"\n    def test_non_overlapping_plug_mappings(self):\n        def find_overlapping_mappings(kb, all_keybindings):\n            found_overlapping_mapping = False\n            for tkb in all_keybindings:\n                if kb.mode == tkb.mode or MODE_ALL in (kb.mode, tkb.mode):\n                    if isinstance(kb._action, Plug) and isinstance(tkb._action, Plug):\n                        akb = kb.action\n                        atkb = tkb.action\n                        if (akb.startswith(atkb) or atkb.startswith(akb)) and akb != atkb:\n                            print(u'\\nERROR: Found overlapping mapping: %s (%s), %s (%s)' % (kb.key, akb, tkb.key, atkb))\n                            found_overlapping_mapping = True\n\n            if all_keybindings:\n                res = find_overlapping_mappings(all_keybindings[0], all_keybindings[1:])\n                if not found_overlapping_mapping:\n                    return res\n            return found_overlapping_mapping\n\n        if self.keybindings:\n            self.assertFalse(find_overlapping_mappings(self.keybindings[0], self.keybindings[1:]))\n\n    def setUp(self):\n        self.keybindings = []\n\n        vim.EVALRESULTS = {\n                u'exists(\"g:org_debug\")': 0,\n                u'exists(\"b:org_debug\")': 0,\n                u'exists(\"*repeat#set()\")': 0,\n                u'b:changedtick': 0,\n                u_encode(u'exists(\"b:org_plugins\")'): 0,\n                u_encode(u'exists(\"g:org_plugins\")'): 1,\n                u_encode(u'g:org_plugins'): ORG_PLUGINS,\n                }\n        for plugin in filter(lambda p: p != '|', ORG_PLUGINS):\n            try:\n                ORGMODE.register_plugin(plugin)\n            except PluginError:\n                pass\n            if plugin in ORGMODE._plugins:\n                self.keybindings.extend(ORGMODE._plugins[plugin].keybindings)\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(MappingTestCase)\n"
  },
  {
    "path": "tests/test_plugin_misc.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode._vim import indent_orgmode, fold_orgmode, ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\nORGMODE.debug = True\n\nSTART = True\nEND = False\n\ncounter = 0\nclass MiscTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u\"v:lnum\"): u_encode(u'0')}\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n\n    def test_indent_noheading(self):\n        # test first heading\n        vim.current.window.cursor = (1, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'1')\n        indent_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 0)\n\n    def test_indent_heading(self):\n        # test first heading\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'2')\n        indent_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 0)\n\n    def test_indent_heading_middle(self):\n        # test first heading\n        vim.current.window.cursor = (3, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'3')\n        indent_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:indent_level = 2'))\n\n    def test_indent_heading_middle2(self):\n        # test first heading\n        vim.current.window.cursor = (4, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'4')\n        indent_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:indent_level = 2'))\n\n    def test_indent_heading_end(self):\n        # test first heading\n        vim.current.window.cursor = (5, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'5')\n        indent_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:indent_level = 2'))\n\n    def test_fold_heading_start(self):\n        # test first heading\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'2')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = \">1\"'))\n\n    def test_fold_heading_middle(self):\n        # test first heading\n        vim.current.window.cursor = (3, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'3')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = 1'))\n\n    def test_fold_heading_end(self):\n        # test first heading\n        vim.current.window.cursor = (5, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'5')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = 1'))\n\n    def test_fold_heading_end_of_last_child(self):\n        # test first heading\n        vim.current.window.cursor = (16, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'16')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        # which is also end of the parent heading <1\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = \">3\"'))\n\n    def test_fold_heading_end_of_last_child_next_heading(self):\n        # test first heading\n        vim.current.window.cursor = (17, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'17')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = \">1\"'))\n\n    def test_fold_middle_subheading(self):\n        # test first heading\n        vim.current.window.cursor = (13, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'13')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = \">4\"'))\n\n    def test_fold_middle_subheading2(self):\n        # test first heading\n        vim.current.window.cursor = (14, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'14')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = 4'))\n\n    def test_fold_middle_subheading3(self):\n        # test first heading\n        vim.current.window.cursor = (15, 0)\n        vim.EVALRESULTS[u_encode(u'v:lnum')] = u_encode(u'15')\n        fold_orgmode()\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'let b:fold_expr = 4'))\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(MiscTestCase)\n"
  },
  {
    "path": "tests/test_plugin_navigator.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode._vim import ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\nSTART = True\nEND = False\n\ndef set_visual_selection(visualmode, line_start, line_end, col_start=1,\n        col_end=1, cursor_pos=START):\n\n    if visualmode not in (u'\u0016', u'V', u'v'):\n        raise ValueError(u'Illegal value for visualmode, must be in \u0016, V, v')\n\n    vim.EVALRESULTS['visualmode()'] = visualmode\n\n    # getpos results [bufnum, lnum, col, off]\n    vim.EVALRESULTS['getpos(\"\\'<\")'] = ('', '%d' % line_start, '%d' %\n            col_start, '')\n    vim.EVALRESULTS['getpos(\"\\'>\")'] = ('', '%d' % line_end, '%d' %\n            col_end, '')\n    if cursor_pos == START:\n        vim.current.window.cursor = (line_start, col_start)\n    else:\n        vim.current.window.cursor = (line_end, col_end)\n\n\ncounter = 0\nclass NavigatorTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u\"v:count\"): u_encode(u'0'),\n                }\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n\n        if not u'Navigator' in ORGMODE.plugins:\n            ORGMODE.register_plugin(u'Navigator')\n        self.navigator = ORGMODE.plugins[u'Navigator']\n\n    def test_movement(self):\n        # test movement outside any heading\n        vim.current.window.cursor = (1, 0)\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (1, 0))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n    def test_forward_movement(self):\n        # test forward movement\n        vim.current.window.cursor = (2, 0)\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (6, 3))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (13, 5))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (16, 4))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (17, 2))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n\n        ## don't move cursor if last heading is already focused\n        vim.current.window.cursor = (19, 6)\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (19, 6))\n\n        ## test movement with count\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'-1')\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (6, 3))\n\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'0')\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (6, 3))\n\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'1')\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (6, 3))\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'3')\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (16, 4))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n        self.navigator.next(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'0')\n\n    def test_backward_movement(self):\n        # test backward movement\n        vim.current.window.cursor = (19, 6)\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (17, 2))\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (16, 4))\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (13, 5))\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (6, 3))\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n        ## test movement with count\n        vim.current.window.cursor = (19, 6)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'-1')\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n\n        vim.current.window.cursor = (19, 6)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'0')\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (18, 2))\n\n        vim.current.window.cursor = (19, 6)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'3')\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (16, 4))\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'4')\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'4')\n        self.navigator.previous(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n    def test_parent_movement(self):\n        # test movement to parent\n        vim.current.window.cursor = (2, 0)\n        self.assertEqual(self.navigator.parent(mode=u'normal'), None)\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n        vim.current.window.cursor = (3, 4)\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (3, 4))\n\n        vim.current.window.cursor = (16, 4)\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n        vim.current.window.cursor = (15, 6)\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n        ## test movement with count\n        vim.current.window.cursor = (16, 4)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'-1')\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n\n        vim.current.window.cursor = (16, 4)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'0')\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n\n        vim.current.window.cursor = (16, 4)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'1')\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (10, 3))\n\n        vim.current.window.cursor = (16, 4)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'2')\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n        vim.current.window.cursor = (16, 4)\n        vim.EVALRESULTS[u_encode(u\"v:count\")] = u_encode(u'3')\n        self.navigator.parent(mode=u'normal')\n        self.assertEqual(vim.current.window.cursor, (2, 2))\n\n    def test_next_parent_movement(self):\n        # test movement to parent\n        vim.current.window.cursor = (6, 0)\n        self.assertNotEqual(self.navigator.parent_next_sibling(mode=u'normal'), None)\n        self.assertEqual(vim.current.window.cursor, (17, 2))\n\n    def test_forward_movement_visual(self):\n        # selection start: <<\n        # selection end:   >>\n        # cursor position: |\n\n        # << text\n        # text| >>\n        # text\n        # heading\n        set_visual_selection(u'V', 2, 4, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV5gg'))\n\n        # << text\n        # text\n        # text| >>\n        # heading\n        set_visual_selection(u'V', 2, 5, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV9gg'))\n\n        # << text\n        # x. heading\n        # text| >>\n        # heading\n        set_visual_selection(u'V', 12, 14, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV15gg'))\n\n        set_visual_selection(u'V', 12, 15, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV16gg'))\n\n        set_visual_selection(u'V', 12, 16, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV17gg'))\n\n        # << text\n        # text\n        # text| >>\n        # heading\n        # EOF\n        set_visual_selection(u'V', 15, 17, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 15ggV20gg'))\n\n        # << text >>\n        # heading\n        set_visual_selection(u'V', 1, 1, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 1ggV5gg'))\n\n        # << heading >>\n        # text\n        # heading\n        set_visual_selection(u'V', 2, 2, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV5gg'))\n\n        # << text >>\n        # heading\n        set_visual_selection(u'V', 1, 1, cursor_pos=END)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 1ggV5gg'))\n\n        # << |text\n        # heading\n        # text\n        # heading\n        # text >>\n        set_visual_selection(u'V', 1, 8, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV8ggo'))\n\n        # << |heading\n        # text\n        # heading\n        # text >>\n        set_visual_selection(u'V', 2, 8, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 6ggV8ggo'))\n\n        # << |heading\n        # text >>\n        # heading\n        set_visual_selection(u'V', 6, 8, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 8ggV9gg'))\n\n        # << |x. heading\n        # text >>\n        # heading\n        set_visual_selection(u'V', 13, 15, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 15ggV15gg'))\n\n        set_visual_selection(u'V', 13, 16, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16ggV16ggo'))\n\n        set_visual_selection(u'V', 16, 16, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16ggV17gg'))\n\n        # << |x. heading\n        # text >>\n        # heading\n        # EOF\n        set_visual_selection(u'V', 17, 17, cursor_pos=START)\n        self.assertNotEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 17ggV20gg'))\n\n        # << |heading\n        # text>>\n        # text\n        # EOF\n        set_visual_selection(u'V', 18, 19, cursor_pos=START)\n        self.assertEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 19ggV20gg'))\n\n        # << heading\n        # text|>>\n        # text\n        # EOF\n        set_visual_selection(u'V', 18, 19, cursor_pos=END)\n        self.assertEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 18ggV20gg'))\n\n        # << heading\n        # text|>>\n        # EOF\n        set_visual_selection(u'V', 18, 20, cursor_pos=END)\n        self.assertEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 18ggV20gg'))\n\n        # << |heading\n        # text>>\n        # EOF\n        set_visual_selection(u'V', 20, 20, cursor_pos=START)\n        self.assertEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 20ggV20gg'))\n\n    def test_forward_movement_visual_to_the_end_of_the_file(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\ntest\n\"\"\".split(u'\\n') ]\n        # << |heading\n        # text>>\n        # EOF\n        set_visual_selection(u'V', 15, 15, cursor_pos=START)\n        self.assertEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 15ggV17gg'))\n\n        set_visual_selection(u'V', 15, 17, cursor_pos=END)\n        self.assertEqual(self.navigator.next(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 15ggV17gg'))\n\n    def test_backward_movement_visual(self):\n        # selection start: <<\n        # selection end:   >>\n        # cursor position: |\n\n        # << text | >>\n        # text\n        # heading\n        set_visual_selection(u'V', 1, 1, cursor_pos=START)\n        self.assertEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! gv'))\n\n        set_visual_selection(u'V', 1, 1, cursor_pos=END)\n        self.assertEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! gv'))\n\n        # << heading| >>\n        # text\n        # heading\n        set_visual_selection(u'V', 2, 2, cursor_pos=START)\n        self.assertEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV2ggo'))\n\n        set_visual_selection(u'V', 2, 2, cursor_pos=END)\n        self.assertEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV2ggo'))\n\n        # heading\n        # text\n        # << |text\n        # text >>\n        set_visual_selection(u'V', 3, 5, cursor_pos=START)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV5ggo'))\n\n        # heading\n        # text\n        # << text\n        # text| >>\n        set_visual_selection(u'V', 3, 5, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV3ggo'))\n\n        # heading\n        # text\n        # << text\n        # text| >>\n        set_visual_selection(u'V', 8, 9, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 6ggV8ggo'))\n\n        # heading\n        # << text\n        # x. heading\n        # text| >>\n        set_visual_selection(u'V', 12, 14, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV12gg'))\n\n        set_visual_selection(u'V', 12, 15, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV12gg'))\n\n        # heading\n        # << |text\n        # x. heading\n        # text >>\n        set_visual_selection(u'V', 12, 15, cursor_pos=START)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 10ggV15ggo'))\n\n        # heading\n        # << text\n        # x. heading| >>\n        set_visual_selection(u'V', 12, 13, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV12gg'))\n\n        # heading\n        # << text\n        # heading\n        # text\n        # x. heading| >>\n        set_visual_selection(u'V', 12, 16, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV15gg'))\n\n        # << text\n        # heading\n        # text\n        # heading| >>\n        set_visual_selection(u'V', 15, 17, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 15ggV16gg'))\n\n        # heading\n        # << |text\n        # text\n        # heading\n        # text >>\n        set_visual_selection(u'V', 4, 8, cursor_pos=START)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV8ggo'))\n\n        # heading\n        # << text\n        # text\n        # heading\n        # text| >>\n        set_visual_selection(u'V', 4, 8, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 4ggV5gg'))\n\n        # heading\n        # << text\n        # text\n        # heading\n        # text| >>\n        set_visual_selection(u'V', 4, 5, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV4ggo'))\n\n        # BOF\n        # << |heading\n        # text\n        # heading\n        # text >>\n        set_visual_selection(u'V', 2, 8, cursor_pos=START)\n        self.assertEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV8ggo'))\n\n        # BOF\n        # heading\n        # << text\n        # text| >>\n        set_visual_selection(u'V', 3, 4, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV3ggo'))\n\n        # BOF\n        # << heading\n        # text\n        # text| >>\n        set_visual_selection(u'V', 2, 4, cursor_pos=END)\n        self.assertNotEqual(self.navigator.previous(mode=u'visual'), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV2ggo'))\n\n        # << text\n        # heading\n        # text\n        # x. heading\n        # text| >>\n        set_visual_selection(u'V', 8, 14, cursor_pos=END)\n        self.navigator.previous(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 8ggV12gg'))\n\n    def test_parent_movement_visual(self):\n        # selection start: <<\n        # selection end:   >>\n        # cursor position: |\n\n        # heading\n        # << text|\n        # text\n        # text >>\n        set_visual_selection(u'V', 4, 8, cursor_pos=START)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! gv'))\n\n        # heading\n        # << text|\n        # text\n        # text >>\n        set_visual_selection(u'V', 6, 8, cursor_pos=START)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV8ggo'))\n\n        # heading\n        # << text\n        # text\n        # text| >>\n        set_visual_selection(u'V', 6, 8, cursor_pos=END)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 6ggV5gg'))\n\n        # << |heading\n        # text\n        # text\n        # text >>\n        set_visual_selection(u'V', 2, 8, cursor_pos=START)\n        self.assertEqual(self.navigator.parent(mode=u'visual'), None)\n\n        # << heading\n        # text\n        # heading\n        # text| >>\n        set_visual_selection(u'V', 2, 8, cursor_pos=END)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV5gg'))\n\n        set_visual_selection(u'V', 7, 8, cursor_pos=START)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV8ggo'))\n\n        # heading\n        # heading\n        # << text\n        # text| >>\n        set_visual_selection(u'V', 12, 13, cursor_pos=END)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 12ggV12gg'))\n\n        set_visual_selection(u'V', 10, 12, cursor_pos=START)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggV12ggo'))\n\n        # heading\n        # << text\n        # text\n        # heading| >>\n        set_visual_selection(u'V', 11, 17, cursor_pos=END)\n        self.assertEqual(self.navigator.parent(mode=u'visual'), None)\n\n        # << text\n        # heading\n        # text\n        # x. heading\n        # text| >>\n        set_visual_selection(u'V', 8, 14, cursor_pos=END)\n        self.navigator.parent(mode=u'visual')\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 8ggV12gg'))\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(NavigatorTestCase)\n"
  },
  {
    "path": "tests/test_plugin_show_hide.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode._vim import ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ncounter = 0\nclass ShowHideTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u\"v:count\"): u_encode(u'0')}\n        if not u'ShowHide' in ORGMODE.plugins:\n            ORGMODE.register_plugin(u'ShowHide')\n        self.showhide = ORGMODE.plugins[u'ShowHide']\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n\n    def test_no_heading_toggle_folding(self):\n        vim.current.window.cursor = (1, 0)\n        self.assertEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(vim.EVALHISTORY[-1], u_encode(u'feedkeys(\"<Tab>\", \"n\")'))\n        self.assertEqual(vim.current.window.cursor, (1, 0))\n\n    def test_toggle_folding_first_heading_with_no_children(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'2'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(7)'): u_encode(u'-1'),\n                })\n        vim.current.window.cursor = (2, 0)\n\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 1zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_close_one(self):\n        vim.current.window.cursor = (13, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(13)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 2)\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'13,15foldclose!'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2zo'))\n        self.assertEqual(vim.current.window.cursor, (13, 0))\n\n    def test_toggle_folding_open_one(self):\n        vim.current.window.cursor = (10, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(10)'): u_encode(u'10'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 1zo'))\n        self.assertEqual(vim.current.window.cursor, (10, 0))\n\n    def test_toggle_folding_close_multiple_all_open(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(16)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'2,16foldclose!'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_all_closed(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'2'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 1zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_first_level_open(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'6'),\n                u_encode(u'foldclosed(10)'): u_encode(u'10'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 2)\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 6gg1zo'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 10gg1zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_second_level_half_open(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'10'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 4)\n        self.assertEqual(vim.CMDHISTORY[-4], u_encode(u'normal! 6gg2zo'))\n        self.assertEqual(vim.CMDHISTORY[-3], u_encode(u'normal! 10gg2zo'))\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 13gg2zo'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16gg2zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_other_second_level_half_open(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'6'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 4)\n        self.assertEqual(vim.CMDHISTORY[-4], u_encode(u'normal! 6gg2zo'))\n        self.assertEqual(vim.CMDHISTORY[-3], u_encode(u'normal! 10gg2zo'))\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 13gg2zo'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16gg2zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_third_level_half_open(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 4)\n        self.assertEqual(vim.CMDHISTORY[-4], u_encode(u'normal! 6gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-3], u_encode(u'normal! 10gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 13gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16gg3zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_other_third_level_half_open(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 4)\n        self.assertEqual(vim.CMDHISTORY[-4], u_encode(u'normal! 6gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-3], u_encode(u'normal! 10gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 13gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16gg3zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_other_third_level_half_open_second_level_half_closed(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'6'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(), None)\n        self.assertEqual(len(vim.CMDHISTORY), 4)\n        self.assertEqual(vim.CMDHISTORY[-4], u_encode(u'normal! 6gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-3], u_encode(u'normal! 10gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 13gg3zo'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16gg3zo'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_no_heading_toggle_folding_reverse(self):\n        vim.current.window.cursor = (1, 0)\n        self.assertEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(vim.EVALHISTORY[-1], u_encode(u'feedkeys(\"<Tab>\", \"n\")'))\n        self.assertEqual(vim.current.window.cursor, (1, 0))\n\n    def test_toggle_folding_first_heading_with_no_children_reverse(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'2'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(7)'): u_encode(u'-1'),\n                })\n        vim.current.window.cursor = (2, 0)\n\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'2,5foldopen!'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_close_one_reverse(self):\n        vim.current.window.cursor = (13, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(13)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 13ggzc'))\n        self.assertEqual(vim.current.window.cursor, (13, 0))\n\n    def test_toggle_folding_open_one_reverse(self):\n        vim.current.window.cursor = (10, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(10)'): u_encode(u'10'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'10,16foldopen!'))\n        self.assertEqual(vim.current.window.cursor, (10, 0))\n\n    def test_toggle_folding_close_multiple_all_open_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(16)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 2)\n        self.assertEqual(vim.CMDHISTORY[-2], u_encode(u'normal! 13ggzc'))\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_all_closed_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'2'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'2,16foldopen!'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_first_level_open_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'6'),\n                u_encode(u'foldclosed(10)'): u_encode(u'10'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 2ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_second_level_half_open_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'10'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 6ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_other_second_level_half_open_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'6'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 10ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_third_level_half_open_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(16)'): u_encode(u'16'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 13ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_other_third_level_half_open_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\n    def test_toggle_folding_open_multiple_other_third_level_half_open_second_level_half_closed_reverse(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS.update({\n                u_encode(u'foldclosed(2)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(6)'): u_encode(u'6'),\n                u_encode(u'foldclosed(10)'): u_encode(u'-1'),\n                u_encode(u'foldclosed(13)'): u_encode(u'13'),\n                u_encode(u'foldclosed(16)'): u_encode(u'-1'),\n                })\n        self.assertNotEqual(self.showhide.toggle_folding(reverse=True), None)\n        self.assertEqual(len(vim.CMDHISTORY), 1)\n        self.assertEqual(vim.CMDHISTORY[-1], u_encode(u'normal! 16ggzc'))\n        self.assertEqual(vim.current.window.cursor, (2, 0))\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(ShowHideTestCase)\n"
  },
  {
    "path": "tests/test_plugin_tags_properties.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode._vim import indent_orgmode, fold_orgmode, ORGMODE\n\nfrom orgmode.py3compat.encode_compatibility import *\n\nORGMODE.debug = True\n\nSTART = True\nEND = False\n\ncounter = 0\nclass TagsPropertiesTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'&ts'): u_encode(u'6'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): (u_encode(u'%d' % counter)),\n                u_encode(u\"v:count\"): u_encode(u'0')}\n        if not u'TagsProperties' in ORGMODE.plugins:\n            ORGMODE.register_plugin(u'TagsProperties')\n        self.tagsproperties = ORGMODE.plugins[u'TagsProperties']\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n\n    def test_new_property(self):\n        u\"\"\" TODO: Docstring for test_new_property\n\n        :returns: TODO\n        \"\"\"\n        pass\n\n    def test_set_tags(self):\n        # set first tag\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t\\t    :hello:'))\n\n        # set second tag\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \":hello:\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello:world:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\n    def test_parse_tags_no_colons_single_tag(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u'hello')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t\\t    :hello:'))\n\n    def test_parse_tags_no_colons_multiple_tags(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u'hello:world')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\n    def test_parse_tags_single_colon_left_single_tag(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t\\t    :hello:'))\n\n    def test_parse_tags_single_colon_left_multiple_tags(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello:world')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\n    def test_parse_tags_single_colon_right_single_tag(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u'hello:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t\\t    :hello:'))\n\n    def test_parse_tags_single_colon_right_multiple_tags(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u'hello:world:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\n    def test_filter_empty_tags(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u'::hello::')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t\\t    :hello:'))\n\n    def test_delete_tags(self):\n        # set up\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello:world:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\n        # delete second of two tags\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \":hello:world:\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t\\t    :hello:'))\n\n        # delete last tag\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \":hello:\", \"customlist,Org_complete_tags\")')] = u_encode(u'')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n\n    def test_realign_tags_noop(self):\n        vim.current.window.cursor = (2, 0)\n        self.tagsproperties.realign_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n\n    def test_realign_tags_remove_spaces(self):\n        # remove spaces in multiple locations\n        vim.current.buffer[1] = u_encode(u'*  Überschrift 1 ')\n        vim.current.window.cursor = (2, 0)\n        self.tagsproperties.realign_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n\n        # remove tabs and spaces in multiple locations\n        vim.current.buffer[1] = u_encode(u'*\\t  \\tÜberschrift 1 \\t')\n        vim.current.window.cursor = (2, 0)\n        self.tagsproperties.realign_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1'))\n\n    def test_realign_tags(self):\n        vim.current.window.cursor = (2, 0)\n        vim.EVALRESULTS[u_encode(u'input(\"Tags: \", \"\", \"customlist,Org_complete_tags\")')] = u_encode(u':hello:world:')\n        self.tagsproperties.set_tags()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\n        d = ORGMODE.get_document()\n        heading = d.find_current_heading()\n        self.assertEqual(str(heading), u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n        self.tagsproperties.realign_tags()\n        heading = d.find_current_heading()\n        self.assertEqual(str(heading), u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n        self.assertEqual(vim.current.buffer[1], u_encode(u'* Überschrift 1\\t\\t\\t\\t\\t\\t\\t\\t    :hello:world:'))\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(TagsPropertiesTestCase)\n"
  },
  {
    "path": "tests/test_plugin_todo.py",
    "content": "# -*- coding: utf-8 -*-\n\n\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport unittest\nfrom orgmode.liborgmode.base import Direction\nfrom orgmode.vimbuffer import VimBuffer\nfrom orgmode.plugins.Todo import Todo\n\nimport vim\n\nfrom orgmode.py3compat.encode_compatibility import *\n\ncounter = 0\n\nclass TodoTestCase(unittest.TestCase):\n    u\"\"\"Tests all the functionality of the TODO module.\"\"\"\n\n    def setUp(self):\n        # set content of the buffer\n        global counter\n        counter += 1\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u\"v:count\"): u_encode(u'0')\n                }\n\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Heading 1\n** Text 1\n*** Text 2\n* Text 1\n** Text 1\n   some text that is\n   no heading\n\n\"\"\".split(u'\\n') ]\n\n    # toggle\n    def test_toggle_todo_with_no_heading(self):\n        # nothing should happen\n        vim.current.window.cursor = (1, 0)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[0], u'')\n        # and repeat it -> it should not change\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[0], u'')\n\n    def test_todo_toggle_NOTODO(self):\n        vim.current.window.cursor = (2, 0)\n        vim.current.buffer[1] = u_encode(u'** NOTODO Überschrift 1.1')\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u_encode(u'** TODO NOTODO Überschrift 1.1'))\n\n    def test_toggle_todo_in_heading_with_no_todo_state_different_levels(self):\n        # level 1\n        vim.current.window.cursor = (2, 0)\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* TODO Heading 1')\n        self.assertEqual((2, 0), vim.current.window.cursor)\n\n        # level 2\n        vim.current.window.cursor = (3, 0)\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[2], u'** TODO Text 1')\n\n        # level 2\n        vim.current.window.cursor = (4, 4)\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[3], u'*** TODO Text 2')\n        self.assertEqual((4, 9), vim.current.window.cursor)\n\n    def test_circle_through_todo_states(self):\n        # * Heading 1 -->\n        # * TODO Heading 1 -->\n        # * DONE Heading 1 -->\n        # * Heading 1 -->\n        # * TODO Heading 1 -->\n        # * DONE Heading 1\n        vim.current.window.cursor = (2, 6)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* TODO Heading 1')\n        self.assertEqual((2, 11), vim.current.window.cursor)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* DONE Heading 1')\n        self.assertEqual((2, 11), vim.current.window.cursor)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* Heading 1')\n        self.assertEqual((2, 6), vim.current.window.cursor)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* TODO Heading 1')\n        self.assertEqual((2, 11), vim.current.window.cursor)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* DONE Heading 1')\n        self.assertEqual((2, 11), vim.current.window.cursor)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* Heading 1')\n        self.assertEqual((2, 6), vim.current.window.cursor)\n\n    def test_circle_through_todo_states_with_more_states(self):\n        # * Heading 1 -->\n        # * TODO Heading 1 -->\n        # * STARTED Heading 1 -->\n        # * DONE Heading 1 -->\n        # * Heading 1 -->\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'STARTED'), u_encode(u'DONE'),\n                u_encode(u'|')]\n        vim.current.window.cursor = (2, 0)\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* TODO Heading 1')\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* STARTED Heading 1')\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* DONE Heading 1')\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[1], u'* Heading 1')\n\n    def test_toggle_todo_with_cursor_in_text_not_heading(self):\n        # nothing should happen\n        vim.current.window.cursor = (7, 0)\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[5], u'** TODO Text 1')\n        self.assertEqual(vim.current.window.cursor, (7, 0))\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[5], u'** DONE Text 1')\n        self.assertEqual(vim.current.window.cursor, (7, 0))\n\n        Todo.toggle_todo_state()\n        self.assertEqual(vim.current.buffer[5], u'** Text 1')\n        self.assertEqual(vim.current.window.cursor, (7, 0))\n\n    # get_states\n    def test_get_states_without_seperator(self):\n        u\"\"\"The last element in the todostates shouold be used as DONE-state when no sperator is given\"\"\"\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo, expected_done = [u'TODO'], [u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'INPROGRESS'), u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo = [u'TODO', u'INPROGRESS']\n        expected_done = [u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'INPROGRESS'),\n                u_encode(u'DUMMY'), u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo  = [u'TODO', u'INPROGRESS', u'DUMMY']\n        expected_done = [u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n    def test_get_states_with_seperator(self):\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo = [u'TODO']\n        expected_done = [u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'INPROGRESS'), u_encode(u'|'),\n                u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo = [u'TODO', u'INPROGRESS']\n        expected_done = [u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'INPROGRESS'),\n                u_encode(u'DUMMY'), u_encode(u'|'),  u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo = [u'TODO', u'INPROGRESS', u'DUMMY']\n        expected_done = [u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'INPROGRESS'),\n                u_encode(u'DUMMY'), u_encode(u'|'), u_encode(u'DELEGATED'), u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo =[u'TODO', u'INPROGRESS', u'DUMMY']\n        expected_done = [u'DELEGATED', u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [u_encode(u'TODO'), u_encode(u'|'), u_encode(u'DONEX'),\n                u_encode(u'DUMMY'), u_encode(u'DELEGATED'), u_encode(u'DONE')]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo = [u'TODO']\n        expected_done = [u'DONEX', u'DUMMY', u'DELEGATED', u'DONE']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n        vim.EVALRESULTS[u_encode(u'g:org_todo_keywords')] = [[u_encode(u'TODO(t)'), u_encode(u'|'), u_encode(u'DONEX')],\n                [u_encode(u'DUMMY'), u_encode(u'DELEGATED'), u_encode(u'DONE')]]\n        states_todo, states_done = VimBuffer().get_todo_states()[0]\n        expected_todo = [u'TODO']\n        expected_done = [u'DONEX']\n        self.assertEqual(states_todo, expected_todo)\n        self.assertEqual(states_done, expected_done)\n\n    # get_next_state\n    def test_get_next_state_with_no_current_state(self):\n        states = [((u'TODO', ), (u'DONE', ))]\n        current_state = u''\n        self.assertEquals(Todo._get_next_state(current_state, states), u'TODO')\n\n        states = [((u'TODO', u'NEXT'), (u'DELEGATED', u'DONE'))]\n        self.assertEquals(Todo._get_next_state(current_state, states), u'TODO')\n\n        states = [((u'NEXT', ), (u'DELEGATED', u'DONE'))]\n        self.assertEquals(Todo._get_next_state(current_state, states), u'NEXT')\n\n    def test_get_next_state_backward_with_no_current_state(self):\n        states = [((u'TODO', ), (u'DONE', ))]\n        current_state = u''\n        self.assertEquals(Todo._get_next_state(current_state, states,\n                Direction.BACKWARD), u'DONE')\n\n        states = [((u'TODO', u'NEXT'), (u'DELEGATED', u'DONE'))]\n        self.assertEquals(Todo._get_next_state(current_state, states,\n                Direction.BACKWARD), u'DONE')\n\n        states = [((u'NEXT', ), (u'DELEGATED', u'DONE'))]\n        self.assertEquals(Todo._get_next_state(current_state, states,\n                Direction.BACKWARD), u'DONE')\n\n    def test_get_next_state_with_invalid_current_state(self):\n        states = [((u'TODO', ), (u'DONE', ))]\n        current_state = u'STI'\n        self.assertEquals(Todo._get_next_state(current_state, states), u'TODO')\n\n        states = [((u'TODO', u'NEXT'), (u'DELEGATED', u'DONE'))]\n        self.assertEquals(Todo._get_next_state(current_state, states), u'TODO')\n\n        states = [((u'NEXT', ), (u'DELEGATED', u'DONE'))]\n        self.assertEquals(Todo._get_next_state(current_state, states), u'NEXT')\n\n    def test_get_next_state_backward_with_invalid_current_state(self):\n        states = [((u'TODO', ), (u'DONE', ))]\n        current_state = u'STI'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'DONE')\n\n        states = [((u'TODO', u'NEXT'), (u'DELEGATED', u'DONE'))]\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'DONE')\n\n        states = [((u'NEXT', ), (u'DELEGATED', u'DONE'))]\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'DONE')\n\n    def test_get_next_state_with_current_state_equals_todo_state(self):\n        states = [((u'TODO', u'NEXT', u'NOW'), (u'DELEGATED', u'DONE'))]\n        current_state = u'TODO'\n        self.assertEquals(Todo._get_next_state(current_state, states), u'NEXT')\n\n        current_state = u'NEXT'\n        self.assertEquals(Todo._get_next_state(current_state, states), u'NOW')\n\n    def test_get_next_state_backward_with_current_state_equals_todo_state(self):\n        states = [((u'TODO', u'NEXT', u'NOW'), (u'DELEGATED', u'DONE'))]\n        current_state = u'TODO'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, None)\n\n    def test_get_next_state_backward_misc(self):\n        states = [((u'TODO', u'NEXT', u'NOW'), (u'DELEGATED', u'DONE'))]\n        current_state = u'DONE'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'DELEGATED')\n\n        current_state = u'DELEGATED'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'NOW')\n\n        current_state = u'NOW'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'NEXT')\n\n        current_state = u'NEXT'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'TODO')\n\n        current_state = u'TODO'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, None)\n\n        current_state = None\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'DONE')\n\n    def test_get_next_state_with_jump_from_todo_to_done(self):\n        states = [((u'TODO', u'NEXT', u'NOW'), (u'DELEGATED', u'DONE'))]\n        current_state = u'NOW'\n        self.assertEquals(Todo._get_next_state(current_state, states), u'DELEGATED')\n\n    def test_get_next_state_with_jump_from_done_to_todo(self):\n        states = [((u'TODO', u'NEXT', u'NOW'), (u'DELEGATED', u'DONE'))]\n        current_state = u'DONE'\n        self.assertEquals(Todo._get_next_state(current_state, states), None)\n\n    def test_get_next_state_in_current_sequence(self):\n        states = [((u'TODO', u'NEXT', u'NOW'), (u'DELEGATED', u'DONE')), ((u'QA', ), (u'RELEASED', ))]\n        current_state = u'QA'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD)\n        self.assertEquals(result, u'RELEASED')\n\n    def test_get_next_state_in_current_sequence_with_access_keys(self):\n        states = [((u'TODO(t)', u'NEXT(n)', u'NOW(w)'), (u'DELEGATED(g)', u'DONE(d)')), ((u'QA(q)', ), (u'RELEASED(r)', ))]\n        current_state = u'QA'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD)\n        self.assertEquals(result, u'RELEASED')\n\n        current_state = u'NEXT'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD)\n        self.assertEquals(result, u'NOW')\n\n        current_state = u'TODO'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, None)\n\n        current_state = None\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD)\n        self.assertEquals(result, u'RELEASED')\n\n    def test_get_next_keyword_sequence(self):\n        states = [((u'TODO(t)', u'NEXT(n)', u'NOW(w)'), (u'DELEGATED(g)', u'DONE(d)')), ((u'QA(q)', ), (u'RELEASED(r)', ))]\n        current_state = None\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD, next_set=True)\n        self.assertEquals(result, u'TODO')\n\n        current_state = None\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD, next_set=True)\n        self.assertEquals(result, u'QA')\n\n        current_state = u'TODO'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD, next_set=True)\n        self.assertEquals(result, None)\n\n        current_state = u'TODO'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD, next_set=True)\n        self.assertEquals(result, u'QA')\n\n        current_state = u'NOW'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD, next_set=True)\n        self.assertEquals(result, u'QA')\n\n        current_state = u'DELEGATED'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD, next_set=True)\n        self.assertEquals(result, u'QA')\n\n        current_state = u'QA'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD, next_set=True)\n        self.assertEquals(result, u'TODO')\n\n        current_state = u'QA'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD, next_set=True)\n        self.assertEquals(result, None)\n\n        current_state = u'RELEASED'\n        result = Todo._get_next_state(current_state, states,\n                Direction.FORWARD, next_set=True)\n        self.assertEquals(result, None)\n\n        current_state = u'RELEASED'\n        result = Todo._get_next_state(current_state, states,\n                Direction.BACKWARD, next_set=True)\n        self.assertEquals(result, u'TODO')\n\n\ndef suite():\n    return unittest.TestLoader().loadTestsFromTestCase(TodoTestCase)\n"
  },
  {
    "path": "tests/test_vimbuffer.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport unittest\nimport sys\nsys.path.append(u'../ftplugin')\n\nimport vim\n\nfrom orgmode.liborgmode.headings import Heading\nfrom orgmode.vimbuffer import VimBuffer\n\nfrom orgmode.py3compat.encode_compatibility import *\nfrom orgmode.py3compat.unicode_compatibility import *\n\ncounter = 0\nclass VimBufferTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'),\n                                       u_encode(u'DONE'), u_encode(u'|')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'%d' % counter),\n                u_encode(u'&ts'): u_encode(u'8'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0')}\n        vim.current.buffer[:] = [u_encode(i) for i in u\"\"\"#Meta information\n#more meta information\n* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n        self.document = VimBuffer().init_dom()\n\n    def test_write_heading_tags(self):\n        self.assertEqual(self.document.is_dirty, False)\n        h = self.document.find_heading()\n        self.assertEqual(h._orig_start, 2)\n        self.assertEqual(h.title, u'Überschrift 1')\n        h.tags = [u'test', u'tag']\n        self.assertEqual(h.tags[0], u'test')\n        self.document.write_heading(h)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        h2 = self.document.find_heading()\n        self.assertEqual(d.headings[0].title, u'Überschrift 1')\n        self.assertEqual(len(d.headings[0].tags), 2)\n        self.assertEqual(d.headings[0].tags[0], u'test')\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(d.headings[0].children[0]._orig_start, 6)\n\n    def test_write_multi_heading_bodies(self):\n        self.assertEqual(self.document.is_dirty, False)\n        h = self.document.headings[0].copy()\n        self.assertEqual(h._orig_start, 2)\n        self.assertEqual(h.title, u'Überschrift 1')\n        h.body.append(u'test')\n        h.children[0].body.append(u'another line')\n        self.document.write_heading(h)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        h2 = self.document.find_heading()\n        self.assertEqual(len(d.headings[0].body), 4)\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(d.headings[0].children[0]._orig_start, 7)\n        self.assertEqual(d.headings[0].children[0].title, u'Überschrift 1.1')\n        self.assertEqual(len(d.headings[0].children[0].body), 4)\n        self.assertEqual(d.headings[0].children[1]._orig_start, 12)\n        self.assertEqual(d.headings[0].children[1].title, u'Überschrift 1.2')\n        self.assertEqual(len(d.headings[0].children[1].body), 2)\n\n    def test_meta_information_assign_directly(self):\n        # read meta information from document\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#Meta information\\n#more meta information')\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].start, 2)\n\n        # assign meta information directly to an element in array\n        self.document.meta_information[0] = u'#More or less meta information'\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#More or less meta information\\n#more meta information')\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, True)\n        self.assertEqual(self.document.headings[0].start, 2)\n\n    def test_meta_information_assign_string(self):\n        # assign a single line string\n        self.document.meta_information = u'#Less meta information'\n        self.assertEqual('\\n'.join(self.document.meta_information), u'#Less meta information')\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, True)\n        self.assertEqual(self.document.headings[0].start, 1)\n\n    def test_meta_information_assign_multi_line_string(self):\n        # assign a multi line string\n        self.document.meta_information = u'#Less meta information\\n#lesser information'\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#Less meta information\\n#lesser information')\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, True)\n        self.assertEqual(self.document.headings[0].start, 2)\n\n    def test_meta_information_assign_one_element_array(self):\n        # assign a single element array of strings\n        self.document.meta_information = u'#More or less meta information'.split(u'\\n')\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#More or less meta information')\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, True)\n        self.assertEqual(self.document.headings[0].start, 1)\n\n    def test_meta_information_assign_multi_element_array(self):\n        # assign a multi element array of strings\n        self.document.meta_information = u'#More or less meta information\\n#lesser information'.split(u'\\n')\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#More or less meta information\\n#lesser information')\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, True)\n        self.assertEqual(self.document.headings[0].start, 2)\n\n    def test_meta_information_read_no_meta_information(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"* Überschrift 1\nText 1\n\nBla bla\n** Überschrift 1.1\nText 2\n\nBla Bla bla\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n        self.document = VimBuffer().init_dom()\n\n        # read no meta information from document\n        self.assertEqual(self.document.meta_information, [])\n        self.assertEqual(self.document.headings[0].start, 0)\n        self.assertEqual(self.document.is_dirty, False)\n\n        # assign meta information to a former empty field\n        self.document.meta_information = u'#More or less meta information\\n#lesser information'.split('\\n')\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#More or less meta information\\n#lesser information')\n        self.assertEqual(self.document.headings[0].start, 2)\n        self.assertEqual(self.document.is_dirty, True)\n\n    def test_meta_information_assign_empty_array(self):\n        # assign an empty array as meta information\n        self.document.meta_information = []\n        self.assertEqual(self.document.meta_information, [])\n        self.assertEqual(self.document.headings[0].start, 0)\n        self.assertEqual(self.document.is_dirty, True)\n\n    def test_meta_information_assign_empty_string(self):\n        # assign an empty string as meta information\n        self.document.meta_information = u''\n        self.assertEqual(self.document.meta_information, [u''])\n        self.assertEqual(self.document.headings[0].start, 1)\n        self.assertEqual(self.document.is_dirty, True)\n\n    def test_bufnr(self):\n        self.assertEqual(self.document.bufnr, vim.current.buffer.number)\n        # TODO add more tests as soon as multi buffer support has been implemented\n\n    def test_write_meta_information(self):\n        # write nothing\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.write(), False)\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#Meta information\\n#more meta information')\n\n        # write changed meta information\n        self.assertEqual(self.document.is_dirty, False)\n        self.document.meta_information = u'#More or less meta information\\n#lesser information'.split('\\n')\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'#More or less meta information\\n#lesser information')\n        self.assertEqual(self.document.headings[0].start, 2)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].start, 2)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(u'\\n'.join(VimBuffer().init_dom().meta_information), u'#More or less meta information\\n#lesser information')\n\n        # shorten meta information\n        self.assertEqual(self.document.is_dirty, False)\n        self.document.meta_information = u'!More or less meta information'.split(u'\\n')\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'!More or less meta information')\n        self.assertEqual(self.document.headings[0].start, 1)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].start, 1)\n        self.assertEqual(self.document.headings[0]._orig_start, 1)\n        self.assertEqual(u'\\n'.join(VimBuffer().init_dom().meta_information), u'!More or less meta information')\n\n        # lengthen meta information\n        self.assertEqual(self.document.is_dirty, False)\n        self.document.meta_information = u'!More or less meta information\\ntest\\ntest'\n        self.assertEqual(u'\\n'.join(self.document.meta_information), u'!More or less meta information\\ntest\\ntest')\n        self.assertEqual(self.document.headings[0].start, 3)\n        self.assertEqual(self.document.headings[0]._orig_start, 1)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].start, 3)\n        self.assertEqual(self.document.headings[0]._orig_start, 3)\n        self.assertEqual(u'\\n'.join(VimBuffer().init_dom().meta_information), u'!More or less meta information\\ntest\\ntest')\n\n        # write empty meta information\n        self.assertEqual(self.document.is_dirty, False)\n        self.document.meta_information = []\n        self.assertEqual(self.document.meta_information, [])\n        self.assertEqual(self.document.headings[0].start, 0)\n        self.assertEqual(self.document.headings[0]._orig_start, 3)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].start, 0)\n        self.assertEqual(self.document.headings[0]._orig_start, 0)\n        self.assertEqual(VimBuffer().init_dom().meta_information, [])\n\n    def test_write_changed_title(self):\n        # write a changed title\n        self.document.headings[0].title = u'Heading 1'\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, False)\n        self.assertEqual(self.document.headings[0].is_dirty_body, False)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, True)\n        self.assertEqual(self.document.headings[0].title, u'Heading 1')\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(VimBuffer().init_dom().headings[0].title, u'Heading 1')\n\n    def test_write_changed_body(self):\n        # write a changed body\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.document.headings[0].body[0] = u'Another text'\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, False)\n        self.assertEqual(self.document.headings[0].is_dirty_body, True)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, False)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(self.document.headings[0].body, [u'Another text', u'', u'Bla bla'])\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(VimBuffer().init_dom().headings[0].body, [u'Another text', u'', u'Bla bla'])\n\n    def test_write_shortened_body(self):\n        # write a shortened body\n        self.document.headings[0].body = u'Another text'\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, False)\n        self.assertEqual(self.document.headings[0].is_dirty_body, True)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, False)\n        self.assertEqual(self.document.headings[0].end, 3)\n        self.assertEqual(len(self.document.headings[0]), 2)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 4)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(self.document.headings[0].body, [u'Another text'])\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 3)\n        self.assertEqual(len(self.document.headings[0]), 2)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 2)\n        self.assertEqual(self.document.headings[0].children[0].start, 4)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 4)\n        self.assertEqual(VimBuffer().init_dom().headings[0].body, [u'Another text'])\n\n    def test_write_lengthened_body(self):\n        # write a lengthened body\n        self.document.headings[0].body = [u'Another text', u'more', u'and more', u'and more']\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.is_dirty_meta_information, False)\n        self.assertEqual(self.document.headings[0].is_dirty_body, True)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, False)\n        self.assertEqual(self.document.headings[0].end, 6)\n        self.assertEqual(len(self.document.headings[0]), 5)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 7)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(self.document.headings[0].body, [u'Another text', u'more', u'and more', u'and more'])\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 6)\n        self.assertEqual(len(self.document.headings[0]), 5)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 5)\n        self.assertEqual(self.document.headings[0].children[0].start, 7)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 7)\n        self.assertEqual(VimBuffer().init_dom().headings[0].body, [u'Another text', u'more', u'and more', u'and more'])\n\n    def test_write_delete_heading(self):\n        # delete a heading\n        self.assertEqual(len(self.document.headings[0].children), 2)\n        del self.document.headings[0].children[0]\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings[0].children), 1)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 10)\n        self.assertEqual(self.document.headings[0].children[0]._orig_len, 3)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(self.document.headings[0].children[0]._orig_len, 3)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(self.document.headings[0].children), 1)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(d.headings[0].end, 5)\n        self.assertEqual(len(d.headings[0]), 4)\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(d.headings[0]._orig_len, 4)\n        self.assertEqual(d.headings[0].children[0].start, 6)\n        self.assertEqual(d.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(d.headings[0].children[0]._orig_len, 3)\n\n    def test_write_delete_first_heading(self):\n        # delete the first heading\n        self.assertEqual(len(self.document.headings), 3)\n        del self.document.headings[0]\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 2)\n        self.assertEqual(self.document.headings[0].end, 2)\n        self.assertEqual(len(self.document.headings[0]), 1)\n        self.assertEqual(self.document.headings[0]._orig_start, 17)\n        self.assertEqual(self.document.headings[0]._orig_len, 1)\n        self.assertEqual(self.document.headings[1].start, 3)\n        self.assertEqual(self.document.headings[1]._orig_start, 18)\n        self.assertEqual(self.document.headings[1]._orig_len, 3)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 2)\n        self.assertEqual(len(self.document.headings[0]), 1)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 1)\n        self.assertEqual(self.document.headings[1].start, 3)\n        self.assertEqual(self.document.headings[1]._orig_start, 3)\n        self.assertEqual(self.document.headings[1]._orig_len, 3)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(self.document.headings), 2)\n        self.assertEqual(d.headings[0].end, 2)\n        self.assertEqual(len(d.headings[0]), 1)\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(d.headings[0]._orig_len, 1)\n        self.assertEqual(d.headings[1].start, 3)\n        self.assertEqual(d.headings[1]._orig_start, 3)\n        self.assertEqual(d.headings[1]._orig_len, 3)\n\n    def test_write_delete_last_heading(self):\n        # delete the last heading\n        self.assertEqual(len(self.document.headings), 3)\n        del self.document.headings[-1]\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 2)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(self.document.headings[0].end_of_last_child, 16)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[-1].start, 17)\n        self.assertEqual(self.document.headings[-1]._orig_start, 17)\n        self.assertEqual(self.document.headings[-1]._orig_len, 1)\n        self.assertEqual(self.document.headings[-1].end, 17)\n        self.assertEqual(self.document.headings[-1].end_of_last_child, 17)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(self.document.headings[0].end_of_last_child, 16)\n        self.assertEqual(len(self.document.headings[0]), 4)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0]._orig_len, 4)\n        self.assertEqual(self.document.headings[-1].start, 17)\n        self.assertEqual(self.document.headings[-1]._orig_start, 17)\n        self.assertEqual(self.document.headings[-1]._orig_len, 1)\n        self.assertEqual(self.document.headings[-1].end, 17)\n        self.assertEqual(self.document.headings[-1].end_of_last_child, 17)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(self.document.headings), 2)\n        self.assertEqual(d.headings[0].end, 5)\n        self.assertEqual(d.headings[0].end_of_last_child, 16)\n        self.assertEqual(len(d.headings[0]), 4)\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(d.headings[0]._orig_len, 4)\n        self.assertEqual(d.headings[-1].start, 17)\n        self.assertEqual(d.headings[-1]._orig_start, 17)\n        self.assertEqual(d.headings[-1]._orig_len, 1)\n        self.assertEqual(d.headings[-1].end, 17)\n        self.assertEqual(d.headings[-1].end_of_last_child, 17)\n\n    def test_write_delete_multiple_headings(self):\n        # delete multiple headings\n        self.assertEqual(len(self.document.headings), 3)\n        del self.document.headings[1]\n        del self.document.headings[0].children[1].children[0]\n        del self.document.headings[0].children[0]\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 2)\n        self.assertEqual(len(self.document.headings[0].children), 1)\n        self.assertEqual(len(self.document.headings[0].children[0].children), 1)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(self.document.headings[0].end_of_last_child, 9)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 10)\n        self.assertEqual(self.document.headings[0].children[0].children[0]._orig_start, 16)\n        self.assertEqual(self.document.headings[-1]._orig_start, 18)\n        self.assertEqual(self.document.headings[0].start, 2)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0].children[0].start, 9)\n        self.assertEqual(self.document.headings[-1].start, 10)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].end, 5)\n        self.assertEqual(self.document.headings[0].end_of_last_child, 9)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(self.document.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(self.document.headings[0].children[0].children[0]._orig_start, 9)\n        self.assertEqual(self.document.headings[-1]._orig_start, 10)\n        self.assertEqual(self.document.headings[0].start, 2)\n        self.assertEqual(self.document.headings[0].children[0].start, 6)\n        self.assertEqual(self.document.headings[0].children[0].children[0].start, 9)\n        self.assertEqual(self.document.headings[-1].start, 10)\n        self.assertEqual(self.document.headings[0].title, u'Überschrift 1')\n        self.assertEqual(self.document.headings[0].children[0].title, u'Überschrift 1.2')\n        self.assertEqual(self.document.headings[0].children[0].children[0].title, u'Überschrift 1.2.1')\n        self.assertEqual(self.document.headings[-1].title, u'Überschrift 3')\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(self.document.headings), 2)\n        self.assertEqual(len(self.document.headings[0].children), 1)\n        self.assertEqual(len(self.document.headings[0].children[0].children), 1)\n        self.assertEqual(d.headings[0].end, 5)\n        self.assertEqual(d.headings[0].end_of_last_child, 9)\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(d.headings[0].children[0]._orig_start, 6)\n        self.assertEqual(d.headings[0].children[0].children[0]._orig_start, 9)\n        self.assertEqual(d.headings[-1]._orig_start, 10)\n        self.assertEqual(d.headings[0].start, 2)\n        self.assertEqual(d.headings[0].children[0].start, 6)\n        self.assertEqual(d.headings[0].children[0].children[0].start, 9)\n        self.assertEqual(d.headings[-1].start, 10)\n        self.assertEqual(d.headings[0].title, u'Überschrift 1')\n        self.assertEqual(d.headings[0].children[0].title, u'Überschrift 1.2')\n        self.assertEqual(d.headings[0].children[0].children[0].title, u'Überschrift 1.2.1')\n        self.assertEqual(d.headings[-1].title, u'Überschrift 3')\n\n\n    def test_write_add_heading(self):\n        # add a heading\n        self.assertEqual(len(self.document.headings), 3)\n        self.assertEqual(len(self.document.headings[0].children), 2)\n        h = Heading()\n        h.title = u'Test heading'\n        h.level = 2\n        h.body = u'Text, text\\nmore text'\n        self.document.headings[0].children.append(h)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings[0].children), 3)\n        self.assertEqual(self.document.headings[0].children[-1].title, u'Test heading')\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(len(self.document.headings[0].children), 3)\n        self.assertEqual(self.document.headings[0].children[-1].title, u'Test heading')\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings[0].children), 3)\n        self.assertEqual(d.headings[0].children[-1].title, u'Test heading')\n\n    def test_write_add_heading_before_first_heading(self):\n        # add a heading before the first heading\n        self.assertEqual(len(self.document.headings), 3)\n        h = Heading()\n        h.title = u'Test heading'\n        h.level = 2\n        h.body = u'Text, text\\nmore text'\n        self.assertEqual(h.start, None)\n        self.document.headings[0:0] = h\n        self.assertEqual(h.start, 2)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 4)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].title, u'Test heading')\n        self.assertEqual(self.document.headings[0].start, 2)\n        self.assertEqual(self.document.headings[0]._orig_start, 2)\n        self.assertEqual(len(self.document.headings[0]), 3)\n        self.assertEqual(self.document.headings[1].title, u'Überschrift 1')\n        self.assertEqual(self.document.headings[1].start, 5)\n        self.assertEqual(len(self.document.headings[1]), 4)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings), 4)\n        self.assertEqual(d.headings[0].title, u'Test heading')\n        self.assertEqual(d.headings[0].start, 2)\n        self.assertEqual(d.headings[0]._orig_start, 2)\n        self.assertEqual(len(d.headings[0]), 3)\n        self.assertEqual(d.headings[1].title, u'Überschrift 1')\n        self.assertEqual(d.headings[1].start, 5)\n        self.assertEqual(len(d.headings[1]), 4)\n\n    def test_write_add_heading_after_last_heading_toplevel(self):\n        # add a heading after the last heading (top level heading)\n        self.assertEqual(len(self.document.headings), 3)\n        h = Heading()\n        h.title = u'Test heading'\n        h.body = u'Text, text\\nmore text'\n        self.assertEqual(h.start, None)\n        #self.document.headings += h\n        self.document.headings.append(h)\n        self.assertEqual(h.start, 21)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 4)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[-1].title, u'Test heading')\n        self.assertEqual(self.document.headings[-1].start, 21)\n        self.assertEqual(self.document.headings[-1]._orig_start, 21)\n        self.assertEqual(len(self.document.headings[-1]), 3)\n        self.assertEqual(self.document.headings[-2].title, u'Überschrift 3')\n        self.assertEqual(self.document.headings[-2].start, 18)\n        self.assertEqual(len(self.document.headings[-2]), 3)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings), 4)\n        self.assertEqual(d.headings[-1].title, u'Test heading')\n        self.assertEqual(d.headings[-1].start, 21)\n        self.assertEqual(d.headings[-1]._orig_start, 21)\n        self.assertEqual(len(d.headings[-1]), 3)\n        self.assertEqual(d.headings[-2].title, u'Überschrift 3')\n        self.assertEqual(d.headings[-2].start, 18)\n        self.assertEqual(len(d.headings[-2]), 3)\n\n    def test_write_add_heading_after_last_heading_subheading(self):\n        # add a heading after the last heading (subheading)\n        self.assertEqual(len(self.document.headings), 3)\n        h = Heading()\n        h.title = u'Test heading'\n        h.level = 2\n        h.body = u'Text, text\\nmore text'\n        self.assertEqual(h.start, None)\n        # TODO make it work with += operator so far it works with append and\n        # extend so it seems that there is a problem in __iadd__ method in\n        # UserList from collection in python3\n        #self.document.headings[-1].children += h\n        #self.document.headings[-1].children.extend([h])\n        self.document.headings[-1].children.append(h)\n        self.assertEqual(h.start, 21)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 3)\n        self.assertEqual(len(self.document.headings[-1]), 3)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[-1].children[-1].title, u'Test heading')\n        self.assertEqual(self.document.headings[-1].children[-1].start, 21)\n        self.assertEqual(self.document.headings[-1].children[-1]._orig_start, 21)\n        self.assertEqual(len(self.document.headings[-1].children[-1]), 3)\n        self.assertEqual(self.document.headings[-1].title, u'Überschrift 3')\n        self.assertEqual(self.document.headings[-1].start, 18)\n        self.assertEqual(len(self.document.headings[-1]), 3)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings), 3)\n        self.assertEqual(len(d.headings[-1]), 3)\n        self.assertEqual(d.headings[-1].children[-1].title, u'Test heading')\n        self.assertEqual(d.headings[-1].children[-1].start, 21)\n        self.assertEqual(d.headings[-1].children[-1]._orig_start, 21)\n        self.assertEqual(len(d.headings[-1].children[-1]), 3)\n        self.assertEqual(d.headings[-1].title, u'Überschrift 3')\n        self.assertEqual(d.headings[-1].start, 18)\n        self.assertEqual(len(d.headings[-1]), 3)\n\n    def test_write_replace_one_heading(self):\n        # replace subheadings by a list of newly created headings (one item)\n        self.assertEqual(len(self.document.headings), 3)\n        h = Heading()\n        h.title = u'Test heading'\n        h.level = 3\n        h.body = u'Text, text\\nmore text\\nanother text'\n        self.assertEqual(h.start, None)\n        self.document.headings[0].children[1].children[0] = h\n        self.assertEqual(h.start, 13)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(len(self.document.headings), 3)\n        self.assertEqual(len(self.document.headings[0].children[1].children), 2)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].children[1].children[0].title, u'Test heading')\n        self.assertEqual(self.document.headings[0].children[1].children[0].start, 13)\n        self.assertEqual(self.document.headings[0].children[1].children[0]._orig_start, 13)\n        self.assertEqual(len(self.document.headings[0].children[1].children[0]), 4)\n        self.assertEqual(len(self.document.headings[0].children[1].children[0].children), 0)\n        self.assertEqual(len(self.document.headings[0].children[1]), 3)\n        self.assertEqual(len(self.document.headings[0].children[0].children), 0)\n        self.assertEqual(len(self.document.headings[1].children), 0)\n        self.assertEqual(self.document.headings[0].children[1].children[-1].title, u'Überschrift 1.2.1')\n        self.assertEqual(self.document.headings[0].children[1].children[-1].start, 17)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings), 3)\n        self.assertEqual(len(d.headings[0].children[1].children), 2)\n        self.assertEqual(d.headings[0].children[1].children[0].title, u'Test heading')\n        self.assertEqual(d.headings[0].children[1].children[0].start, 13)\n        self.assertEqual(d.headings[0].children[1].children[0]._orig_start, 13)\n        self.assertEqual(len(d.headings[0].children[1].children[0]), 4)\n        self.assertEqual(len(d.headings[0].children[1].children[0].children), 0)\n        self.assertEqual(len(d.headings[0].children[1]), 3)\n        self.assertEqual(len(d.headings[0].children[0].children), 0)\n        self.assertEqual(len(d.headings[1].children), 0)\n        self.assertEqual(d.headings[0].children[1].children[-1].title, u'Überschrift 1.2.1')\n        self.assertEqual(d.headings[0].children[1].children[-1].start, 17)\n\n    def test_write_replace_multiple_headings_with_one_heading(self):\n        # replace subheadings by a list of newly created headings (one item)\n        self.assertEqual(len(self.document.headings), 3)\n        h = Heading()\n        h.title = u'Test heading'\n        h.level = 3\n        h.body = u'Text, text\\nmore text\\nanother text'\n\n        self.assertEqual(h.start, None)\n        self.assertEqual(len(self.document.headings[0].children[1].children), 2)\n        self.document.headings[0].children[1].children[:] = h\n        self.assertEqual(h.start, 13)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.headings[0].children[1].is_dirty, False)\n        self.assertEqual(len(self.document.headings), 3)\n        self.assertEqual(len(self.document.headings[0].children[1].children), 1)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].children[1].title, u'Überschrift 1.2')\n        self.assertEqual(self.document.headings[0].children[1].children[0].title, u'Test heading')\n        self.assertEqual(self.document.headings[0].children[1].children[0].start, 13)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings[0].children[1].children), 1)\n        self.assertEqual(d.headings[0].children[1].title, u'Überschrift 1.2')\n        self.assertEqual(d.headings[0].children[1].children[0].title, u'Test heading')\n        self.assertEqual(d.headings[0].children[1].children[0].start, 13)\n\n    def test_write_replace_multiple_headings_with_a_multiple_heading_structure(self):\n        # replace subheadings by a list of newly created headings (multiple items)\n        self.assertEqual(len(self.document.headings), 3)\n        h = Heading()\n        h.title = u'Test heading'\n        h.level = 3\n        h.body = u'Text, text\\nmore text\\nanother text'\n        h1 = Heading()\n        h1.title = u'another heading'\n        h1.level = 4\n        h1.body = u'This\\nIs\\nJust more\\ntext'\n        h.children.append(h1)\n        h2 = Heading()\n        h2.title = u'yet another heading'\n        h2.level = 3\n        h2.body = u'This\\nis less text'\n\n        self.assertEqual(h.start, None)\n        self.document.headings[0].children[1].children[:] = (h, h2)\n        self.assertEqual(h.start, 13)\n        self.assertEqual(h1.start, 17)\n        self.assertEqual(h2.start, 22)\n        self.assertEqual(self.document.is_dirty, True)\n        self.assertEqual(self.document.headings[0].children[1].is_dirty, False)\n        self.assertEqual(len(self.document.headings), 3)\n        self.assertEqual(len(self.document.headings[0].children[1].children), 2)\n        self.assertEqual(len(self.document.headings[0].children[1].children[0].children), 1)\n        self.assertEqual(len(self.document.headings[0].children[1].children[1].children), 0)\n\n        self.assertEqual(self.document.write(), True)\n        self.assertEqual(self.document.is_dirty, False)\n        self.assertEqual(self.document.headings[0].children[1].title, u'Überschrift 1.2')\n        self.assertEqual(self.document.headings[0].children[1].children[0].title, u'Test heading')\n        self.assertEqual(self.document.headings[0].children[1].children[0].children[0].title, u'another heading')\n        self.assertEqual(self.document.headings[0].children[1].children[1].title, u'yet another heading')\n        self.assertEqual(self.document.headings[0].children[1].children[0].start, 13)\n        self.assertEqual(self.document.headings[0].children[1].children[0].children[0].start, 17)\n        self.assertEqual(self.document.headings[0].children[1].children[1].start, 22)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(d.headings[0].children[1].title, u'Überschrift 1.2')\n        self.assertEqual(d.headings[0].children[1].children[0].title, u'Test heading')\n        self.assertEqual(d.headings[0].children[1].children[0].children[0].title, u'another heading')\n        self.assertEqual(d.headings[0].children[1].children[1].title, u'yet another heading')\n        self.assertEqual(d.headings[0].children[1].children[0].start, 13)\n        self.assertEqual(d.headings[0].children[1].children[0].children[0].start, 17)\n        self.assertEqual(d.headings[0].children[1].children[1].start, 22)\n\n    def test_dom(self):\n        self.assertEqual(len(self.document.headings), 3)\n        for h in self.document.headings:\n            self.assertEqual(h.level, 1)\n        self.assertEqual(len(self.document.headings[0].children), 2)\n        self.assertEqual(len(self.document.headings[0].children[0].children), 0)\n        self.assertEqual(len(self.document.headings[0].children[1].children), 2)\n        self.assertEqual(len(self.document.headings[0].children[1].children[0].children), 0)\n        self.assertEqual(len(self.document.headings[0].children[1].children[1].children), 0)\n        self.assertEqual(len(self.document.headings[1].children), 0)\n        self.assertEqual(len(self.document.headings[2].children), 0)\n\n        # test no heading\n        vim.current.window.cursor = (1, 0)\n        h = self.document.current_heading()\n        self.assertEqual(h, None)\n\n    def test_index_boundaries(self):\n        # test index boundaries\n        vim.current.window.cursor = (-1, 0)\n        h = self.document.current_heading()\n        self.assertEqual(h, None)\n\n        vim.current.window.cursor = (21, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.level, 1)\n        self.assertEqual(h.start, 18)\n        self.assertNotEqual(h.previous_sibling, None)\n        self.assertEqual(h.previous_sibling.level, 1)\n        self.assertEqual(h.parent, None)\n        self.assertEqual(h.next_sibling, None)\n        self.assertEqual(len(h.children), 0)\n\n        vim.current.window.cursor = (999, 0)\n        h = self.document.current_heading()\n        self.assertEqual(h, None)\n\n    def test_heading_start_and_end(self):\n        # test heading start and end\n        vim.current.window.cursor = (3, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.start, 2)\n        self.assertEqual(h.end, 5)\n        self.assertEqual(h.end_of_last_child, 16)\n\n        vim.current.window.cursor = (12, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.start, 10)\n        self.assertEqual(h.end, 12)\n        self.assertEqual(h.end_of_last_child, 16)\n\n        vim.current.window.cursor = (19, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.start, 18)\n        self.assertEqual(h.end, 20)\n        self.assertEqual(h.end_of_last_child, 20)\n\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n** Überschrift 1.2\nText 3\n\n**** Überschrift 1.2.1.falsch\n\nBla Bla bla bla\n*** Überschrift 1.2.1\n* Überschrift 2\n* Überschrift 3\n  asdf sdf\n\"\"\".split(u'\\n') ]\n        self.document = VimBuffer().init_dom()\n        vim.current.window.cursor = (3, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.parent, None)\n        self.assertEqual(h.level, 2)\n        self.assertEqual(h.title, u'Überschrift 1.2')\n        self.assertEqual(len(h.children), 2)\n        self.assertEqual(h.children[1].start, 7)\n        self.assertEqual(h.children[1].children, [])\n        self.assertEqual(h.children[1].next_sibling, None)\n        self.assertEqual(h.children[1].end, 7)\n        self.assertEqual(h.start, 1)\n        self.assertEqual(h.end, 3)\n        self.assertEqual(h.end_of_last_child, 7)\n\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* Überschrift 2\n* Überschrift 3\"\"\".split(u'\\n') ]\n        self.document = VimBuffer().init_dom()\n        vim.current.window.cursor = (3, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.end, 2)\n        self.assertEqual(h.end_of_last_child, 2)\n        self.assertEqual(h.title, u'Überschrift 3')\n\n    def test_first_heading(self):\n        # test first heading\n        vim.current.window.cursor = (3, 0)\n        h = self.document.current_heading()\n\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.parent, None)\n        self.assertEqual(h.level, 1)\n        self.assertEqual(len(h.children), 2)\n        self.assertEqual(h.previous_sibling, None)\n\n        self.assertEqual(h.children[0].level, 2)\n        self.assertEqual(h.children[0].children, [])\n        self.assertEqual(h.children[1].level, 2)\n        self.assertEqual(len(h.children[1].children), 2)\n        self.assertEqual(h.children[1].children[0].level, 4)\n        self.assertEqual(h.children[1].children[1].level, 3)\n\n        self.assertEqual(h.next_sibling.level, 1)\n\n        self.assertEqual(h.next_sibling.next_sibling.level, 1)\n\n        self.assertEqual(h.next_sibling.next_sibling.next_sibling, None)\n        self.assertEqual(h.next_sibling.next_sibling.parent, None)\n\n    def test_heading_in_the_middle(self):\n        # test heading in the middle of the file\n        vim.current.window.cursor = (14, 0)\n        h = self.document.current_heading()\n\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.level, 4)\n        self.assertEqual(h.parent.level, 2)\n        self.assertNotEqual(h.next_sibling, None)\n        self.assertNotEqual(h.next_sibling.previous_sibling, None)\n        self.assertEqual(h.next_sibling.level, 3)\n        self.assertEqual(h.previous_sibling, None)\n\n    def test_previous_headings(self):\n        # test previous headings\n        vim.current.window.cursor = (17, 0)\n        h = self.document.current_heading()\n\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.level, 3)\n        self.assertNotEqual(h.previous_sibling, None)\n        self.assertEqual(h.parent.level, 2)\n        self.assertNotEqual(h.parent.previous_sibling, None)\n        self.assertNotEqual(h.previous_sibling.parent, None)\n        self.assertEqual(h.previous_sibling.parent.start, 10)\n\n        vim.current.window.cursor = (14, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h.parent, None)\n        self.assertEqual(h.parent.start, 10)\n\n        vim.current.window.cursor = (21, 0)\n        h = self.document.current_heading()\n        self.assertNotEqual(h, None)\n        self.assertEqual(h.level, 1)\n        self.assertNotEqual(h.previous_sibling, None)\n        self.assertEqual(h.previous_sibling.level, 1)\n        self.assertNotEqual(h.previous_sibling.previous_sibling, None)\n        self.assertEqual(h.previous_sibling.previous_sibling.level, 1)\n        self.assertEqual(h.previous_sibling.previous_sibling.previous_sibling,\n                None)\n\n        vim.current.window.cursor = (77, 0)\n        h = self.document.current_heading()\n        self.assertEqual(h, None)\n\nclass VimBufferTagsTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'),\n                                       u_encode(u'DONE'), u_encode(u'|')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'0'),\n                u_encode(u'&ts'): u_encode(u'8'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0')}\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"#Meta information\n#more meta information\n* Überschrift 1     :testtag:\nText 1\n\nBla bla\n** Überschrift 1.1 :multi:tags:\nText 2\n\nBla Bla bla\n** Überschrift 1.2:notag:\nText 3\n\n**** Überschrift 1.2.1.falsch :no tag:\n\nBla Bla bla bla\n*** Überschrift 1.2.1 :no tag\n*** Überschrift 1.2.2 no tag:\n* Überschrift 2\t\t\t\t  :more:tags:\n* Überschrift 3\t:lesser:tag:\n  asdf sdf\n* Überschrift 4 super long long long long long long long long extremely long title\t:title:long:\n* TODO Überschrift 5 super long long long long long long long long extremely long title\t:title_with_todo:\n* oneword :with:tags:\n* :noword:with:tags:\n* TODO :todo:with:tags:\n\"\"\".split(u'\\n') ]\n        self.document = VimBuffer().init_dom()\n\n    def test_tag_read_no_word_with_tags(self):\n        self.assertEqual(len(self.document.headings[6].tags), 3)\n        self.assertEqual(self.document.headings[6].tags[0], u'noword')\n        self.assertEqual(self.document.headings[6].title, u'')\n        self.assertEqual(self.document.headings[6].todo, None)\n\n    def test_tag_read_one_word_with_tags(self):\n        self.assertEqual(len(self.document.headings[5].tags), 2)\n        self.assertEqual(self.document.headings[5].tags[0], u'with')\n        self.assertEqual(self.document.headings[5].title, u'oneword')\n        self.assertEqual(self.document.headings[5].todo, None)\n\n    def test_tag_read_TODO_with_tags(self):\n        self.assertEqual(len(self.document.headings[7].tags), 3)\n        self.assertEqual(self.document.headings[7].tags[0], u'todo')\n        self.assertEqual(self.document.headings[7].title, u'')\n        self.assertEqual(self.document.headings[7].todo, u'TODO')\n\n    def test_tag_read_one(self):\n        self.assertEqual(len(self.document.headings[0].tags), 1)\n        self.assertEqual(self.document.headings[0].tags[0], u'testtag')\n        self.assertEqual(unicode(self.document.headings[0]), u'* Überschrift 1\t\t\t\t\t\t\t    :testtag:')\n\n    def test_tag_read_multiple(self):\n        self.assertEqual(len(self.document.headings[0].children[0].tags), 2)\n        self.assertEqual(self.document.headings[0].children[0].tags, [u'multi', 'tags'])\n        self.assertEqual(unicode(self.document.headings[0].children[0]), u'** Überschrift 1.1\t\t\t\t\t\t :multi:tags:')\n\n    def test_tag_no_tags(self):\n        self.assertEqual(len(self.document.headings[0].children[1].children), 3)\n        self.assertEqual(len(self.document.headings[0].children[1].tags), 0)\n        self.assertEqual(len(self.document.headings[0].children[1].children[0].tags), 0)\n        self.assertEqual(len(self.document.headings[0].children[1].children[1].tags), 0)\n        self.assertEqual(len(self.document.headings[0].children[1].children[2].tags), 0)\n\n    def test_tag_read_space_and_tab_separated(self):\n        self.assertEqual(len(self.document.headings[1].children), 0)\n        self.assertEqual(len(self.document.headings[1].tags), 2)\n        self.assertEqual(self.document.headings[1].tags, [u'more', u'tags'])\n\n    def test_tag_read_tab_separated(self):\n        self.assertEqual(len(self.document.headings[2].children), 0)\n        self.assertEqual(len(self.document.headings[2].tags), 2)\n        self.assertEqual(self.document.headings[2].tags, [u'lesser', u'tag'])\n\n    def test_tag_read_long_title(self):\n        self.assertEqual(len(self.document.headings[3].children), 0)\n        self.assertEqual(len(self.document.headings[3].tags), 2)\n        self.assertEqual(self.document.headings[3].tags, [u'title', u'long'])\n        self.assertEqual(unicode(self.document.headings[3]), u'* Überschrift 4 super long long long long long long long long extremely long title  :title:long:')\n\n    def test_tag_read_long_title_plus_todo_state(self):\n        self.assertEqual(len(self.document.headings[4].children), 0)\n        self.assertEqual(len(self.document.headings[4].tags), 1)\n        self.assertEqual(self.document.headings[4].level, 1)\n        self.assertEqual(self.document.headings[4].todo, u'TODO')\n        self.assertEqual(self.document.headings[4].title, u'Überschrift 5 super long long long long long long long long extremely long title')\n        self.assertEqual(self.document.headings[4].tags, [u'title_with_todo'])\n        self.assertEqual(unicode(self.document.headings[4]), u'* TODO Überschrift 5 super long long long long long long long long extremely long title  :title_with_todo:')\n\n    def test_tag_del_tags(self):\n        self.assertEqual(len(self.document.headings[0].tags), 1)\n        del self.document.headings[0].tags\n        self.assertEqual(len(self.document.headings[0].tags), 0)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, True)\n        self.assertEqual(self.document.headings[0].is_dirty_body, False)\n        self.assertEqual(unicode(self.document.headings[0]), u'* Überschrift 1')\n        self.assertEqual(self.document.write(), True)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings[0].tags), 0)\n        self.assertEqual(d.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(d.headings[0]), u'* Überschrift 1')\n\n    def test_tag_replace_one_tag(self):\n        self.assertEqual(len(self.document.headings[0].tags), 1)\n        self.document.headings[0].tags = [u'justonetag']\n        self.assertEqual(len(self.document.headings[0].tags), 1)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, True)\n        self.assertEqual(self.document.headings[0].is_dirty_body, False)\n        self.assertEqual(unicode(self.document.headings[0]), u'* Überschrift 1\t\t\t\t\t\t\t :justonetag:')\n        self.assertEqual(self.document.write(), True)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings[0].tags), 1)\n        self.assertEqual(d.headings[0].tags, [u'justonetag'])\n        self.assertEqual(d.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(d.headings[0]), u'* Überschrift 1\t\t\t\t\t\t\t :justonetag:')\n\n    def test_tag_replace_multiple_tags(self):\n        self.assertEqual(len(self.document.headings[1].tags), 2)\n        self.document.headings[1].tags = [u'justonetag', u'moretags', u'lesstags']\n        self.assertEqual(len(self.document.headings[1].tags), 3)\n        self.assertEqual(self.document.headings[1].is_dirty_heading, True)\n        self.assertEqual(self.document.headings[1].is_dirty_body, False)\n        self.assertEqual(unicode(self.document.headings[1]), u'* Überschrift 2\t\t\t\t       :justonetag:moretags:lesstags:')\n        self.assertEqual(self.document.write(), True)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(len(d.headings[1].tags), 3)\n        self.assertEqual(d.headings[1].tags, [u'justonetag', u'moretags', u'lesstags'])\n        self.assertEqual(d.headings[1].title, u'Überschrift 2')\n        self.assertEqual(unicode(d.headings[1]), u'* Überschrift 2\t\t\t\t       :justonetag:moretags:lesstags:')\n\nclass VimBufferTodoTestCase(unittest.TestCase):\n    def setUp(self):\n        global counter\n        counter += 1\n        vim.CMDHISTORY = []\n        vim.CMDRESULTS = {}\n        vim.EVALHISTORY = []\n        vim.EVALRESULTS = {\n                # no org_todo_keywords for b\n                u_encode(u'exists(\"b:org_todo_keywords\")'): u_encode('0'),\n                # global values for org_todo_keywords\n                u_encode(u'exists(\"g:org_todo_keywords\")'): u_encode('1'),\n                u_encode(u'g:org_todo_keywords'): [u_encode(u'TODO'), \\\n                        u_encode(u'DONß'), u_encode(u'DONÉ'), \\\n                        u_encode(u'DÖNE'), u_encode(u'WAITING'), \\\n                        u_encode(u'DONE'), u_encode(u'|')],\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"g:org_debug\")'): u_encode(u'0'),\n                u_encode(u'exists(\"*repeat#set()\")'): u_encode(u'0'),\n                u_encode(u'b:changedtick'): u_encode(u'0'),\n                u_encode(u'&ts'): u_encode(u'8'),\n                u_encode(u'exists(\"g:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u'exists(\"b:org_tag_column\")'): u_encode(u'0'),\n                u_encode(u\"v:count\"): u_encode(u'0')}\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"#Meta information\n#more meta information\n* TODO Überschrift 1     :testtag:\nText 1\n\nBla bla\n** TODO NOTODO Überschrift 1.1 :multi:tags:\nText 2\n\nBla Bla bla\n** NO-TODO Überschrift 1.2:notag:\nText 3\n\n**** NOTODOÜberschrift 1.2.1.falsch :no tag:\n\nBla Bla bla bla\n*** notodo Überschrift 1.2.1 :no tag\n*** NOTODo Überschrift 1.2.2 no tag:\n* WAITING Überschrift 2\t\t\t\t  :more:tags:\n* DONE Überschrift 3\t:lesser:tag:\n  asdf sdf\n* DÖNE Überschrift 4\n* DONß Überschrift 5\n* DONÉ Überschrift 6\n* DONé    Überschrift 7\n\"\"\".split(u'\\n') ]\n        self.document = VimBuffer().init_dom()\n\n    def test_no_space_after_upper_case_single_word_heading(self):\n        vim.current.buffer[:] = [ u_encode(i) for i in u\"\"\"\n* TEST\n** Text 1\n*** Text 2\n* Text 1\n** Text 1\n   some text that is\n   no heading\n\n\"\"\".split(u'\\n') ]\n        d = VimBuffer().init_dom()\n        self.assertEqual(unicode(d.headings[0]), u'* TEST')\n\n    def test_todo_read_TODO(self):\n        self.assertEqual(self.document.headings[0].todo, u'TODO')\n        self.assertEqual(self.document.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(self.document.headings[0]), u'* TODO Überschrift 1\t\t\t\t\t\t    :testtag:')\n\n    def test_todo_read_TODO_NOTODO(self):\n        self.assertEqual(self.document.headings[0].children[0].todo, u'TODO')\n        self.assertEqual(self.document.headings[0].children[0].title, u'NOTODO Überschrift 1.1')\n        self.assertEqual(unicode(self.document.headings[0].children[0]), u'** TODO NOTODO Überschrift 1.1\t\t\t\t\t :multi:tags:')\n\n    def test_todo_read_WAITING(self):\n        self.assertEqual(self.document.headings[1].todo, u'WAITING')\n        self.assertEqual(self.document.headings[1].title, u'Überschrift 2')\n        self.assertEqual(unicode(self.document.headings[1]), u'* WAITING Überschrift 2\t\t\t\t\t\t  :more:tags:')\n\n    def test_todo_read_DONE(self):\n        self.assertEqual(self.document.headings[2].todo, u'DONE')\n        self.assertEqual(self.document.headings[2].title, u'Überschrift 3')\n        self.assertEqual(unicode(self.document.headings[2]), u'* DONE Überschrift 3\t\t\t\t\t\t :lesser:tag:')\n\n    def test_todo_read_special(self):\n        self.assertEqual(self.document.headings[3].todo, u'DÖNE')\n        self.assertEqual(self.document.headings[3].title, u'Überschrift 4')\n\n        self.assertEqual(self.document.headings[4].todo, u'DONß')\n        self.assertEqual(self.document.headings[4].title, u'Überschrift 5')\n\n        self.assertEqual(self.document.headings[5].todo, u'DONÉ')\n        self.assertEqual(self.document.headings[5].title, u'Überschrift 6')\n\n        self.assertEqual(self.document.headings[6].todo, None)\n        self.assertEqual(self.document.headings[6].title, u'DONé    Überschrift 7')\n\n    def test_todo_del_todo(self):\n        self.assertEqual(self.document.headings[0].todo, u'TODO')\n        del self.document.headings[0].todo\n        self.assertEqual(self.document.headings[0].is_dirty_body, False)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, True)\n        self.assertEqual(self.document.headings[0].todo, None)\n        self.assertEqual(self.document.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(self.document.headings[0]), u'* Überschrift 1\t\t\t\t\t\t\t    :testtag:')\n        self.assertEqual(self.document.write(), True)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(d.headings[0].todo, None)\n        self.assertEqual(d.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(d.headings[0]), u'* Überschrift 1\t\t\t\t\t\t\t    :testtag:')\n\n    def test_todo_write_todo_uppercase(self):\n        self.assertEqual(self.document.headings[0].todo, u'TODO')\n        self.document.headings[0].todo = u'DONE'\n        self.assertEqual(self.document.headings[0].is_dirty_body, False)\n        self.assertEqual(self.document.headings[0].is_dirty_heading, True)\n        self.assertEqual(self.document.headings[0].todo, u'DONE')\n        self.assertEqual(self.document.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(self.document.headings[0]), u'* DONE Überschrift 1\t\t\t\t\t\t    :testtag:')\n        self.assertEqual(self.document.write(), True)\n\n        # sanity check\n        d = VimBuffer().init_dom()\n        self.assertEqual(d.headings[0].todo, u'DONE')\n        self.assertEqual(d.headings[0].title, u'Überschrift 1')\n        self.assertEqual(unicode(d.headings[0]), u'* DONE Überschrift 1\t\t\t\t\t\t    :testtag:')\n\n    def test_todo_set_illegal_todo(self):\n        def set_todo(todo):\n            self.document.headings[0].todo = todo\n        self.assertEqual(self.document.headings[0].todo, u'TODO')\n        self.assertRaises(ValueError, set_todo, u'DO NE')\n        self.assertRaises(ValueError, set_todo, u'DO\\tNE')\n        self.assertRaises(ValueError, set_todo, u'D\\nNE')\n        self.assertRaises(ValueError, set_todo, u'DO\\rNE')\n        self.assertEqual(self.document.headings[0].todo, u'TODO')\n\ndef suite():\n    return (\n        unittest.TestLoader().loadTestsFromTestCase(VimBufferTestCase),\n        unittest.TestLoader().loadTestsFromTestCase(VimBufferTagsTestCase),\n        unittest.TestLoader().loadTestsFromTestCase(VimBufferTodoTestCase),\n    )\n"
  },
  {
    "path": "tests/vim.py",
    "content": "# -*- coding: utf-8 -*-\n\n\nclass VimWindow(object):\n    u\"\"\" Docstring for VimWindow \"\"\"\n\n    def __init__(self, test):\n        object.__init__(self)\n        self._test = test\n        self.cursor = (1, 0)\n\n    def buffer():\n        def fget(self):\n            return self._test.buffer\n\n        def fset(self, value):\n            self._test.buffer = value\n        return locals()\n    buffer = property(**buffer())\n\n\nclass VimBuffer(list):\n    def __init__(self, iterable=None):\n        self.number = 0\n        if iterable is not None:\n            list.__init__(self, iterable)\n        else:\n            list.__init__(self)\n\n    def append(self, o):\n        u\"\"\"\n        mimic the specific behavior of vim.current.buffer\n        \"\"\"\n        if isinstance(o, list) or isinstance(o, tuple):\n            for i in o:\n                list.append(self, i)\n        else:\n            list.append(self, o)\n\n\nclass VimTest(object):\n    u\"\"\" Replacement for vim API \"\"\"\n\n    def __init__(self):\n        object.__init__(self)\n        self._buffer = VimBuffer()\n        self.window = VimWindow(self)\n\n    def buffer():\n        def fget(self):\n            return self._buffer\n\n        def fset(self, value):\n            self._buffer = VimBuffer(value)\n        return locals()\n    buffer = property(**buffer())\n\n\nEVALHISTORY = []\nEVALRESULTS = {\n        u'exists(\"g:org_debug\")': 0,\n        u'exists(\"b:org_debug\")': 0,\n        u'exists(\"*repeat#set()\")': 0,\n        u'exists(\"b:org_plugins\")': 0,\n        u'exists(\"g:org_plugins\")': 0,\n        u'b:changedtick': 0,\n        }\n\n\ndef eval(cmd):\n    u\"\"\" evaluate command\n\n    :returns: results stored in EVALRESULTS\n    \"\"\"\n    EVALHISTORY.append(cmd)\n    return EVALRESULTS.get(cmd, None)\n\n\nCMDHISTORY = []\nCMDRESULTS = {}\n\n\ndef command(cmd):\n    CMDHISTORY.append(cmd)\n    return CMDRESULTS.get(cmd, None)\n\n\ncurrent = VimTest()\n"
  }
]