- Introduction
- Installation
- Configuration
- Bindings
- Folding
- Meta-command
- Prompt completion
- Autocommands
- Related
- Misc
- Warning
Organ generalizes the great concepts of Orgmode to Markdown and any folded file. It is primarily focused on editing these documents with ease and agility.
Headline completion, todo, links, list, table :
See also the organ-multimedia repository.
- folding based on headings in org and markdown files
- headings based on markers folding in folded files
- you can handle your folds like headings in orgmode
- navigate in headings or list items hierarchy
- next, previous : any level
- forward, backward : same level as current one
- parent heading, upper level
- child heading, lower level :
- loosely speaking : first headline of level + 1, forward
- strictly speaking : must be in the current subtree
- go to another headline with prompt completion of full path
- modify headings or list items
- new headline or list item
- select, yank, delete subtree
- promote, demote heading or list item
- move subtree up or down
- move current subtree in another one (aka org-refile)
- cycle todo status
- headlines
- tags
- lists
- cycle list item prefix
- toggle checkbox
- checked boxes ratio on parent item
- tables
- inside of table : align columns
- also works with multibyte characters
- outside of table : align following a pattern
- go to next or previous cell
- go to beginning or end of cell
- duplicate above cell content to current one
- select cell content
- add new row, colum
- delete row, colum
- move row up or down
- move column left or right
- inside of table : align columns
- links
- store url at cursor
- create link with url completion
- goto link under or close to cursor
- goto next/previous link
- expand shortcut to template (aka org-structure-template)
- markdown support limited to code blocks
- insert timestamp
- insert unicode character
- refer to autoload/organ/unicode.vim to see available chars
- insert result of vim or python expression
- export in another format using
- pandoc
- emacs
- asciidoc or asciidoctor
- view exported document
- convert headings and links org <-> markdown
Organ supports :
- org files
- markdown
- folded files with markers
- indent folded files
- basic navigation
- subtree selection, yank & delete
- promote & demote subtree
- asciidoc
It is written in vimscript and is compatible with both Vim and Neovim.
- speed keys are also available in first char of list item line
- movements can
- wrap around the end of the file
- cross over a parent headline
The core part runs on its own.
Some extra-features need external tools, see below.
If you want to export your file to another format, you just need to have pandoc installed, and the plugin takes care of the rest. For org files, it can also be done with emacs installed, at least for the formats supported by orgmode.
For asciidoc files, you need to install asciidoc or asciidoctor.
If you want to add interactions between org or markdown files, you can install wheel. With it, you can :
- quickly jump to another org/markdown/whatever file
- look for headlines in all orgmode or markdown files of a group (aka outline)
- grep all your group files for special keywords, like TODO
Simply add this line after packager#init()
to your initialisation file :
call packager#add('chimay/organ', { 'type' : 'start' })
and run :PackagerInstall
(see the
vim-packager readme).
The syntax should be similar with other git oriented plugin managers.
You can clone the repository somewhere in your runtime-search-path
. You
can get a minimal version by asking a shallow clone (depth 1) and
filtering out the screenshots blobs :
mkdir -p ~/.local/share/nvim/site/pack/foo/start
cd ~/.local/share/nvim/site/pack/foo/start
git clone --depth 1 --filter=blob:none https://github.com/chimay/organ
If you install or update with git, don't forget to run :
:helptags doc
to be able to use the inline help.
Here is a complete example, cherrypick what you need :
if ! exists("g:organ_loaded")
" ---- DONT FORGET TO INITIALIZE DICTS BEFORE USING THEM
let g:organ_config = {}
let g:organ_config.prefixless_plugs = {}
let g:organ_config.completion = {}
let g:organ_config.list = {}
let g:organ_config.list.unordered = {}
let g:organ_config.list.ordered = {}
let g:organ_config.links = {}
let g:organ_config.templates = {}
let g:organ_config.expr = {}
" ---- enable for every file if > 0
" ---- default : 0
let g:organ_config.everywhere = 0
" ---- enable speed keys on first char of headlines and list items
" ---- default : 0
let g:organ_config.speedkeys = 1
" ---- key to trigger <plug>(organ-previous)
" ---- and go where speedkeys are available
" ---- examples : <m-p> (default), [z
let g:organ_config.previous = '<m-p>'
" ---- choose your mappings prefix (default)
let g:organ_config.prefix = '<m-o>'
" ---- enable prefixless maps
let g:organ_config.prefixless = 1
" ---- prefixless maps in these modes (default)
" ---- possible values : normal, visual, insert
let g:organ_config.prefixless_modes = ['normal', 'visual', 'insert']
" ---- enable only the prefixless maps you want
" ---- leave a list empty to enable all plugs in the mode
" ---- see the output of :map <plug>(organ- to see available plugs
" let g:organ_config.prefixless_plugs.normal = ['organ-backward', 'organ-forward']
" let g:organ_config.prefixless_plugs.visual = []
" let g:organ_config.prefixless_plugs.insert = []
" ---- whether to enable vowels-fuzzy completion
" ---- default : 0
let g:organ_config.completion.vocalize = 1
" ---- whether to enable word-fuzzy completion
" ---- default : 0
let g:organ_config.completion.wordize = 1
" ---- whether to enable full fuzzy completion
" ---- default : 0
let g:organ_config.completion.fuzzy = 0
" ---- whether to sort completion results by scores (default)
let g:organ_config.completion.scores = 0
" ---- number of spaces to indent each list level (default)
let g:organ_config.list.indent_length = 2
" ---- items chars in unordered list
let g:organ_config.list.unordered.org = ['-', '+', '*']
let g:organ_config.list.unordered.markdown = ['-', '+']
let g:organ_config.list.unordered.asciidoc = ['*', '**', '***']
" ---- items chars in ordered list
let g:organ_config.list.ordered.org = ['.', ')']
let g:organ_config.list.ordered.markdown = ['.']
let g:organ_config.list.ordered.asciidoc = ['.', '..', '...']
" ---- first item counter in an ordered list
" ---- must be >= 0, default 1
let g:organ_config.list.counter_start = 1
" ---- number of stored links to keep in history (default)
let g:organ_config.links.keep = 5
" ---- todo keywoard cycle
" ---- default : todo : TODO - DONE - none
" ---- no need to add none to the list
let g:organ_config.todo_cycle = ['TODO', 'IN PROGRESS', 'ALMOST DONE', 'DONE']
" ---- add/overwrite a template trigger & expansion
" ---- to see the default ones, run :echo organ#crystal#fetch('templates/expansions')
" -- #+begin_mystuff ... #+end_mystuff bloc
let g:organ_config.templates['<m'] = 'mystuff'
" -- #+mystuff: line
let g:organ_config.templates['+m'] = 'mystuff'
" ---- timestamp format
let g:organ_config.timestamp_format = '<%Y-%m-%d %a %H:%M>'
" ---- number of evaluated expressions to keep in history (default)
let g:organ_config.expr.keep = 30
" ---- custom maps
nmap <c-cr> <plug>(organ-meta-return)
imap <c-cr> <plug>(organ-meta-return)
nnoremap <space>o :<c-u>Organ<space>
endif
The following data :
- stored urls
are kept in the g:ORGAN_STOPS
global variable. It is persistent across
(neo)vim sessions if you have !
in your 'shada' (neovim) or 'viminfo'
(vim) option.
Plugs are intermediates that give you acces to the plugin routines. You can map your favorite keys like that :
nmap <c-n> <plug>(organ-next)
Here is a complete list :
Plugs | Heading or list item | Table |
---|---|---|
<plug> (organ-enable) |
enable in current buffer | |
<plug> (organ-previous) |
previous heading or item | |
<plug> (organ-next) |
next heading or item | |
<plug> (organ-backward) |
previous, same level | |
<plug> (organ-forward) |
next, same level | |
<plug> (organ-parent) |
parent heading or item | |
<plug> (organ-loose-child) |
loose child | |
<plug> (organ-strict-child) |
strict child | |
<plug> (organ-info) |
full heading path | |
<plug> (organ-goto-headline) |
go to headline, with comp | |
<plug> (organ-cycle-fold) |
cycle current fold | |
<plug> (organ-cycle-all-folds) |
cycle all folds | |
<plug> (organ-select-subtree) |
select subtree | |
<plug> (organ-yank-subtree) |
yank subtree | |
<plug> (organ-delete-subtree) |
delete subtree | |
<plug> (organ-meta-return) |
new heading or item | new row |
<plug> (organ-shift-return) |
new heading or checkbox | new row |
<plug> (organ-tab) |
go to next cell | |
<plug> (organ-shift-tab) |
go to prev cell | |
<plug> (organ-meta-left) |
promote | move column left |
<plug> (organ-meta-right) |
demote | move column right |
<plug> (organ-meta-up) |
move heading or item up | move row up |
<plug> (organ-meta-down) |
move heading or item down | move row down |
<plug> (organ-shift-left) |
cycle item prefix left | go to cell begin |
<plug> (organ-shift-right) |
cycle item prefix right | go to cell end |
<plug> (organ-shift-up) |
cycle todo keyword left | copy above -> cur cell |
<plug> (organ-shift-down) |
cycle todo keyword right | select cell |
<plug> (organ-meta-shift-left) |
promote subtree | delete column |
<plug> (organ-meta-shift-right) |
demote subtree | add new column |
<plug> (organ-meta-shift-up) |
delete row | |
<plug> (organ-meta-shift-down) |
add new row | |
<plug> (organ-move-subtree-to) |
move subtree, prompt comp | |
<plug> (organ-align) |
align table | |
<plug> (organ-new-separator-line) |
add separator line |
Plugs | Operation |
---|---|
<plug> (organ-expand-template) |
expand template before cursor |
<plug> (organ-store-url) |
store url under or near cursor |
<plug> (organ-new-link) |
create new link |
<plug> (organ-previous-link) |
go to previous link |
<plug> (organ-next-link) |
go to next link |
<plug> (organ-goto-link-target) |
go to link target |
<plug> (organ-timestamp) |
add timestamp at cursor |
<plug> (organ-eval-vim) |
eval vim expression |
<plug> (organ-eval-python) |
eval python expression |
<plug> (organ-unicode) |
add unicode character at cursor |
<plug> (organ-export) |
export document |
<plug> (organ-alter-export) |
export document, alternative tool |
You can also list them with the command :map <plug>(organ-
.
If you set the g:organ_config.speedkeys
variable to a greater-than-zero
value in your init file, the speed keys become available. They are active
only in normal mode, when the cursor is on the first char of a headline
or a list item line. Here is a complete list :
<f1>
: help<pageup>
: previous heading<pagedown>
: next heading<home>
: backward heading of same level<end>
: forward heading of same level+
: upper, parent heading-
: lower, child heading, loosely speaking_
: lower, child heading, strictly speakingi
: info : full headings path (part, chapter, section, subsection, ...)<space>
: go to headline, with prompt completion of full headings paths
: select subtreeY
: yank subtreeX
: delete subtree<del>
: promote heading (and delete a level of indent)<ins>
: demote heading (and insert a level of indent)H
: promote subtreeL
: demote subtreeU
: move subtree upD
: move subtree downM
: move subtree in another one, with prompt completion#
: toggle tag in headlinet
: cycle todo rightT
: cycle todo leftC
: toggle checkbox in list item
Some of them are context sensitive :
Map | First char in heading line | List | Table |
---|---|---|---|
<tab> |
cycle current fold visibility | toggle checkbox | go to next cell |
<s-tab> |
cycle all folds visibility | go to previous cell |
Some of them are filetype dependent :
Map | Org | Asciidoc | Other |
---|---|---|---|
% |
export with emacs | export with asciidoc | export with pandoc |
g% |
export with pandoc | export with asciidoctor | export with pandoc |
Once you are on the first char of a headline or list item, the speedkeys
become available. The plug <plug>(organ-previous)
brings you precisely
there, and is therefore one of the most important maps. For this reason,
it's always defined, regardless of the prefixless setting. You can use
g:organ_config.previous
to choose the key that triggers it.
If you set the g:organ_config.prefixless
variable to a greater-than-zero
value in your init file, these bindings become available :
<M-!>
: enable organ in current buffer<M-i>
: info : full headings path (chapter, section, subsection, ...)<M-h>
: go to headline, with prompt completion of full headings path<M-z>
: cycle current fold visibility (like an improvedza
)<M-S-z>
: cycle all folds visibility<M-m>
: move subtree in another one, with prompt completion<M-t>
: toggle tag on headline<M-c>
: toggle checkbox on list item<M-a>
: align table, paragraph or selected lines<M-_>
: add a separator line in a table<M-s>
: store url at cursor<M-->
: (press alt and dash) create new link<M-@>
: go to previous link<M-&>
: go to next link<M-o>
: go to link under or close to cursor<M-x>
: expand template<M-d>
: add date & time stamp<M-=>
: insert result of vim expression<M-'>
: insert result of python expression<M-$>
: add unicode character<M-e>
: export with pandoc<M-S-e>
: export with emacs (works only in org files)
Some of them are context sensitive :
Map | Heading | List | Table |
---|---|---|---|
<M-p> |
previous heading | previous item | |
<M-n> |
next heading | next item | |
<M-b> |
prev head, same level | prev item, = level | |
<M-f> |
next head, same level | next item, = level | |
<M-u> |
parent heading | parent item | |
<M-l> |
child heading, loose | child item, loose | |
<M-S-l> |
child heading, strict | child item, strict | |
<M-v> |
select subtree | select subtree | |
<M-y> |
yank subtree | yank subtree | |
<M-S-x> |
delete subtree | delete subtree | |
<M-CR> |
new headline | new item | new row |
<S-CR> |
new headline | new checkbox item | new row |
<M-left> |
promote | promote | move column left |
<M-right> |
demote | demote | move column right |
<M-up> |
move subtree up | move subtree up | move row up |
<M-down> |
move subtree down | move subtree down | move row down |
<S-left> |
cycle prefix left | go to cell begin | |
<S-right> |
cycle prefix right | go to cell end | |
<S-up> |
cycle todo left | cycle todo left | copy above -> cur cell |
<S-down> |
cycle todo right | cycle todo right | select cell |
<M-S-left> |
promote subtree | promote subtree | new column |
<M-S-right> |
demote subtree | demote subtree | delete column |
<M-S-up> |
delete row | ||
<M-S-down> |
new row |
Note that most table operations expect an aligned table. So, if it's not, you have to align it before juggling with rows & cols.
If there are some conflicts with your settings, you can restrict the prefixless maps to a sublist. Example :
let g:organ_config.prefixless_plugs = [
\ 'organ-meta-return',
\ 'organ-shift-return',
\ 'organ-tab',
\ 'organ-shift-tab',
\ 'organ-meta-left',
\ 'organ-meta-right',
\ 'organ-meta-up',
\ 'organ-meta-down',
\ 'organ-shift-left',
\ 'organ-shift-right',
\ 'organ-shift-up',
\ 'organ-shift-down',
\ 'organ-meta-shift-left',
\ 'organ-meta-shift-right',
\ 'organ-meta-shift-up',
\ 'organ-meta-shift-down',
\]
The elements of this list are derived from the plugs names. For instance,
organ-meta-return
is derived from <plug>(organ-meta-return)
You can also use a dictionary to have distinct map sets on normal, visual and insert modes :
let g:organ_config.prefixless_plugs = {}
let g:organ_config.prefixless_plugs.normal = [
\ 'organ-meta-return',
\ 'organ-shift-return',
\ 'organ-tab',
\ 'organ-shift-tab',
\ 'organ-meta-left',
\ 'organ-meta-right',
\ 'organ-meta-up',
\ 'organ-meta-down',
\]
let g:organ_config.prefixless_plugs.visual = []
let g:organ_config.prefixless_plugs.insert = []
Leaving a list empty means that all available plugs for the mode will be enabled.
You can also customize g:organ_config.prefixless_modes
to create
prefixless maps only in the modes you specify.
These are the same as the prefixless maps, but preceded by a prefix to
avoid conflicts with other plugins. Examples with the default prefix
<M-o>
:
<M-o><M-p>
: previous heading<M-o><M-n>
: next heading<M-o><M-b>
: previous heading of same level<M-o><M-f>
: next heading of same level
Some of them are inspired by orgmode, with <C-...>
replaced by <M-...>
.
You can customize the prefix by setting g:organ_config.prefix
to the
key you want.
The prefix bindings are always available, regardless of the
g:organ_config.prefixless
value.
Plugs can be mapped as usual :
nmap <c-n> <plug>(organ-next)
imap <c-n> <plug>(organ-next)
If you wish to enable it only for certain filetypes, you can use autocommands :
autocmd FileType org,markdown nmap <buffer> <c-n> <plug>(organ-next)
autocmd FileType org,markdown imap <buffer> <c-n> <plug>(organ-next)
This should have the same effect as writing :
nmap <buffer> <c-n> <plug>(organ-next)
imap <buffer> <c-n> <plug>(organ-next)
in ftplugin/org/main.vim
and ftplugin/markdown/main.vim
, somewhere
in your runtimepath.
You can find below a list of all available plugs.
Let's say you want to enable this plugin in text, python and vim files. Just add :
autocmd filetype text,vim,python call organ#void#enable ()
to your init file.
If you want to enable it for all filetypes, just set the everywhere setting :
let g:organ_config.everywhere = 1
This plugin is enabled by default in org & markdown files.
When editing a folded file, this plugin expect folds delimited by markers
with level included, like {{{1
, {{{2
, and so on. The closing markers
}}}
are useless, and could in fact have undesired side effects.
On files where foldmethod=indent
, a limited support for basic navigation
is available.
The :Organ
meta-command gives you access to all the plugin features :
:Organ subcommand
Examples :
:Organ store-url
:Organ export-with-pandoc
Some less-used features, like copying a subtree to another place, are only available via this command :
:Organ copy-subtree-to
Completion is available for subcommands.
I suggest you map it to a convenient key. Example :
nnoremap <space>o :<c-u>Organ<space>
Completion is available for :
- meta-command subcommands
- full path of headlines (goto, move to)
- adding a new link
- clipboard content
- stored links
- file tree in current directory
- links protocols
- template expansion
- languages of source code block
- unicode character
- expression history (insert expression result)
It is intended to work roughly as with the combo org-goto and helm in
Emacs. A space is interpreted as a logical and, a |
as a logical or. In
fact, it works exactly as in wheel.
If g:organ_config.completion.vocalize
is greater than 0, the plugin adds
vowels patterns between the chars you enter, to enable a kind of vowels-fuzzy
completion.
If g:wheel_config.completion.wordize
is greater than 0, the plugin
adds word-characters patterns between the chars you enter, to enable
a kind of word-fuzzy completion.
If g:organ_config.completion.fuzzy
is greater than 0, full fuzzy
completion is enabled.
For further details, please refer to the completion page on the wheel wiki.
Automatically update the current table alignment after each insertion :
augroup organ
autocmd!
autocmd InsertLeave *.org,*.md call organ#table#update ()
augroup END
If you copy some headings and links back and forth from org to markdown, you can automatically convert the links at buffer write with the following autocommands :
" ---- convert headings org <-> markdown
autocmd bufwritepre *.md call organ#tree#org2markdown ()
autocmd bufwritepre *.org call organ#tree#markdown2org ()
" ---- convert links org <-> markdown
autocmd bufwritepre *.md call organ#vine#org2markdown ()
autocmd bufwritepre *.org call organ#vine#markdown2org ()
- vim-orgmode (python)
- vimOrganizer (abandoned)
- nvim-orgmode (lua, neovim only)
All of these plugins are for org files only.
Besides being a short name for organizer, it's a pun for pipe-organ, especially the big ones. With all these keyboards, pedalboards and stop actions, an organist has to be organized, for sure.
First of all, it is not intended as a clone, more of a loose adaptation.
The current orgmode plugins for (neo)vim that I could find are for org files only, and are either :
- abandoned and not adapted for my usage
- written in python (which is fine but still a dependency)
- written in lua, which means they only work with neovim
So, I started to write a lightweight org-mode plugin in plain vimscript, and then I realized it wouldn't be too difficult to adapt it for markdown and folded files. And here it is !
Despite abundant testing, some bugs might remain, so be careful.