An attempt to build org-mode for vim (http://orgmode.org)
Information about the license are found in the file LICENSE
Open the file in vim and run the command “:so %”. The plugin is than installed into your .vim directory.
In case you want to install the plugin into a specific directory when you are using pathogen, e.g. $HOME/.vim/bundle/orgmode, then add this directory as the first one to the runtimepath and execute “:so %” as described.
:set rtp=$HOME/.vim/bundle/orgmode,&rtp :so %
Copy the directories ftdetect, ftplugin, indent and syntax to your $HOME/.vim directory or the bundle directory in case you are using pathogen.
vim-orgmode aims to be clone of the original orgmode for Emacs. Since Emacs is not vim the clone is not aiming for 100% compatibility. Especially in terms of the keybindings there will be major differences!
You’ll definitively enjoy the modal interface, this where vim’s strength is. Almost all keybindings for orgmode work only in normal and visual mode where as in insert mode just a few are available.
To start vim-orgmode open a file with the extension .org. An additional menu “Org” is shown that gives an overview of the implemented functionality and the keybindings.
- pathogen, for an easy management of multiple plugins, (http://www.vim.org/scripts/script.php?script_id=2332)
- repeat (http://www.vim.org/scripts/script.php?script_id=2136)
- taglist (http://www.vim.org/scripts/script.php?script_id=273)
- speeddating (http://www.vim.org/scripts/script.php?script_id=2120)
- Narrow Region (http://www.vim.org/scripts/script.php?script_id=3075)
- Ultimate Text Linking (http://www.vim.org/scripts/script.php?script_id=293)
orgmode.vba is a Vimball archive containing all files that are needed by the plugin. It’s installable, see Installation.
To build orgmode.vba.gz just run make in the root folder of this plugin.
build_vim - Build file for the Vimball ftdetect/ - Filetype detection for orgmode files ftplugin/ - Home of the main part of the plugin ftplugin/orgmode/ - Home for all Python code related to the plugin ftplugin/orgmode/plugins - Home for all orgmode plugins indent/ - Indentation for orgmode files LICENSE - License Information Makefile - Build file for the Vimball README - This file syntax/ - Syntax highlighting test/ - Tests to verify the consistency and correctness of the plugin
The majority of the source code is stored in folder ftplugin/orgmode. This is where the actual functionality of the plugin is located.
I choose to implement vim-orgmode mainly in Python. I hope this will ease the implementation especially with the functionality of the Python standard library at hand.
Right below the directory ftplugin/orgmode the basic implementation of vim-orgmode is found. This basic functionality provides everything for higher level implementations that modify the buffer, provide a menu and keybindings to the user and everything else that is needed.
Below the directory ftplugin/orgmode/plugins the plugins are located. Every plugin must provide a class equal to its filename with the .py-extension. An example for a plugin can be found in file ftplugin/orgmode/plugins/Example.py.
Every plugin must be enabled by the user by setting the g:org_plugins variable. By default all shipped plugins are enabled. Example:
let g:org_plugins = [‘ShowHide’, ‘|’, ‘Navigator’, ‘EditStructure’]
To write a plugin:
- copy file ftplugin/orgmode/plugins/Example.py to ftplugin/orgmode/plugins/YourPlugin.py
- Change class name to “YourPlugin”
- Set the menu name, it doesn’t need to match the filename anymore, e.g. “Your Plugin”
- Prepare keybindings in function register by defining a proper action and a key this action should be mapped to. For further information refer to section Keybindings.
- Register your plugin: let g:org_plugins = [‘ShowHide’, ‘|’, ‘Navigator’, ‘EditStructure’, ‘YourPlugin’]
- Implement YourPlugin
Keybindings alias mappings are described very well in the vim documentation, see |map-modes|. vim-orgmode tries to make it easy for the developer to register new keybindings, make them customizable and provide menu entries so that the user can access the functionality like in original orgmode.
This is done by providing three classes: Keybinding, Plug and ActionEntry
This is the basic class that encapsulates a single keybinding consisting of a key/mapping and an action. Several options can be set when creating the object to specify the mode and all kinds of other things.
If a Plug is given instead of an action string the Plug is bound to the key. All relevant data is read from the Plug, e.g. name, mode aso.
Map g{ to moving to parent heading in normal mode:
Keybinding(‘g{‘, ‘:py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR>’, mode=MODE_NORMAL) vim -> :nmap g{ :py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR>
Map g{ to moving to parent heading in normal mode by using a Plug:
Keybinding(‘g{‘, Plug(‘OrgJumpToParentNormal’, ‘:py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR>’)) vim -> :nnoremap <Plug>OrgJumpToParentNormal :py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR> vim -> :nmap g{ <Plug>OrgJumpToParentNormal
A Plug is a unique keybinding that can not be executed by pressing any key. This makes it a special Keybinding that takes a name and an action to create an object. A plug normally goes together with a regular Keybinding to bind the Plug to a key.
This special behavior is needed to ensure that keybindings are customizable by the user. If the user creates a keybinding to a Plug the Keybinding object makes sure that the users keybinding is used and the keybinding specified by the plugin is not used.
Map g{ to moving to parent heading in normal mode by using a Plug:
Keybinding(‘g{‘, Plug(‘OrgJumpToParentNormal’, ‘:py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR>’)) vim -> :nnoremap <Plug>OrgJumpToParentNormal :py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR> vim -> :nmap g{ <Plug>OrgJumpToParentNormal
An ActionEntry makes Keybindings accessible by the vim menu. It takes a description and a Keybinding object and builds a menu entry from this. The resulting object can be added to a Submenu object by using the + operator.
Map g{ to moving to parent heading in normal mode by using a Plug:
k = Keybinding(‘g{‘, Plug(‘OrgJumpToParentNormal’, ‘:py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR>’)) vim -> :nnoremap <Plug>OrgJumpToParentNormal :py ORGMODE.plugins[“Navigator”].parent(mode=”normal”)<CR> vim -> :nmap g{ <Plug>OrgJumpToParentNormal
menu + ActionEntry(‘&Up’, k) vim -> :nmenu &Org.&Naviagte Headings.&Up<Tab>g{ <Plug>OrgJumpToParentNormal
implement promotion/demotion of headings in visual mode, do I really need this? How do I promote/demote a single heading without subheadings?
implement other paragraph motions, e.g. d}, c{, this should also work for a whole heading with subheadings
Figure out a way to get the keys the user pressed to activate a mapping so that feedkeys can be used properly
implement better object structure for Heading.parent and Heading.children. At the moment the already created objects are not reused, especially for iterchildern this is important!
Create vimball http://vim.wikia.com/wiki/Using_VimBall_with_%27Make%27
vi: ft=org:tw=72:sw=4:ts=4