Slim down vim config

This commit is contained in:
Anthony Rose 2019-06-20 21:41:02 +01:00
parent 58a37ac525
commit 6c1efec2a5
246 changed files with 0 additions and 47778 deletions

View file

@ -1,3 +0,0 @@
.DS_Store
Thumbs.db
*.swp

View file

@ -1,109 +0,0 @@
jellybeans.vim
==============
A colorful, dark color scheme, inspired by [ir_black][] and [twilight][].
Designed primarily for a graphical Vim, but includes support for 256, 88, 16,
and 8 color terminals. On a 16 or 8 color terminal, replace its colors with
those in `ansi-term-colors.txt` for best results.
This script is [vimscript #2555][vimscript] at Vim.org.
Scroll down for [screenshots][ss-anchor]!
## Options
### Custom Highlights
If you prefer slightly different colors from what Jellybeans defines,
you can set `g:jellybeans_overrides` in your .vimrc to a dictionary of
custom highlighting parameters:
let g:jellybeans_overrides = {
\ 'Todo': { 'guifg': '303030', 'guibg': 'f0f000',
\ 'ctermfg': 'Black', 'ctermbg': 'Yellow',
\ 'attr': 'bold' },
\ 'Comment': { 'guifg': 'cccccc' },
\}
This removes the need to edit Jellybeans directly, simplifying
upgrades. In addition, RGB colors specified this way are run through
the same color approximation algorithm that the core theme uses, so
your colors work just as well in 256-color terminals.
If you can pick better colors than the approximator, specify them
in the `256ctermfg` and `256ctermbg` parameters to override
its choices.
#### Custom Background Colors
To set a custom background color, override the special
`background` highlight group:
let g:jellybeans_overrides = {
\ 'background': { 'guibg': '000000' },
\}
Jellybeans uses the background color in multiple highlight
groups. Using the special `background` group overrides them all
at once.
This replaces `g:jellybeans_background_color` and
`g:jellybeans_background_color_256` from Jellybeans versions
before 1.6.
#### Terminal Background
If you would prefer to use your terminal's default background
(e.g. for transparent backgrounds, image backgrounds, or a
different color) instead of the background color that Jellybeans
applies, use this `background` override:
let g:jellybeans_overrides = {
\ 'background': { 'ctermbg': 'none', '256ctermbg': 'none' },
\}
### Italics
Jellybeans disables italics in terminal Vim by default, as some
terminals do other things with the text's colors instead of
actually italicizing the text. If your terminal does fully
support italics, add
let g:jellybeans_use_term_italics = 1
to your .vimrc to enable italics in terminal Vim.
If you don't want italics even in GUI Vim, add
let g:jellybeans_use_gui_italics = 0
### Low-Color Black (16 and 8 color terminals)
Since the background on a dark terminal is usually black already,
Jellybeans appropriates the black ANSI color as a dark grey and
uses no color when it really wants black.
If you cant or dont want to change your terminals color
mappings, add
let g:jellybeans_use_lowcolor_black = 0
to your .vimrc to render “black” text as Vims grey (ANSI white).
Users of Apples pre-10.7 Terminal.app can use the TerminalColours
plugin ([Leopard][tc-leopard], [Snow Leopard][tc-snowleopard]) to
change the default colors.
## Screenshots
![][preview-ss]
[ir_black]: https://web.archive.org/web/20140211124943/http://toddwerth.com/2008/01/25/a-black-os-x-leopard-terminal-theme-that-is-actually-readable/
[twilight]: http://www.vim.org/scripts/script.php?script_id=1677
[vimscript]: http://www.vim.org/scripts/script.php?script_id=2555
[tc-leopard]: http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal
[tc-snowleopard]: https://github.com/timmfin/terminalcolours
[preview-ss]: https://nanotech.nanotechcorp.net/downloads/jellybeans-preview.png
[ss-anchor]: #screenshots

View file

@ -1,8 +0,0 @@
Black rgb(59,59,59) #3b3b3b
Red rgb(207,106,76) #cf6a4c
Green rgb(153,173,106) #99ad6a
Yellow rgb(216,173,76) #d8ad4c
Blue rgb(89,123,197) #597bc5
Magenta rgb(160,55,176) #a037b0
Cyan rgb(113,185,248) #71b9f8
White rgb(173,173,173) #adadad

View file

@ -1,668 +0,0 @@
" Vim color file
"
" " __ _ _ _ "
" " \ \ ___| | |_ _| |__ ___ __ _ _ __ ___ "
" " \ \/ _ \ | | | | | _ \ / _ \/ _ | _ \/ __| "
" " /\_/ / __/ | | |_| | |_| | __/ |_| | | | \__ \ "
" " \___/ \___|_|_|\__ |____/ \___|\____|_| |_|___/ "
" " \___/ "
"
" "A colorful, dark color scheme for Vim."
"
" File: jellybeans.vim
" URL: github.com/nanotech/jellybeans.vim
" Scripts URL: vim.org/scripts/script.php?script_id=2555
" Maintainer: NanoTech (nanotech.nanotechcorp.net)
" Version: 1.6
" Last Change: October 18th, 2016
" License: MIT
" Contributors: Andrew Wong (w0ng)
" Brian Marshall (bmars)
" Daniel Herbert (pocketninja)
" David Liang <bmdavll at gmail dot com>
" Henry So, Jr. <henryso@panix.com>
" Joe Doherty (docapotamus)
" Karl Litterfeldt (Litterfeldt)
" Keith Pitt (keithpitt)
" Philipp Rustemeier (12foo)
" Rafael Bicalho (rbika)
" Rich Healey (richo)
" Siwen Yu (yusiwen)
" Tim Willis (willist)
"
" Copyright (c) 2009-2016 NanoTech
"
" Permission is hereby granted, free of charge, to any per
" son obtaining a copy of this software and associated doc
" umentation files (the “Software”), to deal in the Soft
" ware without restriction, including without limitation
" the rights to use, copy, modify, merge, publish, distrib
" ute, sublicense, and/or sell copies of the Software, and
" to permit persons to whom the Software is furnished to do
" so, subject to the following conditions:
"
" The above copyright notice and this permission notice
" shall be included in all copies or substantial portions
" of the Software.
"
" THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY
" KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
" THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICU
" LAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CON
" TRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON
" NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
" THE SOFTWARE.
set background=dark
hi clear
if exists("syntax_on")
syntax reset
endif
let colors_name = "jellybeans"
if has("gui_running") || &t_Co == 88 || &t_Co == 256
let s:low_color = 0
else
let s:low_color = 1
endif
" Configuration Variables:
" - g:jellybeans_overrides (default = {})
" - g:jellybeans_use_lowcolor_black (default = 1)
" - g:jellybeans_use_gui_italics (default = 1)
" - g:jellybeans_use_term_italics (default = 0)
let s:background_color = "151515"
if exists("g:jellybeans_overrides")
let s:overrides = g:jellybeans_overrides
else
let s:overrides = {}
endif
" Backwards compatibility
if exists("g:jellybeans_background_color")
\ || exists("g:jellybeans_background_color_256")
\ || exists("g:jellybeans_use_term_background_color")
let s:overrides = deepcopy(s:overrides)
if !has_key(s:overrides, "background")
let s:overrides["background"] = {}
endif
if exists("g:jellybeans_background_color")
let s:overrides["background"]["guibg"] = g:jellybeans_background_color
endif
if exists("g:jellybeans_background_color_256")
let s:overrides["background"]["256ctermbg"] = g:jellybeans_background_color_256
endif
if exists("g:jellybeans_use_term_background_color")
\ && g:jellybeans_use_term_background_color
let s:overrides["background"]["ctermbg"] = "NONE"
let s:overrides["background"]["256ctermbg"] = "NONE"
endif
endif
if !exists("g:jellybeans_use_lowcolor_black") || g:jellybeans_use_lowcolor_black
let s:termBlack = "Black"
else
let s:termBlack = "Grey"
endif
" Color approximation functions by Henry So, Jr. and David Liang {{{
" Added to jellybeans.vim by Daniel Herbert
" returns an approximate grey index for the given grey level
fun! s:grey_number(x)
if &t_Co == 88
if a:x < 23
return 0
elseif a:x < 69
return 1
elseif a:x < 103
return 2
elseif a:x < 127
return 3
elseif a:x < 150
return 4
elseif a:x < 173
return 5
elseif a:x < 196
return 6
elseif a:x < 219
return 7
elseif a:x < 243
return 8
else
return 9
endif
else
if a:x < 14
return 0
else
let l:n = (a:x - 8) / 10
let l:m = (a:x - 8) % 10
if l:m < 5
return l:n
else
return l:n + 1
endif
endif
endif
endfun
" returns the actual grey level represented by the grey index
fun! s:grey_level(n)
if &t_Co == 88
if a:n == 0
return 0
elseif a:n == 1
return 46
elseif a:n == 2
return 92
elseif a:n == 3
return 115
elseif a:n == 4
return 139
elseif a:n == 5
return 162
elseif a:n == 6
return 185
elseif a:n == 7
return 208
elseif a:n == 8
return 231
else
return 255
endif
else
if a:n == 0
return 0
else
return 8 + (a:n * 10)
endif
endif
endfun
" returns the palette index for the given grey index
fun! s:grey_color(n)
if &t_Co == 88
if a:n == 0
return 16
elseif a:n == 9
return 79
else
return 79 + a:n
endif
else
if a:n == 0
return 16
elseif a:n == 25
return 231
else
return 231 + a:n
endif
endif
endfun
" returns an approximate color index for the given color level
fun! s:rgb_number(x)
if &t_Co == 88
if a:x < 69
return 0
elseif a:x < 172
return 1
elseif a:x < 230
return 2
else
return 3
endif
else
if a:x < 75
return 0
else
let l:n = (a:x - 55) / 40
let l:m = (a:x - 55) % 40
if l:m < 20
return l:n
else
return l:n + 1
endif
endif
endif
endfun
" returns the actual color level for the given color index
fun! s:rgb_level(n)
if &t_Co == 88
if a:n == 0
return 0
elseif a:n == 1
return 139
elseif a:n == 2
return 205
else
return 255
endif
else
if a:n == 0
return 0
else
return 55 + (a:n * 40)
endif
endif
endfun
" returns the palette index for the given R/G/B color indices
fun! s:rgb_color(x, y, z)
if &t_Co == 88
return 16 + (a:x * 16) + (a:y * 4) + a:z
else
return 16 + (a:x * 36) + (a:y * 6) + a:z
endif
endfun
" returns the palette index to approximate the given R/G/B color levels
fun! s:color(r, g, b)
" map greys directly (see xterm's 256colres.pl)
if &t_Co == 256 && a:r == a:g && a:g == a:b && a:r > 3 && a:r < 243
return float2nr(round(a:r - 8) / 10.0) + 232
endif
" get the closest grey
let l:gx = s:grey_number(a:r)
let l:gy = s:grey_number(a:g)
let l:gz = s:grey_number(a:b)
" get the closest color
let l:x = s:rgb_number(a:r)
let l:y = s:rgb_number(a:g)
let l:z = s:rgb_number(a:b)
if l:gx == l:gy && l:gy == l:gz
" there are two possibilities
let l:dgr = s:grey_level(l:gx) - a:r
let l:dgg = s:grey_level(l:gy) - a:g
let l:dgb = s:grey_level(l:gz) - a:b
let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
let l:dr = s:rgb_level(l:gx) - a:r
let l:dg = s:rgb_level(l:gy) - a:g
let l:db = s:rgb_level(l:gz) - a:b
let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
if l:dgrey < l:drgb
" use the grey
return s:grey_color(l:gx)
else
" use the color
return s:rgb_color(l:x, l:y, l:z)
endif
else
" only one possibility
return s:rgb_color(l:x, l:y, l:z)
endif
endfun
fun! s:is_empty_or_none(str)
return empty(a:str) || a:str ==? "NONE"
endfun
" returns the palette index to approximate the 'rrggbb' hex string
fun! s:rgb(rgb)
if s:is_empty_or_none(a:rgb)
return "NONE"
endif
let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
return s:color(l:r, l:g, l:b)
endfun
fun! s:prefix_highlight_value_with(prefix, color)
if s:is_empty_or_none(a:color)
return "NONE"
else
return a:prefix . a:color
endif
endfun
fun! s:remove_italic_attr(attr)
let l:attr = join(filter(split(a:attr, ","), "v:val !=? 'italic'"), ",")
if empty(l:attr)
let l:attr = "NONE"
endif
return l:attr
endfun
" sets the highlighting for the given group
fun! s:X(group, fg, bg, attr, lcfg, lcbg)
if s:low_color
exec "hi ".a:group.
\ " ctermfg=".s:prefix_highlight_value_with("", a:lcfg).
\ " ctermbg=".s:prefix_highlight_value_with("", a:lcbg)
else
exec "hi ".a:group.
\ " guifg=".s:prefix_highlight_value_with("#", a:fg).
\ " guibg=".s:prefix_highlight_value_with("#", a:bg).
\ " ctermfg=".s:rgb(a:fg).
\ " ctermbg=".s:rgb(a:bg)
endif
let l:attr = s:prefix_highlight_value_with("", a:attr)
if exists("g:jellybeans_use_term_italics") && g:jellybeans_use_term_italics
let l:cterm_attr = l:attr
else
let l:cterm_attr = s:remove_italic_attr(l:attr)
endif
if !exists("g:jellybeans_use_gui_italics") || g:jellybeans_use_gui_italics
let l:gui_attr = l:attr
else
let l:gui_attr = s:remove_italic_attr(l:attr)
endif
exec "hi ".a:group." gui=".l:gui_attr." cterm=".l:cterm_attr
endfun
" }}}
call s:X("Normal","e8e8d3",s:background_color,"","White","")
set background=dark
if version >= 700
call s:X("CursorLine","","1c1c1c","","",s:termBlack)
call s:X("CursorColumn","","1c1c1c","","",s:termBlack)
call s:X("MatchParen","ffffff","556779","bold","","DarkCyan")
call s:X("TabLine","000000","b0b8c0","italic","",s:termBlack)
call s:X("TabLineFill","9098a0","","","",s:termBlack)
call s:X("TabLineSel","000000","f0f0f0","italic,bold",s:termBlack,"White")
" Auto-completion
call s:X("Pmenu","ffffff","606060","","White",s:termBlack)
call s:X("PmenuSel","101010","eeeeee","",s:termBlack,"White")
endif
call s:X("Visual","","404040","","",s:termBlack)
call s:X("Cursor",s:background_color,"b0d0f0","","","")
call s:X("LineNr","605958",s:background_color,"NONE",s:termBlack,"")
call s:X("CursorLineNr","ccc5c4","","NONE","White","")
call s:X("Comment","888888","","italic","Grey","")
call s:X("Todo","c7c7c7","","bold","White",s:termBlack)
call s:X("StatusLine","000000","dddddd","italic","","White")
call s:X("StatusLineNC","ffffff","403c41","italic","White","Black")
call s:X("VertSplit","777777","403c41","",s:termBlack,s:termBlack)
call s:X("WildMenu","f0a0c0","302028","","Magenta","")
call s:X("Folded","a0a8b0","384048","italic",s:termBlack,"")
call s:X("FoldColumn","535D66","1f1f1f","","",s:termBlack)
call s:X("SignColumn","777777","333333","","",s:termBlack)
call s:X("ColorColumn","","000000","","",s:termBlack)
call s:X("Title","70b950","","bold","Green","")
call s:X("Constant","cf6a4c","","","Red","")
call s:X("Special","799d6a","","","Green","")
call s:X("Delimiter","668799","","","Grey","")
call s:X("String","99ad6a","","","Green","")
call s:X("StringDelimiter","556633","","","DarkGreen","")
call s:X("Identifier","c6b6ee","","","LightCyan","")
call s:X("Structure","8fbfdc","","","LightCyan","")
call s:X("Function","fad07a","","","Yellow","")
call s:X("Statement","8197bf","","","DarkBlue","")
call s:X("PreProc","8fbfdc","","","LightBlue","")
hi! link Operator Structure
hi! link Conceal Operator
call s:X("Type","ffb964","","","Yellow","")
call s:X("NonText","606060",s:background_color,"",s:termBlack,"")
call s:X("SpecialKey","444444","1c1c1c","",s:termBlack,"")
call s:X("Search","f0a0c0","302028","underline","Magenta","")
call s:X("Directory","dad085","","","Yellow","")
call s:X("ErrorMsg","","902020","","","DarkRed")
hi! link Error ErrorMsg
hi! link MoreMsg Special
call s:X("Question","65C254","","","Green","")
" Spell Checking
call s:X("SpellBad","","902020","underline","","DarkRed")
call s:X("SpellCap","","0000df","underline","","Blue")
call s:X("SpellRare","","540063","underline","","DarkMagenta")
call s:X("SpellLocal","","2D7067","underline","","Green")
" Diff
hi! link diffRemoved Constant
hi! link diffAdded String
" VimDiff
call s:X("DiffAdd","D2EBBE","437019","","White","DarkGreen")
call s:X("DiffDelete","40000A","700009","","DarkRed","DarkRed")
call s:X("DiffChange","","2B5B77","","White","DarkBlue")
call s:X("DiffText","8fbfdc","000000","reverse","Yellow","")
" PHP
hi! link phpFunctions Function
call s:X("StorageClass","c59f6f","","","Red","")
hi! link phpSuperglobal Identifier
hi! link phpQuoteSingle StringDelimiter
hi! link phpQuoteDouble StringDelimiter
hi! link phpBoolean Constant
hi! link phpNull Constant
hi! link phpArrayPair Operator
hi! link phpOperator Normal
hi! link phpRelation Normal
hi! link phpVarSelector Identifier
" Python
hi! link pythonOperator Statement
" Ruby
hi! link rubySharpBang Comment
call s:X("rubyClass","447799","","","DarkBlue","")
call s:X("rubyIdentifier","c6b6fe","","","Cyan","")
hi! link rubyConstant Type
hi! link rubyFunction Function
call s:X("rubyInstanceVariable","c6b6fe","","","Cyan","")
call s:X("rubySymbol","7697d6","","","Blue","")
hi! link rubyGlobalVariable rubyInstanceVariable
hi! link rubyModule rubyClass
call s:X("rubyControl","7597c6","","","Blue","")
hi! link rubyString String
hi! link rubyStringDelimiter StringDelimiter
hi! link rubyInterpolationDelimiter Identifier
call s:X("rubyRegexpDelimiter","540063","","","Magenta","")
call s:X("rubyRegexp","dd0093","","","DarkMagenta","")
call s:X("rubyRegexpSpecial","a40073","","","Magenta","")
call s:X("rubyPredefinedIdentifier","de5577","","","Red","")
" Erlang
hi! link erlangAtom rubySymbol
hi! link erlangBIF rubyPredefinedIdentifier
hi! link erlangFunction rubyPredefinedIdentifier
hi! link erlangDirective Statement
hi! link erlangNode Identifier
" Elixir
hi! link elixirAtom rubySymbol
" JavaScript
hi! link javaScriptValue Constant
hi! link javaScriptRegexpString rubyRegexp
hi! link javaScriptTemplateVar StringDelim
hi! link javaScriptTemplateDelim Identifier
hi! link javaScriptTemplateString String
" CoffeeScript
hi! link coffeeRegExp javaScriptRegexpString
" Lua
hi! link luaOperator Conditional
" C
hi! link cFormat Identifier
hi! link cOperator Constant
" Objective-C/Cocoa
hi! link objcClass Type
hi! link cocoaClass objcClass
hi! link objcSubclass objcClass
hi! link objcSuperclass objcClass
hi! link objcDirective rubyClass
hi! link objcStatement Constant
hi! link cocoaFunction Function
hi! link objcMethodName Identifier
hi! link objcMethodArg Normal
hi! link objcMessageName Identifier
" Vimscript
hi! link vimOper Normal
" HTML
hi! link htmlTag Statement
hi! link htmlEndTag htmlTag
hi! link htmlTagName htmlTag
" XML
hi! link xmlTag Statement
hi! link xmlEndTag xmlTag
hi! link xmlTagName xmlTag
hi! link xmlEqual xmlTag
hi! link xmlEntity Special
hi! link xmlEntityPunct xmlEntity
hi! link xmlDocTypeDecl PreProc
hi! link xmlDocTypeKeyword PreProc
hi! link xmlProcessingDelim xmlAttrib
" Debugger.vim
call s:X("DbgCurrent","DEEBFE","345FA8","","White","DarkBlue")
call s:X("DbgBreakPt","","4F0037","","","DarkMagenta")
" vim-indent-guides
if !exists("g:indent_guides_auto_colors")
let g:indent_guides_auto_colors = 0
endif
call s:X("IndentGuidesOdd","","232323","","","")
call s:X("IndentGuidesEven","","1b1b1b","","","")
" Plugins, etc.
hi! link TagListFileName Directory
call s:X("PreciseJumpTarget","B9ED67","405026","","White","Green")
" Manual overrides for 256-color terminals. Dark colors auto-map badly.
if !s:low_color
hi StatusLineNC ctermbg=235
hi Folded ctermbg=236
hi DiffText ctermfg=81
hi DbgBreakPt ctermbg=53
hi IndentGuidesOdd ctermbg=235
hi IndentGuidesEven ctermbg=234
endif
if !empty("s:overrides")
fun! s:current_attr(group)
let l:synid = synIDtrans(hlID(a:group))
let l:attrs = []
for l:attr in ["bold", "italic", "reverse", "standout", "underline", "undercurl"]
if synIDattr(l:synid, l:attr, "gui") == 1
call add(l:attrs, l:attr)
endif
endfor
return join(l:attrs, ",")
endfun
fun! s:current_color(group, what, mode)
let l:color = synIDattr(synIDtrans(hlID(a:group)), a:what, a:mode)
if l:color == -1
return ""
else
return substitute(l:color, "^#", "", "")
endif
endfun
fun! s:load_color_def(group, def)
call s:X(a:group, get(a:def, "guifg", s:current_color(a:group, "fg", "gui")),
\ get(a:def, "guibg", s:current_color(a:group, "bg", "gui")),
\ get(a:def, "attr", s:current_attr(a:group)),
\ get(a:def, "ctermfg", s:current_color(a:group, "fg", "cterm")),
\ get(a:def, "ctermbg", s:current_color(a:group, "bg", "cterm")))
if !s:low_color
for l:prop in ["ctermfg", "ctermbg"]
let l:override_key = "256".l:prop
if has_key(a:def, l:override_key)
exec "hi ".a:group." ".l:prop."=".a:def[l:override_key]
endif
endfor
endif
endfun
fun! s:load_colors(defs)
for [l:group, l:def] in items(a:defs)
if l:group == "background"
call s:load_color_def("LineNr", l:def)
call s:load_color_def("NonText", l:def)
call s:load_color_def("Normal", l:def)
else
call s:load_color_def(l:group, l:def)
endif
unlet l:group
unlet l:def
endfor
endfun
call s:load_colors(s:overrides)
delf s:load_colors
delf s:load_color_def
delf s:current_color
delf s:current_attr
endif
" delete functions {{{
delf s:X
delf s:remove_italic_attr
delf s:prefix_highlight_value_with
delf s:rgb
delf s:is_empty_or_none
delf s:color
delf s:rgb_color
delf s:rgb_level
delf s:rgb_number
delf s:grey_color
delf s:grey_level
delf s:grey_number
" }}}

View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2016-2018 Diki Ananta
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,85 +0,0 @@
<p align="center">
<img src="https://i.imgur.com/wXBrfyv.png" alt="Minimalist on HTML">
</p>
# Minimalist
Minimalist is a Material Color Scheme Darker for Vim & inspired by
[Material Theme](https://github.com/equinusocio/material-theme).
## Installation
To install this color scheme, you can use one of the following ways:
- Use [Vundle](https://github.com/VundleVim/Vundle.vim#quick-start) by adding
to your `.vimrc` Vundle plugin section:
Plugin 'dikiaap/minimalist'
Then run `:PluginInstall`.
OR
- Use [vim-plug](https://github.com/junegunn/vim-plug#installation) by adding
to your `.vimrc` vim-plug section:
Plug 'dikiaap/minimalist'
Then run `:PlugInstall`.
OR
- Use [Pathogen](https://github.com/tpope/vim-pathogen#installation):
Run the following in a terminal:
cd ~/.vim/bundle
git clone https://github.com/dikiaap/minimalist
## Usage
After finishing installation, put this code to your `.vimrc`:
```viml
set t_Co=256
syntax on
colorscheme minimalist
```
This color scheme also built-in with airline theme. If you wanna use:
```viml
let g:airline_theme='minimalist'
let g:airline_powerline_fonts = 1
let g:airline#extensions#tabline#enabled = 1
```
## Support
As you know, color scheme in vim by default supports many programming languages.
At this time `minimalist` is looks beautiful & focused on:
* C++
* CSS/CSS3
* HTML/HTML5
* JavaScript
* Markdown
* PHP
* Python
* Ruby
* Sass
* Shell
* XML
If you need more syntax highlighting, you can use
[vim-polyglot](https://github.com/sheerun/vim-polyglot).
## Links
[GitHub](https://github.com/dikiaap/minimalist) ·
[Vim.org](https://www.vim.org/scripts/script.php?script_id=5490) ·
[Vim Awesome](https://vimawesome.com/plugin/minimalist-vim) ·
[DotShare.it](http://dotshare.it/dots/1397/)
## License
MIT © [Diki Ananta](https://dikiaap.id)

View file

@ -1,46 +0,0 @@
" Minimalist Airline - A Material Color Scheme Darker
"
" Author: Diki Ananta <diki1aap@gmail.com>
" Repository: https://github.com/dikiaap/minimalist
" Version: 1.6
" License: MIT
" Normal Mode
let s:N1 = [ '#E4E4E4', '#3A3A3A', 254, 237 ]
let s:N2 = [ '#E4E4E4', '#4E4E4E', 254, 239 ]
let s:N3 = [ '#EEEEEE', '#262626', 255, 235 ]
" Inactive Mode
let s:IA = [ '#666666', s:N3[1], 242, s:N3[3] ]
" Warning Mode
let s:WI = [ '#1C1C1C', '#FFAF5F', 234, 215 ]
" Error Mode
let s:ER = [ s:WI[0], '#D75F5F', s:WI[2], 167 ]
" Terminal Mode
let s:TE = [ s:WI[0], s:N1[1], s:N1[2], s:N1[3] ]
" Reverse Mode
let s:NR = [ s:N2[1], s:N2[0], s:N2[3], s:N2[2], 'bold' ]
let g:airline#themes#minimalist#palette = {}
" Generate
let g:airline#themes#minimalist#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3)
let g:airline#themes#minimalist#palette.insert = g:airline#themes#minimalist#palette.normal
let g:airline#themes#minimalist#palette.visual = g:airline#themes#minimalist#palette.normal
let g:airline#themes#minimalist#palette.replace = g:airline#themes#minimalist#palette.normal
let g:airline#themes#minimalist#palette.inactive = airline#themes#generate_color_map(s:IA, s:IA, s:IA)
let g:airline#themes#minimalist#palette.normal.airline_warning = s:WI
let g:airline#themes#minimalist#palette.normal.airline_error = s:ER
let g:airline#themes#minimalist#palette.normal.airline_term = s:TE
" Accents
let g:airline#themes#minimalist#palette.accents = { 'red': [ s:ER[1], '', s:ER[3], '' ] }
" CtrlP
if get(g:, 'loaded_ctrlp', 0)
let g:airline#themes#minimalist#palette.ctrlp = airline#extensions#ctrlp#generate_color_map(s:N3, s:N2, s:NR)
endif

View file

@ -1,227 +0,0 @@
" Minimalist - A Material Color Scheme Darker
"
" Author: Diki Ananta <diki1aap@gmail.com>
" Repository: https://github.com/dikiaap/minimalist
" Version: 1.6
" License: MIT
set background=dark
if version > 580
hi clear
if exists("syntax_on")
syntax reset
endif
endif
set t_Co=256
let g:colors_name = "minimalist"
"""""""""""""""""""""""
" General
"""""""""""""""""""""""
hi ColorColumn ctermfg=NONE ctermbg=233 cterm=NONE guifg=NONE guibg=#121212 gui=NONE
hi Cursor ctermfg=234 ctermbg=255 cterm=NONE guifg=#1C1C1C guibg=#EEEEEE gui=NONE
hi CursorColumn ctermfg=NONE ctermbg=233 cterm=NONE guifg=NONE guibg=#121212 gui=NONE
hi CursorLine ctermfg=NONE ctermbg=233 cterm=NONE guifg=NONE guibg=#121212 gui=NONE
hi CursorLineNr ctermfg=59 ctermbg=233 cterm=NONE guifg=#5F5F5F guibg=#121212 gui=NONE
hi DiffAdd ctermfg=255 ctermbg=64 cterm=bold guifg=#EEEEEE guibg=#5F8700 gui=bold
hi DiffChange ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE
hi DiffDelete ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi DiffText ctermfg=255 ctermbg=24 cterm=bold guifg=#EEEEEE guibg=#005F87 gui=bold
hi Directory ctermfg=179 ctermbg=NONE cterm=NONE guifg=#D7AF5F guibg=NONE gui=NONE
hi ErrorMsg ctermfg=255 ctermbg=167 cterm=NONE guifg=#EEEEEE guibg=#D75F5F gui=NONE
hi FoldColumn ctermfg=117 ctermbg=239 cterm=NONE guifg=#87D7FF guibg=#4E4E4E gui=NONE
hi Folded ctermfg=242 ctermbg=234 cterm=NONE guifg=#666666 guibg=#1C1C1C gui=NONE
hi IncSearch ctermfg=234 ctermbg=75 cterm=NONE guifg=#1C1C1C guibg=#5FAFFF gui=NONE
hi LineNr ctermfg=59 ctermbg=234 cterm=NONE guifg=#5F5F5F guibg=#1C1C1C gui=NONE
hi MatchParen ctermfg=NONE ctermbg=NONE cterm=underline guifg=NONE guibg=NONE gui=underline
hi MoreMsg ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi NonText ctermfg=234 ctermbg=234 cterm=NONE guifg=#1C1C1C guibg=#1C1C1C gui=NONE
hi Normal ctermfg=255 ctermbg=234 cterm=NONE guifg=#EEEEEE guibg=#1C1C1C gui=NONE
hi Pmenu ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE
hi PmenuSel ctermfg=NONE ctermbg=59 cterm=NONE guifg=NONE guibg=#5F5F5F gui=NONE
hi Question ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=bold
hi Search ctermfg=NONE ctermbg=NONE cterm=underline guifg=NONE guibg=NONE gui=underline
hi SignColumn ctermfg=NONE ctermbg=237 cterm=NONE guifg=NONE guibg=#3A3A3A gui=NONE
hi StatusLine ctermfg=255 ctermbg=239 cterm=bold guifg=#EEEEEE guibg=#4E4E4E gui=bold
hi StatusLineNC ctermfg=255 ctermbg=239 cterm=NONE guifg=#EEEEEE guibg=#4E4E4E gui=NONE
hi Title ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi Underlined ctermfg=NONE ctermbg=NONE cterm=NONE guifg=NONE guibg=NONE gui=NONE
hi VertSplit ctermfg=239 ctermbg=239 cterm=NONE guifg=#4E4E4E guibg=#4E4E4E gui=NONE
hi Visual ctermfg=NONE ctermbg=236 cterm=NONE guifg=NONE guibg=#303030 gui=NONE
hi WarningMsg ctermfg=255 ctermbg=167 cterm=NONE guifg=#EEEEEE guibg=#D75F5F gui=NONE
hi WildMenu ctermfg=234 ctermbg=215 cterm=NONE guifg=#1C1C1C guibg=#FFAF5F gui=NONE
hi NERDTreeUp ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi NERDTreeDir ctermfg=251 ctermbg=NONE cterm=bold guifg=#C6C6C6 guibg=NONE gui=bold
hi NERDTreeDirSlash ctermfg=251 ctermbg=NONE cterm=NONE guifg=#C6C6C6 guibg=NONE gui=NONE
hi NERDTreeFile ctermfg=241 ctermbg=NONE cterm=NONE guifg=#606060 guibg=NONE gui=NONE
hi NERDTreeCWD ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi NERDTreeOpenable ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi NERDTreeClosable ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
"""""""""""""""""""""""
" Syntax Highlighting
"""""""""""""""""""""""
hi Boolean ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi Character ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Comment ctermfg=240 ctermbg=NONE cterm=NONE guifg=#585858 guibg=NONE gui=NONE
hi Conditional ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Constant ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Define ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Error ctermfg=255 ctermbg=167 cterm=NONE guifg=#EEEEEE guibg=#D75F5F gui=NONE
hi Float ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Function ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi Identifier ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=italic
hi Keyword ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Label ctermfg=186 ctermbg=NONE cterm=NONE guifg=#D7D787 guibg=NONE gui=NONE
hi Number ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi Operator ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi PreCondit ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi PreProc ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Repeat ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Special ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi SpecialComment ctermfg=242 ctermbg=NONE cterm=NONE guifg=#666666 guibg=NONE gui=NONE
hi SpecialKey ctermfg=59 ctermbg=237 cterm=NONE guifg=#5F5F5F guibg=#3A3A3A gui=NONE
hi SpellBad ctermfg=255 ctermbg=167 cterm=NONE guifg=#EEEEEE guibg=#D75F5F gui=undercurl
hi SpellCap ctermfg=255 ctermbg=74 cterm=NONE guifg=#EEEEEE guibg=#5FAFD7 gui=undercurl
hi SpellRare ctermfg=255 ctermbg=140 cterm=NONE guifg=#EEEEEE guibg=#AF87D7 gui=undercurl
hi SpellLocal ctermfg=255 ctermbg=14 cterm=NONE guifg=#EEEEEE guibg=#5FB3B3 gui=undercurl
hi Statement ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi StorageClass ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=italic
hi String ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi Structure ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi Tag ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi Todo ctermfg=74 ctermbg=234 cterm=inverse guifg=#5FAFD7 guibg=#1C1C1C gui=inverse,bold
hi Type ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
"""""""""""""""""""""""
" Supports
"""""""""""""""""""""""
hi cInclude ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE " C++
hi cOperator ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi cppStatement ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi cssAttr ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE " CSS/CSS3
hi cssAttrComma ctermfg=231 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi cssBoxProp ctermfg=152 ctermbg=NONE cterm=NONE guifg=#AFD7D7 guibg=NONE gui=NONE
hi cssBraces ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi cssClassName ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi cssColor ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi cssCommonAttr ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi cssFontAttr ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi cssFunctionName ctermfg=75 ctermbg=NONE cterm=NONE guifg=#5FAFFF guibg=NONE gui=NONE
hi cssNoise ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi cssProp ctermfg=152 ctermbg=NONE cterm=NONE guifg=#AFD7D7 guibg=NONE gui=NONE
hi cssPseudoClass ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi cssPseudoClassId ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi cssTagName ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi cssUIAttr ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi cssUnitDecorators ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi cssURL ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=italic
hi cssValueLength ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi cssValueNumber ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi cssVendor ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi htmlArg ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE " HTML/HTML5
hi htmlEndTag ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi htmlScriptTag ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi htmlSpecialChar ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi htmlSpecialTagName ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi htmlTag ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi htmlTagName ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi javaScriptBoolean ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE " JavaScript
hi javaScriptBraces ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi javaScriptConditional ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi javaScriptException ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi javaScriptFunction ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=italic
hi javaScriptGlobal ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi javaScriptIdentifier ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi javaScriptLabel ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi javaScriptMessage ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi javaScriptNull ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi javaScriptNumber ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi javaScriptOperator ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi javaScriptParens ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi javaScriptRegexpString ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi javaScriptRepeat ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi javaScriptSpecial ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi javaScriptStatement ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi markdownCode ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE " Markdown
hi markdownCodeBlock ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi markdownCodeDelimiter ctermfg=247 ctermbg=NONE cterm=NONE guifg=#9E9E9E guibg=NONE gui=NONE
hi markdownError ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi markdownHeadingDelimiter ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi markdownUrl ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi phpBoolean ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE " PHP
hi phpClass ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi phpClassDelimiter ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi phpClassExtends ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi phpClassImplements ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi phpCommentStar ctermfg=240 ctermbg=NONE cterm=NONE guifg=#585858 guibg=NONE gui=NONE
hi phpCommentTitle ctermfg=240 ctermbg=NONE cterm=NONE guifg=#585858 guibg=NONE gui=NONE
hi phpDocComment ctermfg=240 ctermbg=NONE cterm=NONE guifg=#585858 guibg=NONE gui=NONE
hi phpDocIdentifier ctermfg=240 ctermbg=NONE cterm=NONE guifg=#585858 guibg=NONE gui=NONE
hi phpDocParam ctermfg=240 ctermbg=NONE cterm=NONE guifg=#585858 guibg=NONE gui=NONE
hi phpDocTags ctermfg=242 ctermbg=NONE cterm=NONE guifg=#666666 guibg=NONE gui=NONE
hi phpFunction ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi phpFunctions ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi phpIdentifier ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi phpInclude ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi phpKeyword ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi phpMethod ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi phpNumber ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi phpOperator ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi phpParent ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi phpMemberSelector ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi phpMethodsVar ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi phpStaticClasses ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi phpStringDouble ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi phpStringDelimiter ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi phpStringSingle ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi phpSuperglobals ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi phpType ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi phpUseClass ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi phpVarSelector ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi pythonConditional ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE " Python
hi pythonDecorator ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi pythonException ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi pythonFunction ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi pythonInclude ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi pythonNumber ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi pythonOperator ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi pythonRepeat ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi pythonStatement ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi pythonTodo ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi rubyBlockParameter ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE " Ruby
hi rubyClass ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi rubyClassVariable ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubyConstant ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=italic
hi rubyControl ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubyException ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi rubyFunction ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi rubyInclude ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi rubyInstanceVariable ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubyInterpolationDelimiter ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubyOperator ctermfg=140 ctermbg=NONE cterm=NONE guifg=#AF87D7 guibg=NONE gui=NONE
hi rubyPseudoVariable ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi rubyRegexp ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubyRegexpDelimiter ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubyStringDelimiter ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi rubySymbol ctermfg=150 ctermbg=NONE cterm=NONE guifg=#AFD787 guibg=NONE gui=NONE
hi sassClass ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE " Sass
hi sassClassChar ctermfg=215 ctermbg=NONE cterm=NONE guifg=#FFAF5F guibg=NONE gui=NONE
hi sassFunction ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi sassInclude ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi sassVariable ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi shFunction ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE " Shell
hi shOperator ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi shStatement ctermfg=74 ctermbg=NONE cterm=NONE guifg=#5FAFD7 guibg=NONE gui=NONE
hi shTestOpr ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi shVariable ctermfg=255 ctermbg=NONE cterm=NONE guifg=#EEEEEE guibg=NONE gui=NONE
hi xmlAttrib ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE " XML
hi xmlCdataStart ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi xmlCdataCdata ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi xmlEndTag ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE
hi xmlEntity ctermfg=173 ctermbg=NONE cterm=NONE guifg=#D7875F guibg=NONE gui=NONE
hi xmlEntityPunct ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi xmlEqual ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi xmlProcessingDelim ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi xmlTag ctermfg=117 ctermbg=NONE cterm=NONE guifg=#87D7FF guibg=NONE gui=NONE
hi xmlTagName ctermfg=167 ctermbg=NONE cterm=NONE guifg=#D75F5F guibg=NONE gui=NONE

View file

@ -1 +0,0 @@
/doc/tags

View file

@ -1,7 +0,0 @@
---
sudo: required
services:
- docker
language: generic
script: |
cd test && ./run-tests

View file

@ -1,10 +0,0 @@
cmdargs:
# Checking more strictly
severity: style_problem
policies:
# Disable a violation
ProhibitUnnecessaryDoubleQuote:
enabled: false
ProhibitImplicitScopeVariable:
enabled: false

View file

@ -1,27 +0,0 @@
<!--
Hi, and thanks for reporting an issue with rust.vim.
Details about your environment will help us assist you.
Please edit this template!
-->
* rust.vim version: <!-- Describe if you use a Vim plugin manager, and you
can use it to tell which version of rust.vim you are running. -->
Steps to reproduce:
<!-- It's best to try to reproduce the issue with the master version of
rust.vim. The issue may already be fixed! -->
_?_
Expected vs. actual behavior:
_?_
Paste debugging info from the Rust Vim plugin via _one_ of the following
commands: `:RustInfo`, `:RustInfoToClipboard`, or `:RustInfoToFile <filename>`.
_?_

View file

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,25 +0,0 @@
Copyright (c) 2015 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View file

@ -1,107 +0,0 @@
# rust.vim
## Description
This is a Vim plugin that provides [Rust][r] file detection, syntax highlighting, formatting,
[Syntastic][syn] integration, and more. It requires Vim 8 or higher for full functionality.
Some things may not work on earlier versions.
## Installation
Use one of the following package managers:
* [Vim8 packages][vim8pack]:
* `git clone https://github.com/rust-lang/rust.vim ~/.vim/pack/plugins/start/rust.vim`
* [Vundle][v]:
* Add `Plugin 'rust-lang/rust.vim'` to `~/.vimrc`
* `:PluginInstall` or `$ vim +PluginInstall +qall`
* *Note:* Vundle will not automatically detect Rust files properly if `filetype
on` is executed before Vundle. Please check the [quickstart][vqs] for more
details. Errors such as `Not an editor command: RustFmt` may occur if Vundle
is misconfigured with this plugin.
* [Pathogen][p]:
* `git clone --depth=1 https://github.com/rust-lang/rust.vim.git ~/.vim/bundle/rust.vim`
* [vim-plug][vp]:
* Add `Plug 'rust-lang/rust.vim'` to `~/.vimrc`
* `:PlugInstall` or `$ vim +PlugInstall +qall`
* [dein.vim][d]:
* Add `call dein#add('rust-lang/rust.vim')` to `~/.vimrc`
* `:call dein#install()`
* [NeoBundle][nb]:
* Add `NeoBundle 'rust-lang/rust.vim'` to `~/.vimrc`
* Re-open vim or execute `:source ~/.vimrc`
## Features
### Error checking with [Syntastic][syn]
`rust.vim` automatically registers `cargo` as a syntax checker with
[Syntastic][syn], if nothing else is specified. See `:help rust-syntastic`
for more details.
### Source browsing with [Tagbar][tgbr]
`rust.vim` has builtin `ctags/` definitions for [Tagbar][tgbr] which
are loaded if Tagbar is installed.
### Formatting with [rustfmt][rfmt]
The `:RustFmt` command will format your code with
[rustfmt][rfmt] if installed.
Placing `let g:rustfmt_autosave = 1` in your `~/.vimrc` will
enable automatic running of `:RustFmt` when you save a buffer.
Do `:help :RustFmt` for further formatting help and customization
options.
### [Playpen][pp] integration
*Note:* This feature requires [webapi-vim][wav] to be installed.
The `:RustPlay` command will send the current selection, or if
nothing is selected the current buffer, to the [Rust playpen][pp].
If you set g:rust_clip_command RustPlay will copy the url to the clipboard.
- Mac:
let g:rust_clip_command = 'pbcopy'
- Linux:
let g:rust_clip_command = 'xclip -selection clipboard'
### Running a test under cursor
In cargo project, the `:RustTest` command will run a test under the cursor.
This is useful when your project is bigger and running all tests take longer time.
## Help
Further help can be found in the documentation with `:Helptags` then `:help rust`.
Detailed help can be found in the documentation with `:help rust`.
Helptags (`:help helptags`) need to be generated for this plugin
in order to navigate the help. Most plugin managers will do this
automatically, but check their documentation if that is not the case.
## License
Like Rust, rust.vim is primarily distributed under the terms of both the MIT
license and the Apache License (Version 2.0). See LICENSE-APACHE and
LICENSE-MIT for details.
[r]: https://www.rust-lang.org
[v]: https://github.com/gmarik/vundle
[vqs]: https://github.com/gmarik/vundle#quick-start
[p]: https://github.com/tpope/vim-pathogen
[nb]: https://github.com/Shougo/neobundle.vim
[vp]: https://github.com/junegunn/vim-plug
[d]: https://github.com/Shougo/dein.vim
[rfmt]: https://github.com/rust-lang-nursery/rustfmt
[syn]: https://github.com/scrooloose/syntastic
[tgbr]: https://github.com/majutsushi/tagbar
[wav]: https://github.com/mattn/webapi-vim
[pp]: https://play.rust-lang.org/
[vim8pack]: http://vimhelp.appspot.com/repeat.txt.html#packages

View file

@ -1,41 +0,0 @@
scriptencoding utf-8
if !get(g:, 'rust_conceal', 0) || !has('conceal') || &encoding !=# 'utf-8'
finish
endif
" For those who don't want to see `::`...
if get(g:, 'rust_conceal_mod_path', 0)
syn match rustNiceOperator "::" conceal cchar=
endif
syn match rustRightArrowHead contained ">" conceal cchar= 
syn match rustRightArrowTail contained "-" conceal cchar=
syn match rustNiceOperator "->" contains=rustRightArrowHead,rustRightArrowTail
syn match rustFatRightArrowHead contained ">" conceal cchar= 
syn match rustFatRightArrowTail contained "=" conceal cchar=
syn match rustNiceOperator "=>" contains=rustFatRightArrowHead,rustFatRightArrowTail
syn match rustNiceOperator /\<\@!_\(_*\>\)\@=/ conceal cchar=
" For those who don't want to see `pub`...
if get(g:, 'rust_conceal_pub', 0)
syn match rustPublicSigil contained "pu" conceal cchar=
syn match rustPublicRest contained "b" conceal cchar= 
syn match rustNiceOperator "pub " contains=rustPublicSigil,rustPublicRest
endif
hi link rustNiceOperator Operator
if !get(g:, 'rust_conceal_mod_path', 0)
hi! link Conceal Operator
augroup rust.vim.after
autocmd!
" And keep it after a colorscheme change
autocmd ColorScheme <buffer> hi! link Conceal Operator
augroup END
endif
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,115 +0,0 @@
function! cargo#Load()
" Utility call to get this script loaded, for debugging
endfunction
function! cargo#cmd(args)
execute "! cargo" a:args
endfunction
function! s:nearest_cargo(...) abort
" If the second argument is not specified, the first argument determines
" whether we will start from the current directory or the directory of the
" current buffer, otherwise, we start with the provided path on the
" second argument.
let l:is_getcwd = get(a:, 1, 0)
if l:is_getcwd
let l:starting_path = get(a:, 2, getcwd())
else
let l:starting_path = get(a:, 2, expand('%:p:h'))
endif
return findfile('Cargo.toml', l:starting_path . ';')
endfunction
function! cargo#nearestCargo(is_getcwd) abort
return s:nearest_cargo(a:is_getcwd)
endfunction
function! cargo#nearestWorkspaceCargo(is_getcwd) abort
let l:nearest = s:nearest_cargo(a:is_getcwd)
while l:nearest !=# ''
for l:line in readfile(l:nearest, '', 0x100)
if l:line =~# '\V[workspace]'
return l:nearest
endif
endfor
let l:next = fnamemodify(l:nearest, ':p:h:h')
let l:nearest = s:nearest_cargo(0, l:next)
endwhile
return ''
endfunction
function! cargo#nearestRootCargo(is_getcwd) abort
" Try to find a workspace Cargo.toml, and if not found, take the nearest
" regular Cargo.toml
let l:workspace_cargo = cargo#nearestWorkspaceCargo(a:is_getcwd)
if l:workspace_cargo !=# ''
return l:workspace_cargo
endif
return s:nearest_cargo(a:is_getcwd)
endfunction
function! cargo#build(args)
call cargo#cmd("build " . a:args)
endfunction
function! cargo#clean(args)
call cargo#cmd("clean " . a:args)
endfunction
function! cargo#doc(args)
call cargo#cmd("doc " . a:args)
endfunction
function! cargo#new(args)
call cargo#cmd("new " . a:args)
cd `=a:args`
endfunction
function! cargo#init(args)
call cargo#cmd("init " . a:args)
endfunction
function! cargo#run(args)
call cargo#cmd("run " . a:args)
endfunction
function! cargo#test(args)
call cargo#cmd("test " . a:args)
endfunction
function! cargo#bench(args)
call cargo#cmd("bench " . a:args)
endfunction
function! cargo#runtarget(args)
let l:filename = expand('%:p')
let l:read_manifest = system('cargo read-manifest')
let l:metadata = json_decode(l:read_manifest)
let l:targets = get(l:metadata, 'targets', [])
let l:did_run = 0
for l:target in l:targets
let l:src_path = get(l:target, 'src_path', '')
let l:kinds = get(l:target, 'kind', [])
let l:name = get(l:target, 'name', '')
if l:src_path == l:filename
if index(l:kinds, 'example') != -1
let l:did_run = 1
call cargo#run("--example " . shellescape(l:name) . " " . a:args)
return
elseif index(l:kinds, 'bin') != -1
let l:did_run = 1
call cargo#run("--bin " . shellescape(l:name) . " " . a:args)
return
endif
endif
endfor
if l:did_run != 1
call cargo#run(a:args)
return
endif
endfunction
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,26 +0,0 @@
function! cargo#quickfix#CmdPre() abort
if &filetype ==# 'rust' && get(b:, 'current_compiler', '') ==# 'cargo'
" Preserve the current directory, and 'lcd' to the nearest Cargo file.
let b:rust_compiler_cargo_qf_has_lcd = haslocaldir()
let b:rust_compiler_cargo_qf_prev_cd = getcwd()
let b:rust_compiler_cargo_qf_prev_cd_saved = 1
let l:nearest = fnamemodify(cargo#nearestRootCargo(0), ':h')
execute 'lchdir! '.l:nearest
else
let b:rust_compiler_cargo_qf_prev_cd_saved = 0
endif
endfunction
function! cargo#quickfix#CmdPost() abort
if exists("b:rust_compiler_cargo_qf_prev_cd_saved") && b:rust_compiler_cargo_qf_prev_cd_saved
" Restore the current directory.
if b:rust_compiler_cargo_qf_has_lcd
execute 'lchdir! '.b:rust_compiler_cargo_qf_prev_cd
else
execute 'chdir! '.b:rust_compiler_cargo_qf_prev_cd
endif
let b:rust_compiler_cargo_qf_prev_cd_saved = 0
endif
endfunction
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,546 +0,0 @@
" Author: Kevin Ballard
" Description: Helper functions for Rust commands/mappings
" Last Modified: May 27, 2014
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
function! rust#Load()
" Utility call to get this script loaded, for debugging
endfunction
function! rust#GetConfigVar(name, default)
" Local buffer variable with same name takes predeence over global
if has_key(b:, a:name)
return get(b:, a:name)
endif
if has_key(g:, a:name)
return get(g:, a:name)
endif
return a:default
endfunction
" Include expression {{{1
function! rust#IncludeExpr(fname) abort
" Remove leading 'crate::' to deal with 2018 edition style 'use'
" statements
let l:fname = substitute(a:fname, '^crate::', '', '')
" Remove trailing colons arising from lines like
"
" use foo::{Bar, Baz};
let l:fname = substitute(l:fname, ':\+$', '', '')
" Replace '::' with '/'
let l:fname = substitute(l:fname, '::', '/', 'g')
" When we have
"
" use foo::bar::baz;
"
" we can't tell whether baz is a module or a function; and we can't tell
" which modules correspond to files.
"
" So we work our way up, trying
"
" foo/bar/baz.rs
" foo/bar.rs
" foo.rs
while l:fname !=# '.'
let l:path = findfile(l:fname)
if !empty(l:path)
return l:fname
endif
let l:fname = fnamemodify(l:fname, ':h')
endwhile
return l:fname
endfunction
" Jump {{{1
function! rust#Jump(mode, function) range
let cnt = v:count1
normal! m'
if a:mode ==# 'v'
norm! gv
endif
let foldenable = &foldenable
set nofoldenable
while cnt > 0
execute "call <SID>Jump_" . a:function . "()"
let cnt = cnt - 1
endwhile
let &foldenable = foldenable
endfunction
function! s:Jump_Back()
call search('{', 'b')
keepjumps normal! w99[{
endfunction
function! s:Jump_Forward()
normal! j0
call search('{', 'b')
keepjumps normal! w99[{%
call search('{')
endfunction
" Run {{{1
function! rust#Run(bang, args)
let args = s:ShellTokenize(a:args)
if a:bang
let idx = index(l:args, '--')
if idx != -1
let rustc_args = idx == 0 ? [] : l:args[:idx-1]
let args = l:args[idx+1:]
else
let rustc_args = l:args
let args = []
endif
else
let rustc_args = []
endif
let b:rust_last_rustc_args = l:rustc_args
let b:rust_last_args = l:args
call s:WithPath(function("s:Run"), rustc_args, args)
endfunction
function! s:Run(dict, rustc_args, args)
let exepath = a:dict.tmpdir.'/'.fnamemodify(a:dict.path, ':t:r')
if has('win32')
let exepath .= '.exe'
endif
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
let rustc_args = [relpath, '-o', exepath] + a:rustc_args
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
let output = s:system(pwd, shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
if output !=# ''
echohl WarningMsg
echo output
echohl None
endif
if !v:shell_error
exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
endif
endfunction
" Expand {{{1
function! rust#Expand(bang, args)
let args = s:ShellTokenize(a:args)
if a:bang && !empty(l:args)
let pretty = remove(l:args, 0)
else
let pretty = "expanded"
endif
call s:WithPath(function("s:Expand"), pretty, args)
endfunction
function! s:Expand(dict, pretty, args)
try
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
if a:pretty =~? '^\%(everybody_loops$\|flowgraph=\)'
let flag = '--xpretty'
else
let flag = '--pretty'
endif
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
let args = [relpath, '-Z', 'unstable-options', l:flag, a:pretty] + a:args
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
if v:shell_error
echohl WarningMsg
echo output
echohl None
else
new
silent put =output
1
d
setl filetype=rust
setl buftype=nofile
setl bufhidden=hide
setl noswapfile
" give the buffer a nice name
let suffix = 1
let basename = fnamemodify(a:dict.path, ':t:r')
while 1
let bufname = basename
if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
let bufname .= '.pretty.rs'
if bufexists(bufname)
let suffix += 1
continue
endif
exe 'silent noautocmd keepalt file' fnameescape(bufname)
break
endwhile
endif
endtry
endfunction
function! rust#CompleteExpand(lead, line, pos)
if a:line[: a:pos-1] =~# '^RustExpand!\s*\S*$'
" first argument and it has a !
let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph=", "everybody_loops"]
if !empty(a:lead)
call filter(list, "v:val[:len(a:lead)-1] == a:lead")
endif
return list
endif
return glob(escape(a:lead, "*?[") . '*', 0, 1)
endfunction
" Emit {{{1
function! rust#Emit(type, args)
let args = s:ShellTokenize(a:args)
call s:WithPath(function("s:Emit"), a:type, args)
endfunction
function! s:Emit(dict, type, args)
try
let output_path = a:dict.tmpdir.'/output'
let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
let args = [relpath, '--emit', a:type, '-o', output_path] + a:args
let pwd = a:dict.istemp ? a:dict.tmpdir : ''
let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
if output !=# ''
echohl WarningMsg
echo output
echohl None
endif
if !v:shell_error
new
exe 'silent keepalt read' fnameescape(output_path)
1
d
if a:type ==# "llvm-ir"
setl filetype=llvm
let extension = 'll'
elseif a:type ==# "asm"
setl filetype=asm
let extension = 's'
endif
setl buftype=nofile
setl bufhidden=hide
setl noswapfile
if exists('l:extension')
" give the buffer a nice name
let suffix = 1
let basename = fnamemodify(a:dict.path, ':t:r')
while 1
let bufname = basename
if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
let bufname .= '.'.extension
if bufexists(bufname)
let suffix += 1
continue
endif
exe 'silent noautocmd keepalt file' fnameescape(bufname)
break
endwhile
endif
endif
endtry
endfunction
" Utility functions {{{1
" Invokes func(dict, ...)
" Where {dict} is a dictionary with the following keys:
" 'path' - The path to the file
" 'tmpdir' - The path to a temporary directory that will be deleted when the
" function returns.
" 'istemp' - 1 if the path is a file inside of {dict.tmpdir} or 0 otherwise.
" If {istemp} is 1 then an additional key is provided:
" 'tmpdir_relpath' - The {path} relative to the {tmpdir}.
"
" {dict.path} may be a path to a file inside of {dict.tmpdir} or it may be the
" existing path of the current buffer. If the path is inside of {dict.tmpdir}
" then it is guaranteed to have a '.rs' extension.
function! s:WithPath(func, ...)
let buf = bufnr('')
let saved = {}
let dict = {}
try
let saved.write = &write
set write
let dict.path = expand('%')
let pathisempty = empty(dict.path)
" Always create a tmpdir in case the wrapped command wants it
let dict.tmpdir = tempname()
call mkdir(dict.tmpdir)
if pathisempty || !saved.write
let dict.istemp = 1
" if we're doing this because of nowrite, preserve the filename
if !pathisempty
let filename = expand('%:t:r').".rs"
else
let filename = 'unnamed.rs'
endif
let dict.tmpdir_relpath = filename
let dict.path = dict.tmpdir.'/'.filename
let saved.mod = &modified
set nomodified
silent exe 'keepalt write! ' . fnameescape(dict.path)
if pathisempty
silent keepalt 0file
endif
else
let dict.istemp = 0
update
endif
call call(a:func, [dict] + a:000)
finally
if bufexists(buf)
for [opt, value] in items(saved)
silent call setbufvar(buf, '&'.opt, value)
unlet value " avoid variable type mismatches
endfor
endif
if has_key(dict, 'tmpdir') | silent call s:RmDir(dict.tmpdir) | endif
endtry
endfunction
function! rust#AppendCmdLine(text)
call setcmdpos(getcmdpos())
let cmd = getcmdline() . a:text
return cmd
endfunction
" Tokenize the string according to sh parsing rules
function! s:ShellTokenize(text)
" states:
" 0: start of word
" 1: unquoted
" 2: unquoted backslash
" 3: double-quote
" 4: double-quoted backslash
" 5: single-quote
let l:state = 0
let l:current = ''
let l:args = []
for c in split(a:text, '\zs')
if l:state == 0 || l:state == 1 " unquoted
if l:c ==# ' '
if l:state == 0 | continue | endif
call add(l:args, l:current)
let l:current = ''
let l:state = 0
elseif l:c ==# '\'
let l:state = 2
elseif l:c ==# '"'
let l:state = 3
elseif l:c ==# "'"
let l:state = 5
else
let l:current .= l:c
let l:state = 1
endif
elseif l:state == 2 " unquoted backslash
if l:c !=# "\n" " can it even be \n?
let l:current .= l:c
endif
let l:state = 1
elseif l:state == 3 " double-quote
if l:c ==# '\'
let l:state = 4
elseif l:c ==# '"'
let l:state = 1
else
let l:current .= l:c
endif
elseif l:state == 4 " double-quoted backslash
if stridx('$`"\', l:c) >= 0
let l:current .= l:c
elseif l:c ==# "\n" " is this even possible?
" skip it
else
let l:current .= '\'.l:c
endif
let l:state = 3
elseif l:state == 5 " single-quoted
if l:c ==# "'"
let l:state = 1
else
let l:current .= l:c
endif
endif
endfor
if l:state != 0
call add(l:args, l:current)
endif
return l:args
endfunction
function! s:RmDir(path)
" sanity check; make sure it's not empty, /, or $HOME
if empty(a:path)
echoerr 'Attempted to delete empty path'
return 0
elseif a:path ==# '/' || a:path ==# $HOME
echoerr 'Attempted to delete protected path: ' . a:path
return 0
endif
return system("rm -rf " . shellescape(a:path))
endfunction
" Executes {cmd} with the cwd set to {pwd}, without changing Vim's cwd.
" If {pwd} is the empty string then it doesn't change the cwd.
function! s:system(pwd, cmd)
let cmd = a:cmd
if !empty(a:pwd)
let cmd = 'cd ' . shellescape(a:pwd) . ' && ' . cmd
endif
return system(cmd)
endfunction
" Playpen Support {{{1
" Parts of gist.vim by Yasuhiro Matsumoto <mattn.jp@gmail.com> reused
" gist.vim available under the BSD license, available at
" http://github.com/mattn/gist-vim
function! s:has_webapi()
if !exists("*webapi#http#post")
try
call webapi#http#post()
catch
endtry
endif
return exists("*webapi#http#post")
endfunction
function! rust#Play(count, line1, line2, ...) abort
redraw
let l:rust_playpen_url = get(g:, 'rust_playpen_url', 'https://play.rust-lang.org/')
let l:rust_shortener_url = get(g:, 'rust_shortener_url', 'https://is.gd/')
if !s:has_webapi()
echohl ErrorMsg | echomsg ':RustPlay depends on webapi.vim (https://github.com/mattn/webapi-vim)' | echohl None
return
endif
let bufname = bufname('%')
if a:count < 1
let content = join(getline(a:line1, a:line2), "\n")
else
let save_regcont = @"
let save_regtype = getregtype('"')
silent! normal! gvy
let content = @"
call setreg('"', save_regcont, save_regtype)
endif
let url = l:rust_playpen_url."?code=".webapi#http#encodeURI(content)
if strlen(url) > 5000
echohl ErrorMsg | echomsg 'Buffer too large, max 5000 encoded characters ('.strlen(url).')' | echohl None
return
endif
let payload = "format=simple&url=".webapi#http#encodeURI(url)
let res = webapi#http#post(l:rust_shortener_url.'create.php', payload, {})
if res.status[0] ==# '2'
let url = res.content
endif
let footer = ''
if exists('g:rust_clip_command')
call system(g:rust_clip_command, url)
if !v:shell_error
let footer = ' (copied to clipboard)'
endif
endif
redraw | echomsg 'Done: '.url.footer
endfunction
" Run a test under the cursor or all tests {{{1
" Finds a test function name under the cursor. Returns empty string when a
" test function is not found.
function! s:SearchTestFunctionNameUnderCursor() abort
let cursor_line = line('.')
" Find #[test] attribute
if search('\m\C#\[test\]', 'bcW') is 0
return ''
endif
" Move to an opening brace of the test function
let test_func_line = search('\m\C^\s*fn\s\+\h\w*\s*(.\+{$', 'eW')
if test_func_line is 0
return ''
endif
" Search the end of test function (closing brace) to ensure that the
" cursor position is within function definition
normal! %
if line('.') < cursor_line
return ''
endif
return matchstr(getline(test_func_line), '\m\C^\s*fn\s\+\zs\h\w*')
endfunction
function! rust#Test(all, options) abort
let manifest = findfile('Cargo.toml', expand('%:p:h') . ';')
if manifest ==# ''
return rust#Run(1, '--test ' . a:options)
endif
if exists(':terminal')
let cmd = 'terminal '
else
let cmd = '!'
let manifest = shellescape(manifest)
endif
if a:all
if a:options ==# ''
execute cmd . 'cargo test --manifest-path' manifest
else
execute cmd . 'cargo test --manifest-path' manifest a:options
endif
return
endif
let saved = getpos('.')
try
let func_name = s:SearchTestFunctionNameUnderCursor()
if func_name ==# ''
echohl ErrorMsg
echo 'No test function was found under the cursor. Please add ! to command if you want to run all tests'
echohl None
return
endif
if a:options ==# ''
execute cmd . 'cargo test --manifest-path' manifest func_name
else
execute cmd . 'cargo test --manifest-path' manifest func_name a:options
endif
return
finally
call setpos('.', saved)
endtry
endfunction
" }}}1
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,101 +0,0 @@
" For debugging, inspired by https://github.com/w0rp/rust/blob/master/autoload/rust/debugging.vim
let s:global_variable_list = [
\ 'ftplugin_rust_source_path',
\ 'loaded_syntastic_rust_cargo_checker',
\ 'loaded_syntastic_rust_filetype',
\ 'loaded_syntastic_rust_rustc_checker',
\ 'rust_bang_comment_leader',
\ 'rust_cargo_avoid_whole_workspace',
\ 'rust_clip_command',
\ 'rust_conceal',
\ 'rust_conceal_mod_path',
\ 'rust_conceal_pub',
\ 'rust_fold',
\ 'rust_last_args',
\ 'rust_last_rustc_args',
\ 'rust_original_delimitMate_excluded_regions',
\ 'rust_playpen_url',
\ 'rust_prev_delimitMate_quotes',
\ 'rust_recent_nearest_cargo_tol',
\ 'rust_recent_root_cargo_toml',
\ 'rust_recommended_style',
\ 'rust_set_conceallevel',
\ 'rust_set_conceallevel=1',
\ 'rust_set_foldmethod',
\ 'rust_set_foldmethod=1',
\ 'rust_shortener_url',
\ 'rustc_makeprg_no_percent',
\ 'rustc_path',
\ 'rustfmt_autosave',
\ 'rustfmt_autosave_because_of_config',
\ 'rustfmt_autosave_if_config_present',
\ 'rustfmt_command',
\ 'rustfmt_emit_files',
\ 'rustfmt_fail_silently',
\ 'rustfmt_options',
\ 'syntastic_extra_filetypes',
\ 'syntastic_rust_cargo_fname',
\]
function! s:Echo(message) abort
execute 'echo a:message'
endfunction
function! s:EchoGlobalVariables() abort
for l:key in s:global_variable_list
call s:Echo('let g:' . l:key . ' = ' . string(get(g:, l:key, v:null)))
if has_key(b:, l:key)
call s:Echo('let b:' . l:key . ' = ' . string(b:[l:key]))
endif
endfor
endfunction
function! rust#debugging#Info() abort
call cargo#Load()
call rust#Load()
call rustfmt#Load()
call s:Echo('rust.vim Global Variables:')
call s:Echo('')
call s:EchoGlobalVariables()
silent let l:output = system(g:rustfmt_command . ' --version')
echo l:output
let l:rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
silent let l:output = system(l:rustc . ' --version')
echo l:output
silent let l:output = system('cargo --version')
echo l:output
version
if exists(":SyntasticInfo")
echo "----"
echo "Info from Syntastic:"
execute "SyntasticInfo"
endif
endfunction
function! rust#debugging#InfoToClipboard() abort
redir @"
silent call rust#debugging#Info()
redir END
call s:Echo('RustInfo copied to your clipboard')
endfunction
function! rust#debugging#InfoToFile(filename) abort
let l:expanded_filename = expand(a:filename)
redir => l:output
silent call rust#debugging#Info()
redir END
call writefile(split(l:output, "\n"), l:expanded_filename)
call s:Echo('RustInfo written to ' . l:expanded_filename)
endfunction
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,44 +0,0 @@
let s:delimitMate_extra_excluded_regions = ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
" For this buffer, when delimitMate issues the `User delimitMate_map`
" event in the autocommand system, add the above-defined extra excluded
" regions to delimitMate's state, if they have not already been added.
function! rust#delimitmate#onMap() abort
if &filetype !=# 'rust'
return
endif
if get(b:, "delimitMate_quotes")
let b:rust_prev_delimitMate_quotes = b:delimitMate_quotes
endif
let b:delimitMate_quotes = "\" `"
if match(delimitMate#Get("excluded_regions"),
\ s:delimitMate_extra_excluded_regions) == -1
call delimitMate#Set("excluded_regions",
\delimitMate#Get("excluded_regions").s:delimitMate_extra_excluded_regions)
endif
endfunction
" For this buffer, when delimitMate issues the `User delimitMate_unmap`
" event in the autocommand system, delete the above-defined extra excluded
" regions from delimitMate's state (the deletion being idempotent and
" having no effect if the extra excluded regions are not present in the
" targeted part of delimitMate's state).
function! rust#delimitmate#onUnmap() abort
if &filetype !=# 'rust'
return
endif
if get(b:, "rust_prev_delimitMate_quotes")
let b:delimitMate_quotes = b:rust_prev_delimitMate_quotes
endif
call delimitMate#Set("excluded_regions", substitute(
\ delimitMate#Get("excluded_regions"),
\ '\C\V' . s:delimitMate_extra_excluded_regions,
\ '', 'g'))
endfunction
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,257 +0,0 @@
" Author: Stephen Sugden <stephen@stephensugden.com>
"
" Adapted from https://github.com/fatih/vim-go
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if !exists("g:rustfmt_autosave")
let g:rustfmt_autosave = 0
endif
if !exists("g:rustfmt_command")
let g:rustfmt_command = "rustfmt"
endif
if !exists("g:rustfmt_options")
let g:rustfmt_options = ""
endif
if !exists("g:rustfmt_fail_silently")
let g:rustfmt_fail_silently = 0
endif
function! rustfmt#DetectVersion()
" Save rustfmt '--help' for feature inspection
silent let s:rustfmt_help = system(g:rustfmt_command . " --help")
let s:rustfmt_unstable_features = s:rustfmt_help =~# "--unstable-features"
" Build a comparable rustfmt version varible out of its `--version` output:
silent let l:rustfmt_version_full = system(g:rustfmt_command . " --version")
let l:rustfmt_version_list = matchlist(l:rustfmt_version_full,
\ '\vrustfmt ([0-9]+[.][0-9]+[.][0-9]+)')
if len(l:rustfmt_version_list) < 3
let s:rustfmt_version = "0"
else
let s:rustfmt_version = l:rustfmt_version_list[1]
endif
return s:rustfmt_version
endfunction
call rustfmt#DetectVersion()
if !exists("g:rustfmt_emit_files")
let g:rustfmt_emit_files = s:rustfmt_version >= "0.8.2"
endif
if !exists("g:rustfmt_file_lines")
let g:rustfmt_file_lines = s:rustfmt_help =~# "--file-lines JSON"
endif
let s:got_fmt_error = 0
function! rustfmt#Load()
" Utility call to get this script loaded, for debugging
endfunction
function! s:RustfmtWriteMode()
if g:rustfmt_emit_files
return "--emit=files"
else
return "--write-mode=overwrite"
endif
endfunction
function! s:RustfmtConfig()
let l:rustfmt_toml = findfile('rustfmt.toml', expand('%:p:h') . ';')
if l:rustfmt_toml !=# ''
return '--config-path '.l:rustfmt_toml
endif
let l:_rustfmt_toml = findfile('.rustfmt.toml', expand('%:p:h') . ';')
if l:_rustfmt_toml !=# ''
return '--config-path '.l:_rustfmt_toml
endif
return ''
endfunction
function! s:RustfmtCommandRange(filename, line1, line2)
if g:rustfmt_file_lines == 0
echo "--file-lines is not supported in the installed `rustfmt` executable"
return
endif
let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
let l:write_mode = s:RustfmtWriteMode()
let l:rustfmt_config = s:RustfmtConfig()
" FIXME: When --file-lines gets to be stable, add version range checking
" accordingly.
let l:unstable_features = s:rustfmt_unstable_features ? '--unstable-features' : ''
let l:cmd = printf("%s %s %s %s %s --file-lines '[%s]' %s", g:rustfmt_command,
\ l:write_mode, g:rustfmt_options,
\ l:unstable_features, l:rustfmt_config,
\ json_encode(l:arg), shellescape(a:filename))
return l:cmd
endfunction
function! s:RustfmtCommand()
if g:rustfmt_emit_files
let l:write_mode = "--emit=stdout"
else
let l:write_mode = "--write-mode=display"
endif
" rustfmt will pick on the right config on its own due to the
" current directory change.
return g:rustfmt_command . " ". l:write_mode . " " . g:rustfmt_options
endfunction
function! s:DeleteLines(start, end) abort
silent! execute a:start . ',' . a:end . 'delete _'
endfunction
function! s:RunRustfmt(command, tmpname, fail_silently)
mkview!
let l:stderr_tmpname = tempname()
call writefile([], l:stderr_tmpname)
let l:command = a:command . ' 2> ' . l:stderr_tmpname
if a:tmpname ==# ''
" Rustfmt in stdin/stdout mode
" chdir to the directory of the file
let l:has_lcd = haslocaldir()
let l:prev_cd = getcwd()
execute 'lchdir! '.expand('%:h')
let l:buffer = getline(1, '$')
if exists("*systemlist")
silent let out = systemlist(l:command, l:buffer)
else
silent let out = split(system(l:command,
\ join(l:buffer, "\n")), '\r\?\n')
endif
else
if exists("*systemlist")
silent let out = systemlist(l:command)
else
silent let out = split(system(l:command), '\r\?\n')
endif
endif
let l:stderr = readfile(l:stderr_tmpname)
call delete(l:stderr_tmpname)
let l:open_lwindow = 0
if v:shell_error == 0
" remove undo point caused via BufWritePre
try | silent undojoin | catch | endtry
if a:tmpname ==# ''
let l:content = l:out
else
" take the tmpfile's content, this is better than rename
" because it preserves file modes.
let l:content = readfile(a:tmpname)
endif
call s:DeleteLines(len(l:content), line('$'))
call setline(1, l:content)
" only clear location list if it was previously filled to prevent
" clobbering other additions
if s:got_fmt_error
let s:got_fmt_error = 0
call setloclist(0, [])
let l:open_lwindow = 1
endif
elseif g:rustfmt_fail_silently == 0 && a:fail_silently == 0
" otherwise get the errors and put them in the location list
let l:errors = []
let l:prev_line = ""
for l:line in l:stderr
" error: expected one of `;` or `as`, found `extern`
" --> src/main.rs:2:1
let tokens = matchlist(l:line, '^\s\+-->\s\(.\{-}\):\(\d\+\):\(\d\+\)$')
if !empty(tokens)
call add(l:errors, {"filename": @%,
\"lnum": tokens[2],
\"col": tokens[3],
\"text": l:prev_line})
endif
let l:prev_line = l:line
endfor
if !empty(l:errors)
call setloclist(0, l:errors, 'r')
echohl Error | echomsg "rustfmt returned error" | echohl None
else
echo "rust.vim: was not able to parse rustfmt messages. Here is the raw output:"
echo "\n"
for l:line in l:stderr
echo l:line
endfor
endif
let s:got_fmt_error = 1
let l:open_lwindow = 1
endif
" Restore the current directory if needed
if a:tmpname ==# ''
if l:has_lcd
execute 'lchdir! '.l:prev_cd
else
execute 'chdir! '.l:prev_cd
endif
endif
" Open lwindow after we have changed back to the previous directory
if l:open_lwindow == 1
lwindow
endif
silent! loadview
endfunction
function! rustfmt#FormatRange(line1, line2)
let l:tmpname = tempname()
call writefile(getline(1, '$'), l:tmpname)
let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2)
call s:RunRustfmt(command, l:tmpname, 0)
call delete(l:tmpname)
endfunction
function! rustfmt#Format()
call s:RunRustfmt(s:RustfmtCommand(), '', 0)
endfunction
function! rustfmt#Cmd()
" Mainly for debugging
return s:RustfmtCommand()
endfunction
function! rustfmt#PreWrite()
if !filereadable(expand("%@"))
return
endif
if rust#GetConfigVar('rustfmt_autosave_if_config_present', 0)
if findfile('rustfmt.toml', '.;') !=# '' || findfile('.rustfmt.toml', '.;') !=# ''
let b:rustfmt_autosave = 1
let b:rustfmt_autosave_because_of_config = 1
endif
endif
if !rust#GetConfigVar("rustfmt_autosave", 0)
return
endif
call s:RunRustfmt(s:RustfmtCommand(), '', 1)
endfunction
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,49 +0,0 @@
" Vim compiler file
" Compiler: Cargo Compiler
" Maintainer: Damien Radtke <damienradtke@gmail.com>
" Latest Revision: 2014 Sep 24
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if exists('current_compiler')
finish
endif
runtime compiler/rustc.vim
let current_compiler = "cargo"
" vint: -ProhibitAbbreviationOption
let s:save_cpo = &cpo
set cpo&vim
" vint: +ProhibitAbbreviationOption
if exists(':CompilerSet') != 2
command -nargs=* CompilerSet setlocal <args>
endif
if exists('g:cargo_makeprg_params')
execute 'CompilerSet makeprg=cargo\ '.escape(g:cargo_makeprg_params, ' \|"').'\ $*'
else
CompilerSet makeprg=cargo\ $*
endif
augroup RustCargoQuickFixHooks
autocmd!
autocmd QuickFixCmdPre make call cargo#quickfix#CmdPre()
autocmd QuickFixCmdPost make call cargo#quickfix#CmdPost()
augroup END
" Ignore general cargo progress messages
CompilerSet errorformat+=
\%-G%\\s%#Downloading%.%#,
\%-G%\\s%#Compiling%.%#,
\%-G%\\s%#Finished%.%#,
\%-G%\\s%#error:\ Could\ not\ compile\ %.%#,
\%-G%\\s%#To\ learn\ more\\,%.%#,
\%-Gnote:\ Run\ with\ \`RUST_BACKTRACE=%.%#,
\%.%#panicked\ at\ \\'%m\\'\\,\ %f:%l:%c
" vint: -ProhibitAbbreviationOption
let &cpo = s:save_cpo
unlet s:save_cpo
" vint: +ProhibitAbbreviationOption
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,53 +0,0 @@
" Vim compiler file
" Compiler: Rust Compiler
" Maintainer: Chris Morgan <me@chrismorgan.info>
" Latest Revision: 2013 Jul 12
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if exists("current_compiler")
finish
endif
let current_compiler = "rustc"
" vint: -ProhibitAbbreviationOption
let s:save_cpo = &cpo
set cpo&vim
" vint: +ProhibitAbbreviationOption
if exists(":CompilerSet") != 2
command -nargs=* CompilerSet setlocal <args>
endif
if get(g:, 'rustc_makeprg_no_percent', 0)
CompilerSet makeprg=rustc
else
CompilerSet makeprg=rustc\ \%
endif
" New errorformat (after nightly 2016/08/10)
CompilerSet errorformat=
\%-G,
\%-Gerror:\ aborting\ %.%#,
\%-Gerror:\ Could\ not\ compile\ %.%#,
\%Eerror:\ %m,
\%Eerror[E%n]:\ %m,
\%Wwarning:\ %m,
\%Inote:\ %m,
\%C\ %#-->\ %f:%l:%c,
\%E\ \ left:%m,%C\ right:%m\ %f:%l:%c,%Z
" Old errorformat (before nightly 2016/08/10)
CompilerSet errorformat+=
\%f:%l:%c:\ %t%*[^:]:\ %m,
\%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m,
\%-G%f:%l\ %s,
\%-G%*[\ ]^,
\%-G%*[\ ]^%*[~],
\%-G%*[\ ]...
" vint: -ProhibitAbbreviationOption
let &cpo = s:save_cpo
unlet s:save_cpo
" vint: +ProhibitAbbreviationOption
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,11 +0,0 @@
--langdef=Rust
--langmap=Rust:.rs
--regex-Rust=/^[ \t]*(#\[[^\]]\][ \t]*)*(pub[ \t]+)?(extern[ \t]+)?("[^"]+"[ \t]+)?(unsafe[ \t]+)?fn[ \t]+([a-zA-Z0-9_]+)/\6/f,functions,function definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?type[ \t]+([a-zA-Z0-9_]+)/\2/T,types,type definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?enum[ \t]+([a-zA-Z0-9_]+)/\2/g,enum,enumeration names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?struct[ \t]+([a-zA-Z0-9_]+)/\2/s,structure names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?mod[ \t]+([a-zA-Z0-9_]+)/\2/m,modules,module names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?(static|const)[ \t]+([a-zA-Z0-9_]+)/\3/c,consts,static constants/
--regex-Rust=/^[ \t]*(pub[ \t]+)?trait[ \t]+([a-zA-Z0-9_]+)/\2/t,traits,traits/
--regex-Rust=/^[ \t]*(pub[ \t]+)?impl([ \t\n]*<[^>]*>)?[ \t]+(([a-zA-Z0-9_:]+)[ \t]*(<[^>]*>)?[ \t]+(for)[ \t]+)?([a-zA-Z0-9_]+)/\4 \6 \7/i,impls,trait implementations/
--regex-Rust=/^[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/d,macros,macro definitions/

View file

@ -1,463 +0,0 @@
*ft_rust.txt* Filetype plugin for Rust
==============================================================================
CONTENTS *rust*
1. Introduction |rust-intro|
2. Settings |rust-settings|
3. Commands |rust-commands|
4. Mappings |rust-mappings|
==============================================================================
INTRODUCTION *rust-intro*
This plugin provides syntax and supporting functionality for the Rust
filetype. It requires Vim 8 or higher for full functionality. Some commands
will not work on earlier versions.
==============================================================================
SETTINGS *rust-settings*
This plugin has a few variables you can define in your vimrc that change the
behavior of the plugin.
Some variables can be set buffer local (`:b` prefix), and the buffer local
will take precedence over the global `g:` counterpart.
*g:rustc_path*
g:rustc_path~
Set this option to the path to rustc for use in the |:RustRun| and
|:RustExpand| commands. If unset, "rustc" will be located in $PATH: >
let g:rustc_path = $HOME."/bin/rustc"
<
*g:rustc_makeprg_no_percent*
g:rustc_makeprg_no_percent~
Set this option to 1 to have 'makeprg' default to "rustc" instead of
"rustc %": >
let g:rustc_makeprg_no_percent = 1
<
*g:rust_conceal*
g:rust_conceal~
Set this option to turn on the basic |conceal| support: >
let g:rust_conceal = 1
<
*g:rust_conceal_mod_path*
g:rust_conceal_mod_path~
Set this option to turn on |conceal| for the path connecting token
"::": >
let g:rust_conceal_mod_path = 1
<
*g:rust_conceal_pub*
g:rust_conceal_pub~
Set this option to turn on |conceal| for the "pub" token: >
let g:rust_conceal_pub = 1
<
*g:rust_recommended_style*
g:rust_recommended_style~
Set this option to enable vim indentation and textwidth settings to
conform to style conventions of the rust standard library (i.e. use 4
spaces for indents and sets 'textwidth' to 99). This option is enabled
by default. To disable it: >
let g:rust_recommended_style = 0
<
*g:rust_fold*
g:rust_fold~
Set this option to turn on |folding|: >
let g:rust_fold = 1
<
Value Effect ~
0 No folding
1 Braced blocks are folded. All folds are open by
default.
2 Braced blocks are folded. 'foldlevel' is left at the
global value (all folds are closed by default).
*g:rust_bang_comment_leader*
g:rust_bang_comment_leader~
Set this option to 1 to preserve the leader on multi-line doc comments
using the /*! syntax: >
let g:rust_bang_comment_leader = 1
<
*g:rust_use_custom_ctags_defs*
g:rust_use_custom_ctags_defs~
Set this option to 1 if you have customized ctags definitions for Rust
and do not wish for those included with rust.vim to be used: >
let g:rust_use_custom_ctags_defs = 1
<
Note that rust.vim's built-in definitions are only used for the Tagbar
Vim plugin, if you have it installed--it is not automatically used
when generating |tags| files that Vim can use to navigate to
definitions across different source files. Feel free to copy
`rust.vim/ctags/rust.ctags` into your own `~/.ctags` if you wish to
generate |tags| files.
*g:ftplugin_rust_source_path*
g:ftplugin_rust_source_path~
Set this option to a path that should be prepended to 'path' for Rust
source files: >
let g:ftplugin_rust_source_path = $HOME.'/dev/rust'
<
*g:rustfmt_command*
g:rustfmt_command~
Set this option to the name of the 'rustfmt' executable in your $PATH. If
not specified it defaults to 'rustfmt' : >
let g:rustfmt_command = 'rustfmt'
<
*g:rustfmt_autosave*
g:rustfmt_autosave~
Set this option to 1 to run |:RustFmt| automatically when saving a
buffer. If not specified it defaults to 0 : >
let g:rustfmt_autosave = 0
<
There is also a buffer-local b:rustfmt_autosave that can be set for
the same purpose, and can override the global setting.
*g:rustfmt_autosave_if_config_present*
g:rustfmt_autosave_if_config_present~
Set this option to 1 to to have *b:rustfmt_autosave* be set automatically
if a `rustfmt.toml` file is present in any parent directly leading to
the file being edited. If not set, default to 0: >
let g:rustfmt_autosave_if_config_present = 0
<
This is useful to have `rustfmt` only execute on save, on projects
that have `rustfmt.toml` configuration.
There is also a buffer-local b:rustfmt_autosave_if_config_present
that can be set for the same purpose, which can overrides the global
setting.
*g:rustfmt_fail_silently*
g:rustfmt_fail_silently~
Set this option to 1 to prevent 'rustfmt' from populating the
|location-list| with errors. If not specified it defaults to 0: >
let g:rustfmt_fail_silently = 0
<
*g:rustfmt_options*
g:rustfmt_options~
Set this option to a string of options to pass to 'rustfmt'. The
write-mode is already set to 'overwrite'. If not specified it
defaults to '' : >
let g:rustfmt_options = ''
<
*g:rustfmt_emit_files*
g:rustfmt_emit_files~
If not specified rust.vim tries to detect the right parameter to
pass to rustfmt based on its reported version. Otherwise, it
determines whether to run rustfmt with '--emit=files' (when 1 is
provided) instead of '--write-mode=overwrite'. >
let g:rustfmt_emit_files = 0
*g:rust_playpen_url*
g:rust_playpen_url~
Set this option to override the url for the playpen to use: >
let g:rust_playpen_url = 'https://play.rust-lang.org/'
<
*g:rust_shortener_url*
g:rust_shortener_url~
Set this option to override the url for the url shortener: >
let g:rust_shortener_url = 'https://is.gd/'
<
*g:rust_clip_command*
g:rust_clip_command~
Set this option to the command used in your OS to copy the Rust Play
url to the clipboard: >
let g:rust_clip_command = 'xclip -selection clipboard'
<
*g:cargo_makeprg_params*
g:cargo_makeprg_params~
Set this option to the string of parameters to pass to cargo. If not
specified it defaults to '$*' : >
let g:cargo_makeprg_params = 'build'
<
Integration with Syntastic *rust-syntastic*
--------------------------
This plugin automatically integrates with the Syntastic checker. There are two
checkers provided: 'rustc', and 'cargo'. The later invokes 'Cargo' in order to
build code, and the former delivers a single edited '.rs' file as a compilation
target directly to the Rust compiler, `rustc`.
Because Cargo is almost exclusively being used for building Rust code these
days, 'cargo' is the default checker. >
let g:syntastic_rust_checkers = ['cargo']
<
If you would like to change it, you can set `g:syntastic_rust_checkers` to a
different value.
*g:rust_cargo_avoid_whole_workspace*
*b:rust_cargo_avoid_whole_workspace*
g:rust_cargo_avoid_whole_workspace~
When editing a crate that is part of a Cargo workspace, and this
option is set to 1 (the default), then 'cargo' will be executed
directly in that crate directory instead of in the workspace
directory. Setting 0 prevents this behavior - however be aware that if
you are working in large workspace, Cargo commands may take more time,
plus the Syntastic error list may include all the crates in the
workspace. >
let g:rust_cargo_avoid_whole_workspace = 0
<
*g:rust_cargo_check_all_targets*
*b:rust_cargo_check_all_targets*
g:rust_cargo_check_all_targets~
When set to 1, the `--all-targets` option will be passed to cargo when
Syntastic executes it, allowing the linting of all targets under the
package.
The default is 0.
*g:rust_cargo_check_all_features*
*b:rust_cargo_check_all_features*
g:rust_cargo_check_all_features~
When set to 1, the `--all-features` option will be passed to cargo when
Syntastic executes it, allowing the linting of all features of the
package.
The default is 0.
*g:rust_cargo_check_examples*
*b:rust_cargo_check_examples*
g:rust_cargo_check_examples~
When set to 1, the `--examples` option will be passed to cargo when
Syntastic executes it, to prevent the exclusion of examples from
linting. The examples are normally under the `examples/` directory of
the crate.
The default is 0.
*g:rust_cargo_check_tests*
*b:rust_cargo_check_tests*
g:rust_cargo_check_tests~
When set to 1, the `--tests` option will be passed to cargo when
Syntastic executes it, to prevent the exclusion of tests from linting.
The tests are normally under the `tests/` directory of the crate.
The default is 0.
*g:rust_cargo_check_benches*
*b:rust_cargo_check_benches*
g:rust_cargo_check_benches~
When set to 1, the `--benches` option will be passed to cargo when
Syntastic executes it. The benches are normally under the `benches/`
directory of the crate.
The default is 0.
Integration with auto-pairs *rust-auto-pairs*
---------------------------
This plugin automatically configures the auto-pairs plugin not to duplicate
single quotes, which are used more often for lifetime annotations than for
single character literals.
*g:rust_keep_autopairs_default*
g:rust_keep_autopairs_default~
Don't override auto-pairs default for the Rust filetype. The default
is 0.
==============================================================================
COMMANDS *rust-commands*
Invoking Cargo
--------------
This plug defines very simple shortcuts for invoking Cargo from with Vim.
:Cargo <args> *:Cargo*
Runs 'cargo' with the provided arguments.
:Cbuild <args> *:Cbuild*
Shortcut for 'cargo build`.
:Cclean <args> *:Cclean*
Shortcut for 'cargo clean`.
:Cdoc <args> *:Cdoc*
Shortcut for 'cargo doc`.
:Cinit <args> *:Cinit*
Shortcut for 'cargo init`.
:Crun <args> *:Crun*
Shortcut for 'cargo run`.
:Ctest <args> *:Ctest*
Shortcut for 'cargo test`.
:Cupdate <args> *:Cupdate*
Shortcut for 'cargo update`.
:Cbench <args> *:Cbench*
Shortcut for 'cargo bench`.
:Csearch <args> *:Csearch*
Shortcut for 'cargo search`.
:Cpublish <args> *:Cpublish*
Shortcut for 'cargo publish`.
:Cinstall <args> *:Cinstall*
Shortcut for 'cargo install`.
:Cruntarget <args> *:Cruntarget*
Shortcut for 'cargo run --bin' or 'cargo run --example',
depending on the currently open buffer.
Formatting
----------
:RustFmt *:RustFmt*
Runs |g:rustfmt_command| on the current buffer. If
|g:rustfmt_options| is set then those will be passed to the
executable.
If |g:rustfmt_fail_silently| is 0 (the default) then it
will populate the |location-list| with the errors from
|g:rustfmt_command|. If |g:rustfmt_fail_silently| is set to 1
then it will not populate the |location-list|.
:RustFmtRange *:RustFmtRange*
Runs |g:rustfmt_command| with selected range. See
|:RustFmt| for any other information.
Playpen integration
-------------------
:RustPlay *:RustPlay*
This command will only work if you have web-api.vim installed
(available at https://github.com/mattn/webapi-vim). It sends the
current selection, or if nothing is selected, the entirety of the
current buffer to the Rust playpen, and emits a message with the
shortened URL to the playpen.
|g:rust_playpen_url| is the base URL to the playpen, by default
"https://play.rust-lang.org/".
|g:rust_shortener_url| is the base url for the shorterner, by
default "https://is.gd/"
|g:rust_clip_command| is the command to run to copy the
playpen url to the clipboard of your system.
Evaulation of a single Rust file
--------------------------------
NOTE: These commands are useful only when working with standalone Rust files,
which is usually not the case for common Rust development. If you wish to
building Rust crates from with Vim can should use Vim's make, Syntastic, or
functionality from other plugins.
:RustRun [args] *:RustRun*
:RustRun! [rustc-args] [--] [args]
Compiles and runs the current file. If it has unsaved changes,
it will be saved first using |:update|. If the current file is
an unnamed buffer, it will be written to a temporary file
first. The compiled binary is always placed in a temporary
directory, but is run from the current directory.
The arguments given to |:RustRun| will be passed to the
compiled binary.
If ! is specified, the arguments are passed to rustc instead.
A "--" argument will separate the rustc arguments from the
arguments passed to the binary.
If |g:rustc_path| is defined, it is used as the path to rustc.
Otherwise it is assumed rustc can be found in $PATH.
:RustExpand [args] *:RustExpand*
:RustExpand! [TYPE] [args]
Expands the current file using --pretty and displays the
results in a new split. If the current file has unsaved
changes, it will be saved first using |:update|. If the
current file is an unnamed buffer, it will be written to a
temporary file first.
The arguments given to |:RustExpand| will be passed to rustc.
This is largely intended for specifying various --cfg
configurations.
If ! is specified, the first argument is the expansion type to
pass to rustc --pretty. Otherwise it will default to
"expanded".
If |g:rustc_path| is defined, it is used as the path to rustc.
Otherwise it is assumed rustc can be found in $PATH.
:RustEmitIr [args] *:RustEmitIr*
Compiles the current file to LLVM IR and displays the results
in a new split. If the current file has unsaved changes, it
will be saved first using |:update|. If the current file is an
unnamed buffer, it will be written to a temporary file first.
The arguments given to |:RustEmitIr| will be passed to rustc.
If |g:rustc_path| is defined, it is used as the path to rustc.
Otherwise it is assumed rustc can be found in $PATH.
:RustEmitAsm [args] *:RustEmitAsm*
Compiles the current file to assembly and displays the results
in a new split. If the current file has unsaved changes, it
will be saved first using |:update|. If the current file is an
unnamed buffer, it will be written to a temporary file first.
The arguments given to |:RustEmitAsm| will be passed to rustc.
If |g:rustc_path| is defined, it is used as the path to rustc.
Otherwise it is assumed rustc can be found in $PATH.
Running test(s)
---------------
:RustTest[!] [options] *:RustTest*
Runs a test under the cursor when the current buffer is in a
cargo project with "cargo test" command. If the command did
not find any test function under the cursor, it stops with an
error message.
When ! is given, runs all tests regardless of current cursor
position.
When [options] is given, it is passed to "cargo" command
arguments.
When the current buffer is outside cargo project, the command
runs "rustc --test" command instead of "cargo test" as
fallback. All tests are run regardless of adding ! since there
is no way to run specific test function with rustc. [options]
is passed to "rustc" command arguments in the case.
rust.vim Debugging
------------------
:RustInfo *:RustInfo*
Emits debugging info of the Vim Rust plugin.
:RustInfoToClipboard *:RustInfoClipboard*
Saves debugging info of the Vim Rust plugin to the default
register.
:RustInfoToFile [filename] *:RustInfoToFile*
Saves debugging info of the Vim Rust plugin to the the given
file, overwritting it.
==============================================================================
MAPPINGS *rust-mappings*
This plugin defines mappings for |[[| and |]]| to support hanging indents.
==============================================================================
vim:tw=78:sw=4:noet:ts=8:ft=help:norl:

View file

@ -1,12 +0,0 @@
" vint: -ProhibitAutocmdWithNoGroup
autocmd BufRead,BufNewFile *.rs call s:set_rust_filetype()
autocmd BufRead,BufNewFile Cargo.toml setf FALLBACK cfg
function! s:set_rust_filetype() abort
if &filetype !=# 'rust'
set filetype=rust
endif
endfunction
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,201 +0,0 @@
" Language: Rust
" Description: Vim ftplugin for Rust
" Maintainer: Chris Morgan <me@chrismorgan.info>
" Maintainer: Kevin Ballard <kevin@sb.org>
" Last Change: June 08, 2016
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
" vint: -ProhibitAbbreviationOption
let s:save_cpo = &cpo
set cpo&vim
" vint: +ProhibitAbbreviationOption
if get(b:, 'current_compiler', '') ==# ''
if strlen(findfile('Cargo.toml', '.;')) > 0
compiler cargo
else
compiler rustc
endif
endif
" Variables {{{1
" The rust source code at present seems to typically omit a leader on /*!
" comments, so we'll use that as our default, but make it easy to switch.
" This does not affect indentation at all (I tested it with and without
" leader), merely whether a leader is inserted by default or not.
if get(g:, 'rust_bang_comment_leader', 0)
" Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why,
" but without it, */ gets indented one space even if there were no
" leaders. I'm fairly sure that's a Vim bug.
setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,://
else
setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
endif
setlocal commentstring=//%s
setlocal formatoptions-=t formatoptions+=croqnl
" j was only added in 7.3.541, so stop complaints about its nonexistence
silent! setlocal formatoptions+=j
" smartindent will be overridden by indentexpr if filetype indent is on, but
" otherwise it's better than nothing.
setlocal smartindent nocindent
if get(g:, 'rust_recommended_style', 1)
let b:rust_set_style = 1
setlocal tabstop=8 shiftwidth=4 softtabstop=4 expandtab
setlocal textwidth=99
endif
setlocal include=\\v^\\s*(pub\\s+)?use\\s+\\zs(\\f\|:)+
setlocal includeexpr=rust#IncludeExpr(v:fname)
setlocal suffixesadd=.rs
if exists("g:ftplugin_rust_source_path")
let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
endif
if exists("g:loaded_delimitMate")
if exists("b:delimitMate_excluded_regions")
let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
endif
augroup rust.vim.DelimitMate
autocmd!
autocmd User delimitMate_map :call rust#delimitmate#onMap()
autocmd User delimitMate_unmap :call rust#delimitmate#onUnmap()
augroup END
endif
" Integration with auto-pairs (https://github.com/jiangmiao/auto-pairs)
if exists("g:AutoPairsLoaded") && !get(g:, 'rust_keep_autopairs_default', 0)
let b:AutoPairs = {'(':')', '[':']', '{':'}','"':'"', '`':'`'}
endif
if has("folding") && get(g:, 'rust_fold', 0)
let b:rust_set_foldmethod=1
setlocal foldmethod=syntax
if g:rust_fold == 2
setlocal foldlevel<
else
setlocal foldlevel=99
endif
endif
if has('conceal') && get(g:, 'rust_conceal', 0)
let b:rust_set_conceallevel=1
setlocal conceallevel=2
endif
" Motion Commands {{{1
" Bind motion commands to support hanging indents
nnoremap <silent> <buffer> [[ :call rust#Jump('n', 'Back')<CR>
nnoremap <silent> <buffer> ]] :call rust#Jump('n', 'Forward')<CR>
xnoremap <silent> <buffer> [[ :call rust#Jump('v', 'Back')<CR>
xnoremap <silent> <buffer> ]] :call rust#Jump('v', 'Forward')<CR>
onoremap <silent> <buffer> [[ :call rust#Jump('o', 'Back')<CR>
onoremap <silent> <buffer> ]] :call rust#Jump('o', 'Forward')<CR>
" Commands {{{1
" See |:RustRun| for docs
command! -nargs=* -complete=file -bang -buffer RustRun call rust#Run(<bang>0, <q-args>)
" See |:RustExpand| for docs
command! -nargs=* -complete=customlist,rust#CompleteExpand -bang -buffer RustExpand call rust#Expand(<bang>0, <q-args>)
" See |:RustEmitIr| for docs
command! -nargs=* -buffer RustEmitIr call rust#Emit("llvm-ir", <q-args>)
" See |:RustEmitAsm| for docs
command! -nargs=* -buffer RustEmitAsm call rust#Emit("asm", <q-args>)
" See |:RustPlay| for docs
command! -range=% RustPlay :call rust#Play(<count>, <line1>, <line2>, <f-args>)
" See |:RustFmt| for docs
command! -buffer RustFmt call rustfmt#Format()
" See |:RustFmtRange| for docs
command! -range -buffer RustFmtRange call rustfmt#FormatRange(<line1>, <line2>)
" See |:RustInfo| for docs
command! -bar RustInfo call rust#debugging#Info()
" See |:RustInfoToClipboard| for docs
command! -bar RustInfoToClipboard call rust#debugging#InfoToClipboard()
" See |:RustInfoToFile| for docs
command! -bar -nargs=1 RustInfoToFile call rust#debugging#InfoToFile(<f-args>)
" See |:RustTest| for docs
command! -buffer -nargs=* -bang RustTest call rust#Test(<bang>0, <q-args>)
if !exists("b:rust_last_rustc_args") || !exists("b:rust_last_args")
let b:rust_last_rustc_args = []
let b:rust_last_args = []
endif
" Cleanup {{{1
let b:undo_ftplugin = "
\ setlocal formatoptions< comments< commentstring< include< includeexpr< suffixesadd<
\|if exists('b:rust_set_style')
\|setlocal tabstop< shiftwidth< softtabstop< expandtab< textwidth<
\|endif
\|if exists('b:rust_original_delimitMate_excluded_regions')
\|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
\|unlet b:rust_original_delimitMate_excluded_regions
\|else
\|unlet! b:delimitMate_excluded_regions
\|endif
\|if exists('b:rust_set_foldmethod')
\|setlocal foldmethod< foldlevel<
\|unlet b:rust_set_foldmethod
\|endif
\|if exists('b:rust_set_conceallevel')
\|setlocal conceallevel<
\|unlet b:rust_set_conceallevel
\|endif
\|unlet! b:rust_last_rustc_args b:rust_last_args
\|delcommand RustRun
\|delcommand RustExpand
\|delcommand RustEmitIr
\|delcommand RustEmitAsm
\|delcommand RustPlay
\|nunmap <buffer> [[
\|nunmap <buffer> ]]
\|xunmap <buffer> [[
\|xunmap <buffer> ]]
\|ounmap <buffer> [[
\|ounmap <buffer> ]]
\|setlocal matchpairs-=<:>
\|unlet b:match_skip
\"
" }}}1
" Code formatting on save
augroup rust.vim.PreWrite
autocmd!
autocmd BufWritePre *.rs silent! call rustfmt#PreWrite()
augroup END
setlocal matchpairs+=<:>
" For matchit.vim (rustArrow stops `Fn() -> X` messing things up)
let b:match_skip = 's:comment\|string\|rustArrow'
" vint: -ProhibitAbbreviationOption
let &cpo = s:save_cpo
unlet s:save_cpo
" vint: +ProhibitAbbreviationOption
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,40 +0,0 @@
"
" Support for Tagbar -- https://github.com/majutsushi/tagbar
"
if !exists(':Tagbar')
finish
endif
" vint: -ProhibitAbbreviationOption
let s:save_cpo = &cpo
set cpo&vim
" vint: +ProhibitAbbreviationOption
if !exists('g:tagbar_type_rust')
let g:tagbar_type_rust = {
\ 'ctagstype' : 'rust',
\ 'kinds' : [
\'T:types',
\'f:functions',
\'g:enumerations',
\'s:structures',
\'m:modules',
\'c:constants',
\'t:traits',
\'i:trait implementations',
\ ]
\ }
endif
" In case you've updated/customized your ~/.ctags and prefer to use it.
if !get(g:, 'rust_use_custom_ctags_defs', 0)
let g:tagbar_type_rust.deffile = expand('<sfile>:p:h:h:h') . '/ctags/rust.ctags'
endif
" vint: -ProhibitAbbreviationOption
let &cpo = s:save_cpo
unlet s:save_cpo
" vint: +ProhibitAbbreviationOption
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,219 +0,0 @@
" Vim indent file
" Language: Rust
" Author: Chris Morgan <me@chrismorgan.info>
" Last Change: 2018 Jan 10
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
setlocal cindent
setlocal cinoptions=L0,(0,Ws,J1,j1,m1
setlocal cinkeys=0{,0},!^F,o,O,0[,0]
" Don't think cinwords will actually do anything at all... never mind
setlocal cinwords=for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern,macro
" Some preliminary settings
setlocal nolisp " Make sure lisp indenting doesn't supersede us
setlocal autoindent " indentexpr isn't much help otherwise
" Also do indentkeys, otherwise # gets shoved to column 0 :-/
setlocal indentkeys=0{,0},!^F,o,O,0[,0]
setlocal indentexpr=GetRustIndent(v:lnum)
" Only define the function once.
if exists("*GetRustIndent")
finish
endif
" vint: -ProhibitAbbreviationOption
let s:save_cpo = &cpo
set cpo&vim
" vint: +ProhibitAbbreviationOption
" Come here when loading the script the first time.
function! s:get_line_trimmed(lnum)
" Get the line and remove a trailing comment.
" Use syntax highlighting attributes when possible.
" NOTE: this is not accurate; /* */ or a line continuation could trick it
let line = getline(a:lnum)
let line_len = strlen(line)
if has('syntax_items')
" If the last character in the line is a comment, do a binary search for
" the start of the comment. synID() is slow, a linear search would take
" too long on a long line.
if synIDattr(synID(a:lnum, line_len, 1), "name") =~? 'Comment\|Todo'
let min = 1
let max = line_len
while min < max
let col = (min + max) / 2
if synIDattr(synID(a:lnum, col, 1), "name") =~? 'Comment\|Todo'
let max = col
else
let min = col + 1
endif
endwhile
let line = strpart(line, 0, min - 1)
endif
return substitute(line, "\s*$", "", "")
else
" Sorry, this is not complete, nor fully correct (e.g. string "//").
" Such is life.
return substitute(line, "\s*//.*$", "", "")
endif
endfunction
function! s:is_string_comment(lnum, col)
if has('syntax_items')
for id in synstack(a:lnum, a:col)
let synname = synIDattr(id, "name")
if synname ==# "rustString" || synname =~# "^rustComment"
return 1
endif
endfor
else
" without syntax, let's not even try
return 0
endif
endfunction
function GetRustIndent(lnum)
" Starting assumption: cindent (called at the end) will do it right
" normally. We just want to fix up a few cases.
let line = getline(a:lnum)
if has('syntax_items')
let synname = synIDattr(synID(a:lnum, 1, 1), "name")
if synname ==# "rustString"
" If the start of the line is in a string, don't change the indent
return -1
elseif synname =~? '\(Comment\|Todo\)'
\ && line !~# '^\s*/\*' " not /* opening line
if synname =~? "CommentML" " multi-line
if line !~# '^\s*\*' && getline(a:lnum - 1) =~# '^\s*/\*'
" This is (hopefully) the line after a /*, and it has no
" leader, so the correct indentation is that of the
" previous line.
return GetRustIndent(a:lnum - 1)
endif
endif
" If it's in a comment, let cindent take care of it now. This is
" for cases like "/*" where the next line should start " * ", not
" "* " as the code below would otherwise cause for module scope
" Fun fact: " /*\n*\n*/" takes two calls to get right!
return cindent(a:lnum)
endif
endif
" cindent gets second and subsequent match patterns/struct members wrong,
" as it treats the comma as indicating an unfinished statement::
"
" match a {
" b => c,
" d => e,
" f => g,
" };
" Search backwards for the previous non-empty line.
let prevlinenum = prevnonblank(a:lnum - 1)
let prevline = s:get_line_trimmed(prevlinenum)
while prevlinenum > 1 && prevline !~# '[^[:blank:]]'
let prevlinenum = prevnonblank(prevlinenum - 1)
let prevline = s:get_line_trimmed(prevlinenum)
endwhile
" Handle where clauses nicely: subsequent values should line up nicely.
if prevline[len(prevline) - 1] ==# ","
\ && prevline =~# '^\s*where\s'
return indent(prevlinenum) + 6
endif
if prevline[len(prevline) - 1] ==# ","
\ && s:get_line_trimmed(a:lnum) !~# '^\s*[\[\]{}]'
\ && prevline !~# '^\s*fn\s'
\ && prevline !~# '([^()]\+,$'
\ && s:get_line_trimmed(a:lnum) !~# '^\s*\S\+\s*=>'
" Oh ho! The previous line ended in a comma! I bet cindent will try to
" take this too far... For now, let's normally use the previous line's
" indent.
" One case where this doesn't work out is where *this* line contains
" square or curly brackets; then we normally *do* want to be indenting
" further.
"
" Another case where we don't want to is one like a function
" definition with arguments spread over multiple lines:
"
" fn foo(baz: Baz,
" baz: Baz) // <-- cindent gets this right by itself
"
" Another case is similar to the previous, except calling a function
" instead of defining it, or any conditional expression that leaves
" an open paren:
"
" foo(baz,
" baz);
"
" if baz && (foo ||
" bar) {
"
" Another case is when the current line is a new match arm.
"
" There are probably other cases where we don't want to do this as
" well. Add them as needed.
return indent(prevlinenum)
endif
if !has("patch-7.4.355")
" cindent before 7.4.355 doesn't do the module scope well at all; e.g.::
"
" static FOO : &'static [bool] = [
" true,
" false,
" false,
" true,
" ];
"
" uh oh, next statement is indented further!
" Note that this does *not* apply the line continuation pattern properly;
" that's too hard to do correctly for my liking at present, so I'll just
" start with these two main cases (square brackets and not returning to
" column zero)
call cursor(a:lnum, 1)
if searchpair('{\|(', '', '}\|)', 'nbW',
\ 's:is_string_comment(line("."), col("."))') == 0
if searchpair('\[', '', '\]', 'nbW',
\ 's:is_string_comment(line("."), col("."))') == 0
" Global scope, should be zero
return 0
else
" At the module scope, inside square brackets only
"if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum
if line =~# "^\\s*]"
" It's the closing line, dedent it
return 0
else
return &shiftwidth
endif
endif
endif
endif
" Fall back on cindent, which does it mostly right
return cindent(a:lnum)
endfunction
" vint: -ProhibitAbbreviationOption
let &cpo = s:save_cpo
unlet s:save_cpo
" vint: +ProhibitAbbreviationOption
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,26 +0,0 @@
if exists('g:loaded_rust_vim_plugin_cargo')
finish
endif
let g:loaded_rust_vim_plugin_cargo = 1
let s:save_cpo = &cpoptions
set cpoptions&vim
command! -nargs=+ Cargo call cargo#cmd(<q-args>)
command! -nargs=* Cbuild call cargo#build(<q-args>)
command! -nargs=* Cclean call cargo#clean(<q-args>)
command! -nargs=* Cdoc call cargo#doc(<q-args>)
command! -nargs=+ Cnew call cargo#new(<q-args>)
command! -nargs=* Cinit call cargo#init(<q-args>)
command! -nargs=* Crun call cargo#run(<q-args>)
command! -nargs=* Ctest call cargo#test(<q-args>)
command! -nargs=* Cbench call cargo#bench(<q-args>)
command! -nargs=* Cupdate call cargo#update(<q-args>)
command! -nargs=* Csearch call cargo#search(<q-args>)
command! -nargs=* Cpublish call cargo#publish(<q-args>)
command! -nargs=* Cinstall call cargo#install(<q-args>)
command! -nargs=* Cruntarget call cargo#runtarget(<q-args>)
let &cpoptions = s:save_cpo
unlet s:save_cpo
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,28 +0,0 @@
" Vim syntastic plugin helper
" Language: Rust
" Maintainer: Andrew Gallant <jamslam@gmail.com>
if exists('g:loaded_rust_vim')
finish
endif
let g:loaded_rust_vim = 1
let s:save_cpo = &cpoptions
set cpoptions&vim
" This is to let Syntastic know about the Rust filetype.
" It enables tab completion for the 'SyntasticInfo' command.
" (This does not actually register the syntax checker.)
if exists('g:syntastic_extra_filetypes')
call add(g:syntastic_extra_filetypes, 'rust')
else
let g:syntastic_extra_filetypes = ['rust']
endif
if !exists('g:syntastic_rust_checkers')
let g:syntastic_rust_checkers = ['cargo']
endif
let &cpoptions = s:save_cpo
unlet s:save_cpo
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,351 +0,0 @@
" Vim syntax file
" Language: Rust
" Maintainer: Patrick Walton <pcwalton@mozilla.com>
" Maintainer: Ben Blum <bblum@cs.cmu.edu>
" Maintainer: Chris Morgan <me@chrismorgan.info>
" Last Change: Feb 24, 2016
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
" Syntax definitions {{{1
" Basic keywords {{{2
syn keyword rustConditional match if else
syn keyword rustRepeat for loop while
syn keyword rustTypedef type nextgroup=rustIdentifier skipwhite skipempty
syn keyword rustStructure struct enum nextgroup=rustIdentifier skipwhite skipempty
syn keyword rustUnion union nextgroup=rustIdentifier skipwhite skipempty contained
syn match rustUnionContextual /\<union\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*/ transparent contains=rustUnion
syn keyword rustOperator as
syn keyword rustExistential existential nextgroup=rustTypedef skipwhite skipempty contained
syn match rustExistentialContextual /\<existential\_s\+type/ transparent contains=rustExistential,rustTypedef
syn match rustAssert "\<assert\(\w\)*!" contained
syn match rustPanic "\<panic\(\w\)*!" contained
syn match rustKeyword "\<async\%(\s\|\n\)\@="
syn keyword rustKeyword break
syn keyword rustKeyword box nextgroup=rustBoxPlacement skipwhite skipempty
syn keyword rustKeyword continue
syn keyword rustKeyword crate
syn keyword rustKeyword extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty
syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite skipempty
syn keyword rustKeyword in impl let
syn keyword rustKeyword macro
syn keyword rustKeyword pub nextgroup=rustPubScope skipwhite skipempty
syn keyword rustKeyword return
syn keyword rustKeyword yield
syn keyword rustSuper super
syn keyword rustKeyword where
syn keyword rustUnsafeKeyword unsafe
syn keyword rustKeyword use nextgroup=rustModPath skipwhite skipempty
" FIXME: Scoped impl's name is also fallen in this category
syn keyword rustKeyword mod trait nextgroup=rustIdentifier skipwhite skipempty
syn keyword rustStorage move mut ref static const
syn match rustDefault /\<default\ze\_s\+\(impl\|fn\|type\|const\)\>/
syn keyword rustPubScopeCrate crate contained
syn match rustPubScopeDelim /[()]/ contained
syn match rustPubScope /([^()]*)/ contained contains=rustPubScopeDelim,rustPubScopeCrate,rustSuper,rustModPath,rustModPathSep,rustSelf transparent
syn keyword rustExternCrate crate contained nextgroup=rustIdentifier,rustExternCrateString skipwhite skipempty
" This is to get the `bar` part of `extern crate "foo" as bar;` highlighting.
syn match rustExternCrateString /".*"\_s*as/ contained nextgroup=rustIdentifier skipwhite transparent skipempty contains=rustString,rustOperator
syn keyword rustObsoleteExternMod mod contained nextgroup=rustIdentifier skipwhite skipempty
syn match rustIdentifier contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
syn match rustFuncName "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
syn region rustBoxPlacement matchgroup=rustBoxPlacementParens start="(" end=")" contains=TOP contained
" Ideally we'd have syntax rules set up to match arbitrary expressions. Since
" we don't, we'll just define temporary contained rules to handle balancing
" delimiters.
syn region rustBoxPlacementBalance start="(" end=")" containedin=rustBoxPlacement transparent
syn region rustBoxPlacementBalance start="\[" end="\]" containedin=rustBoxPlacement transparent
" {} are handled by rustFoldBraces
syn region rustMacroRepeat matchgroup=rustMacroRepeatDelimiters start="$(" end=")" contains=TOP nextgroup=rustMacroRepeatCount
syn match rustMacroRepeatCount ".\?[*+]" contained
syn match rustMacroVariable "$\w\+"
" Reserved (but not yet used) keywords {{{2
syn keyword rustReservedKeyword alignof become do offsetof priv pure sizeof typeof unsized abstract virtual final override
" Built-in types {{{2
syn keyword rustType isize usize char bool u8 u16 u32 u64 u128 f32
syn keyword rustType f64 i8 i16 i32 i64 i128 str Self
" Things from the libstd v1 prelude (src/libstd/prelude/v1.rs) {{{2
" This section is just straight transformation of the contents of the prelude,
" to make it easy to update.
" Reexported core operators {{{3
syn keyword rustTrait Copy Send Sized Sync
syn keyword rustTrait Drop Fn FnMut FnOnce
" Reexported functions {{{3
" Theres no point in highlighting these; when one writes drop( or drop::< it
" gets the same highlighting anyway, and if someone writes `let drop = …;` we
" dont really want *that* drop to be highlighted.
"syn keyword rustFunction drop
" Reexported types and traits {{{3
syn keyword rustTrait Box
syn keyword rustTrait ToOwned
syn keyword rustTrait Clone
syn keyword rustTrait PartialEq PartialOrd Eq Ord
syn keyword rustTrait AsRef AsMut Into From
syn keyword rustTrait Default
syn keyword rustTrait Iterator Extend IntoIterator
syn keyword rustTrait DoubleEndedIterator ExactSizeIterator
syn keyword rustEnum Option
syn keyword rustEnumVariant Some None
syn keyword rustEnum Result
syn keyword rustEnumVariant Ok Err
syn keyword rustTrait SliceConcatExt
syn keyword rustTrait String ToString
syn keyword rustTrait Vec
" Other syntax {{{2
syn keyword rustSelf self
syn keyword rustBoolean true false
" If foo::bar changes to foo.bar, change this ("::" to "\.").
" If foo::bar changes to Foo::bar, change this (first "\w" to "\u").
syn match rustModPath "\w\(\w\)*::[^<]"he=e-3,me=e-3
syn match rustModPathSep "::"
syn match rustFuncCall "\w\(\w\)*("he=e-1,me=e-1
syn match rustFuncCall "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>();
" This is merely a convention; note also the use of [A-Z], restricting it to
" latin identifiers rather than the full Unicode uppercase. I have not used
" [:upper:] as it depends upon 'noignorecase'
"syn match rustCapsIdent display "[A-Z]\w\(\w\)*"
syn match rustOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?"
" This one isn't *quite* right, as we could have binary-& with a reference
syn match rustSigil display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1
syn match rustSigil display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1
" This isn't actually correct; a closure with no arguments can be `|| { }`.
" Last, because the & in && isn't a sigil
syn match rustOperator display "&&\|||"
" This is rustArrowCharacter rather than rustArrow for the sake of matchparen,
" so it skips the ->; see http://stackoverflow.com/a/30309949 for details.
syn match rustArrowCharacter display "->"
syn match rustQuestionMark display "?\([a-zA-Z]\+\)\@!"
syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustPanic
syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustPanic
syn match rustEscapeError display contained /\\./
syn match rustEscape display contained /\\\([nrt0\\'"]\|x\x\{2}\)/
syn match rustEscapeUnicode display contained /\\u{\%(\x_*\)\{1,6}}/
syn match rustStringContinuation display contained /\\\n\s*/
syn region rustString start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation
syn region rustString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell
syn region rustString start='b\?r\z(#*\)"' end='"\z1' contains=@Spell
syn region rustAttribute start="#!\?\[" end="\]" contains=rustString,rustDerive,rustCommentLine,rustCommentBlock,rustCommentLineDocError,rustCommentBlockDocError
syn region rustDerive start="derive(" end=")" contained contains=rustDeriveTrait
" This list comes from src/libsyntax/ext/deriving/mod.rs
" Some are deprecated (Encodable, Decodable) or to be removed after a new snapshot (Show).
syn keyword rustDeriveTrait contained Clone Hash RustcEncodable RustcDecodable Encodable Decodable PartialEq Eq PartialOrd Ord Rand Show Debug Default FromPrimitive Send Sync Copy
" dyn keyword: It's only a keyword when used inside a type expression, so
" we make effort here to highlight it only when Rust identifiers follow it
" (not minding the case of pre-2018 Rust where a path starting with :: can
" follow).
"
" This is so that uses of dyn variable names such as in 'let &dyn = &2'
" and 'let dyn = 2' will not get highlighted as a keyword.
syn match rustKeyword "\<dyn\ze\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)" contains=rustDynKeyword
syn keyword rustDynKeyword dyn contained
" Number literals
syn match rustDecNumber display "\<[0-9][0-9_]*\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
syn match rustOctNumber display "\<0o[0-7_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
syn match rustBinNumber display "\<0b[01_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
" Special case for numbers of the form "1." which are float literals, unless followed by
" an identifier, which makes them integer literals with a method call or field access,
" or by another ".", which makes them integer literals followed by the ".." token.
" (This must go first so the others take precedence.)
syn match rustFloat display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!"
" To mark a number as a normal float, it must have at least one of the three things integral values don't have:
" a decimal point and more numbers; an exponent; and a type suffix.
syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\="
syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\="
syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)"
" For the benefit of delimitMate
syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u{\%(\x_*\)\{1,6}}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
syn region rustGenericRegion display start=/<\%('\|[^[:cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate
syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
"rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting
syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
syn match rustLabel display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*:"
syn match rustCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/
" The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII).
syn match rustCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/
syn match rustCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode
syn match rustCharacter /'\([^\\]\|\\\(.\|x\x\{2}\|u{\%(\x_*\)\{1,6}}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid
syn match rustShebang /\%^#![^[].*/
syn region rustCommentLine start="//" end="$" contains=rustTodo,@Spell
syn region rustCommentLineDoc start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell
syn region rustCommentLineDocError start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell contained
syn region rustCommentBlock matchgroup=rustCommentBlock start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell
syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNest,rustCommentBlockDocRustCode,@Spell
syn region rustCommentBlockDocError matchgroup=rustCommentBlockDocError start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained
syn region rustCommentBlockNest matchgroup=rustCommentBlock start="/\*" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent
syn region rustCommentBlockDocNest matchgroup=rustCommentBlockDoc start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent
syn region rustCommentBlockDocNestError matchgroup=rustCommentBlockDocError start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained transparent
" FIXME: this is a really ugly and not fully correct implementation. Most
" importantly, a case like ``/* */*`` should have the final ``*`` not being in
" a comment, but in practice at present it leaves comments open two levels
" deep. But as long as you stay away from that particular case, I *believe*
" the highlighting is correct. Due to the way Vim's syntax engine works
" (greedy for start matches, unlike Rust's tokeniser which is searching for
" the earliest-starting match, start or end), I believe this cannot be solved.
" Oh you who would fix it, don't bother with things like duplicating the Block
" rules and putting ``\*\@<!`` at the start of them; it makes it worse, as
" then you must deal with cases like ``/*/**/*/``. And don't try making it
" worse with ``\%(/\@<!\*\)\@<!``, either...
syn keyword rustTodo contained TODO FIXME XXX NB NOTE
" Folding rules {{{2
" Trivial folding rules to begin with.
" FIXME: use the AST to make really good folding
syn region rustFoldBraces start="{" end="}" transparent fold
if !exists("b:current_syntax_embed")
let b:current_syntax_embed = 1
syntax include @RustCodeInComment <sfile>:p:h/rust.vim
unlet b:current_syntax_embed
" Currently regions marked as ```<some-other-syntax> will not get
" highlighted at all. In the future, we can do as vim-markdown does and
" highlight with the other syntax. But for now, let's make sure we find
" the closing block marker, because the rules below won't catch it.
syn region rustCommentLinesDocNonRustCode matchgroup=rustCommentDocCodeFence start='^\z(\s*//[!/]\s*```\).\+$' end='^\z1$' keepend contains=rustCommentLineDoc
" We borrow the rules from rusts src/librustdoc/html/markdown.rs, so that
" we only highlight as Rust what it would perceive as Rust (almost; its
" possible to trick it if you try hard, and indented code blocks arent
" supported because Markdown is a menace to parse and only mad dogs and
" Englishmen would try to handle that case correctly in this syntax file).
syn region rustCommentLinesDocRustCode matchgroup=rustCommentDocCodeFence start='^\z(\s*//[!/]\s*```\)[^A-Za-z0-9_-]*\%(\%(should_panic\|no_run\|ignore\|allow_fail\|rust\|test_harness\|compile_fail\|E\d\{4}\|edition201[58]\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment,rustCommentLineDocLeader
syn region rustCommentBlockDocRustCode matchgroup=rustCommentDocCodeFence start='^\z(\%(\s*\*\)\?\s*```\)[^A-Za-z0-9_-]*\%(\%(should_panic\|no_run\|ignore\|allow_fail\|rust\|test_harness\|compile_fail\|E\d\{4}\|edition201[58]\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment,rustCommentBlockDocStar
" Strictly, this may or may not be correct; this code, for example, would
" mishighlight:
"
" /**
" ```rust
" println!("{}", 1
" * 1);
" ```
" */
"
" … but I dont care. Balance of probability, and all that.
syn match rustCommentBlockDocStar /^\s*\*\s\?/ contained
syn match rustCommentLineDocLeader "^\s*//\%(//\@!\|!\)" contained
endif
" Default highlighting {{{1
hi def link rustDecNumber rustNumber
hi def link rustHexNumber rustNumber
hi def link rustOctNumber rustNumber
hi def link rustBinNumber rustNumber
hi def link rustIdentifierPrime rustIdentifier
hi def link rustTrait rustType
hi def link rustDeriveTrait rustTrait
hi def link rustMacroRepeatCount rustMacroRepeatDelimiters
hi def link rustMacroRepeatDelimiters Macro
hi def link rustMacroVariable Define
hi def link rustSigil StorageClass
hi def link rustEscape Special
hi def link rustEscapeUnicode rustEscape
hi def link rustEscapeError Error
hi def link rustStringContinuation Special
hi def link rustString String
hi def link rustCharacterInvalid Error
hi def link rustCharacterInvalidUnicode rustCharacterInvalid
hi def link rustCharacter Character
hi def link rustNumber Number
hi def link rustBoolean Boolean
hi def link rustEnum rustType
hi def link rustEnumVariant rustConstant
hi def link rustConstant Constant
hi def link rustSelf Constant
hi def link rustFloat Float
hi def link rustArrowCharacter rustOperator
hi def link rustOperator Operator
hi def link rustKeyword Keyword
hi def link rustDynKeyword rustKeyword
hi def link rustTypedef Keyword " More precise is Typedef, but it doesn't feel right for Rust
hi def link rustStructure Keyword " More precise is Structure
hi def link rustUnion rustStructure
hi def link rustExistential rustKeyword
hi def link rustPubScopeDelim Delimiter
hi def link rustPubScopeCrate rustKeyword
hi def link rustSuper rustKeyword
hi def link rustUnsafeKeyword Exception
hi def link rustReservedKeyword Error
hi def link rustRepeat Conditional
hi def link rustConditional Conditional
hi def link rustIdentifier Identifier
hi def link rustCapsIdent rustIdentifier
hi def link rustModPath Include
hi def link rustModPathSep Delimiter
hi def link rustFunction Function
hi def link rustFuncName Function
hi def link rustFuncCall Function
hi def link rustShebang Comment
hi def link rustCommentLine Comment
hi def link rustCommentLineDoc SpecialComment
hi def link rustCommentLineDocLeader rustCommentLineDoc
hi def link rustCommentLineDocError Error
hi def link rustCommentBlock rustCommentLine
hi def link rustCommentBlockDoc rustCommentLineDoc
hi def link rustCommentBlockDocStar rustCommentBlockDoc
hi def link rustCommentBlockDocError Error
hi def link rustCommentDocCodeFence rustCommentLineDoc
hi def link rustAssert PreCondit
hi def link rustPanic PreCondit
hi def link rustMacro Macro
hi def link rustType Type
hi def link rustTodo Todo
hi def link rustAttribute PreProc
hi def link rustDerive PreProc
hi def link rustDefault StorageClass
hi def link rustStorage StorageClass
hi def link rustObsoleteStorage Error
hi def link rustLifetime Special
hi def link rustLabel Label
hi def link rustExternCrate rustKeyword
hi def link rustObsoleteExternMod Error
hi def link rustBoxPlacementParens Delimiter
hi def link rustQuestionMark Special
" Other Suggestions:
" hi rustAttribute ctermfg=cyan
" hi rustDerive ctermfg=cyan
" hi rustAssert ctermfg=yellow
" hi rustPanic ctermfg=red
" hi rustMacro ctermfg=magenta
syn sync minlines=200
syn sync maxlines=500
let b:current_syntax = "rust"
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,93 +0,0 @@
" Vim syntastic plugin
" Language: Rust
" Maintainer: Julien Levesy <jlevesy@gmail.com>
"
" See for details on how to add an external Syntastic checker:
" https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide#external
if exists("g:loaded_syntastic_rust_cargo_checker")
finish
endif
let g:loaded_syntastic_rust_cargo_checker = 1
" Force syntastic to call cargo without a specific file name
let g:syntastic_rust_cargo_fname = ""
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_rust_cargo_IsAvailable() dict
if exists("*syntastic#util#getVersion")
echom "rust.vim: version of Syntastic is too old. Needs to be at least 3.7.0."
return v:false
endif
return executable(self.getExec()) &&
\ syntastic#util#versionIsAtLeast(self.getVersion(), [0, 16, 0])
endfunction
function! SyntaxCheckers_rust_cargo_GetLocList() dict
let makeprg = self.makeprgBuild({ "args": "check" })
let l:root_cargo_toml = cargo#nearestRootCargo(0)
let l:nearest_cargo_toml = cargo#nearestCargo(0)
let b:rust_recent_root_cargo_toml = l:root_cargo_toml
let b:rust_recent_nearest_cargo_toml = l:nearest_cargo_toml
" All pathname prints are relative to the Cargo.toml of the workspace, if
" there is a workspace, otherwise they are relative to the Cargo.toml of
" the single crate. Where to actually execute under these varying
" circumtances 'cargo' is determined here, and controlled by
" configuration.
if rust#GetConfigVar('rust_cargo_avoid_whole_workspace', 1)
if l:root_cargo_toml !=# l:nearest_cargo_toml
let makeprg = "cd " . fnamemodify(l:nearest_cargo_toml, ":p:h")
\ . " && " . makeprg
endif
else
let makeprg = "cd " . fnamemodify(l:root_cargo_toml, ":p:h")
\ . " && " . makeprg
endif
let l:check_all_targets = rust#GetConfigVar('rust_cargo_check_all_targets', 0)
let l:check_all_features = rust#GetConfigVar('rust_cargo_check_all_features', 0)
let l:check_examples = rust#GetConfigVar('rust_cargo_check_examples', 0)
let l:check_tests = rust#GetConfigVar('rust_cargo_check_tests', 0)
let l:check_benches = rust#GetConfigVar('rust_cargo_check_benches', 0)
let makeprg = makeprg. ' '
\ . (l:check_all_targets ? ' --all-targets' : '')
\ . (l:check_all_features ? ' --all-features' : '')
\ . (l:check_benches ? ' --benches' : '')
\ . (l:check_examples ? ' --examples' : '')
\ . (l:check_tests ? ' --tests' : '')
" Ignored patterns, and blank lines
let errorformat =
\ '%-G,' .
\ '%-Gerror: aborting %.%#,' .
\ '%-Gerror: Could not compile %.%#,'
" Meaningful lines (errors, notes, warnings, contextual information)
let errorformat .=
\ '%Eerror: %m,' .
\ '%Eerror[E%n]: %m,' .
\ '%Wwarning: %m,' .
\ '%Inote: %m,' .
\ '%C %#--> %f:%l:%c'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'cwd': fnamemodify(l:root_cargo_toml, ":p:h:."),
\ 'errorformat': errorformat })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'rust',
\ 'name': 'cargo'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,54 +0,0 @@
" Vim syntastic plugin
" Language: Rust
" Maintainer: Andrew Gallant <jamslam@gmail.com>
"
" See for details on how to add an external Syntastic checker:
" https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide#external
if exists("g:loaded_syntastic_rust_rustc_checker")
finish
endif
let g:loaded_syntastic_rust_rustc_checker = 1
" vint: -ProhibitAbbreviationOption
let s:save_cpo = &cpo
set cpo&vim
" vint: +ProhibitAbbreviationOption
function! SyntaxCheckers_rust_rustc_GetLocList() dict
let makeprg = self.makeprgBuild({})
" Old errorformat (before nightly 2016/08/10)
let errorformat =
\ '%E%f:%l:%c: %\d%#:%\d%# %.%\{-}error:%.%\{-} %m,' .
\ '%W%f:%l:%c: %\d%#:%\d%# %.%\{-}warning:%.%\{-} %m,' .
\ '%C%f:%l %m'
" New errorformat (after nightly 2016/08/10)
let errorformat .=
\ ',' .
\ '%-G,' .
\ '%-Gerror: aborting %.%#,' .
\ '%-Gerror: Could not compile %.%#,' .
\ '%Eerror: %m,' .
\ '%Eerror[E%n]: %m,' .
\ '%-Gwarning: the option `Z` is unstable %.%#,' .
\ '%Wwarning: %m,' .
\ '%Inote: %m,' .
\ '%C %#--> %f:%l:%c'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'rust',
\ 'name': 'rustc'})
" vint: -ProhibitAbbreviationOption
let &cpo = s:save_cpo
unlet s:save_cpo
" vint: +ProhibitAbbreviationOption
" vim: set et sw=4 sts=4 ts=8:

View file

@ -1,34 +0,0 @@
# This is brought as reference, to be able to reproduce a new image
FROM alonid/vim-testbed:10
RUN install_vim -tag v7.4.052 -name vim74-trusty -build \
-tag v8.0.1850 -name vim80 -build \
-tag v8.1.0105 -name vim81 -build \
-tag neovim:v0.1.7 -build \
-tag neovim:v0.2.2 -build
ENV PACKAGES="\
bash \
git \
python \
python2-pip \
curl \
"
RUN dnf install -y $PACKAGES
RUN pip install vim-vint==0.3.19
RUN export HOME=/rust ; mkdir $HOME ; curl https://sh.rustup.rs -sSf | sh -s -- -y
RUN chown vimtest.vimtest -R /rust
RUN (dnf remove -y gcc \*-devel ; \
dnf install -y gpm msgpack libvterm libtermkey unibilium ) || true
RUN dnf clean all
RUN echo "export PATH=~/.cargo/bin:$PATH" >> ~/.bashrc
RUN git clone https://github.com/da-x/vader.vim vader && \
cd vader && git checkout v2017-12-26

View file

@ -1,24 +0,0 @@
Given rust (Some Rust code):
fn main() {
println!("Hello World\n")
}
Execute (RustInfo - call it to see that it works):
redir => m
silent RustInfo
redir END
Log m
Execute (RustEmitAsm - see that we actually get assembly output):
silent! w test.rs
silent! e! test.rs
redir => m
silent! RustEmitAsm
redir END
AssertEqual 'asm', &filetype
normal! ggVGy:q<CR>
AssertEqual 1,(@" =~# '\V.section')
bd
call delete('test.rs')
# TODO: a lot more tests

View file

@ -1,105 +0,0 @@
#!/usr/bin/env python
import os
import sys
REPO = "alonid/vim-testbed"
TAG = "10-rust.vim"
IMAGE = "%s:%s" % (REPO, TAG)
class Error(Exception):
pass
def system(cmd, capture=False, ok_fail=False):
if capture:
f = os.popen(cmd)
d = f.read()
return d
res = os.system(cmd)
if res != 0:
if ok_fail:
return res
raise Error("Error executing: %s" % (cmd, ))
return 0
def root():
return os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
def prep():
d = os.path.join(root(), "test")
for i in [".cargo", ".rustup", ".multirust"]:
l = os.path.join(d, i)
if not os.path.lexists(l):
os.symlink("/rust/" + i, l)
l = os.path.join(root(), "test/.vimrc")
if not os.path.lexists(l):
os.symlink("vimrc", l)
if not os.path.exists(os.path.join(d, ".profile")):
f = open(os.path.join(d, ".profile"), "w")
f.write('export PATH="$HOME/.cargo/bin:$PATH"\n')
f.close()
def docker_run(cmd, interactive=False, ok_fail=False):
prep()
d = root()
params = "-v %s:/testplugin -v %s/test:/home/vimtest" % (d, d)
params += " -e HOME=/home/vimtest"
if not interactive:
params += " -a stderr"
params += " -e VADER_OUTPUT_FILE=/dev/stderr"
params += " -u %s" % (os.getuid(), )
params += " -w /testplugin"
if interactive:
interactive_str = "-it"
else:
interactive_str = ""
return system("docker run %s --rm %s %s %s" % (interactive_str, params, IMAGE, cmd),
ok_fail=ok_fail)
def image_exists():
r = system("docker images -q %s" % (IMAGE, ), capture=True)
return len(r.strip().splitlines()) >= 1
def tests_on_docker():
res = docker_run("bash -lc 'python /home/vimtest/run-tests inside-docker'", ok_fail=True)
if res == 0:
print "Tests OK"
else:
print "Tests Failed"
sys.exit(1)
def inside_docker():
res = system("/vim-build/bin/vim80 --not-a-term '+Vader! test/*.vader'", ok_fail=True)
if res != 0:
sys.exit(1)
def run_with_vimrc(vimrc):
res = system("vim -u %s --not-a-term '+Vader! test/*.vader'" % (vimrc, ), ok_fail=True)
if res != 0:
sys.exit(1)
def main():
if sys.argv[1:] == ["inside-docker"]:
inside_docker()
return
if sys.argv[1:2] == ["run-with-vimrc"]:
run_with_vimrc(sys.argv[2])
return
if not image_exists():
print "Need to take image from remote"
system("docker pull %s" % (IMAGE, ))
if "-i" in sys.argv[1:]:
docker_run("bash -l", interactive=True)
return
tests_on_docker()
if __name__ == "__main__":
main()

View file

@ -1,30 +0,0 @@
" vint: -ProhibitSetNoCompatible
"
set nocompatible
filetype off
" This script is currently designed to be run from within Docker, the
" following paths are intrinsic to the container:
source /rtp.vim
" Paths need prepending (instead of what is originally done
" in vim-testbed) in order to supersede the rust.vim that is
" supplied with Vim.
exec 'set runtimepath=/vader,/testplugin,' . &runtimepath
cd /testplugin
filetype plugin indent on
syntax on
set nocompatible
set tabstop=8
set softtabstop=4
set shiftwidth=4
set expandtab
set backspace=2
set nofoldenable
set foldmethod=syntax
set foldlevelstart=10
set foldnestmax=10
set ttimeoutlen=0

View file

@ -1,6 +0,0 @@
*.pyc
*.swp
tags
.ropeproject
.cover*
cover*

View file

@ -1,238 +0,0 @@
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
init-hook=sys.path.append(os.path.abspath('ftplugin'))
# Profiled execution.
profile=no
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=.git
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once).
#disable=
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html
output-format=parseable
# Include message's id in output
include-ids=no
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no
# Tells whether to display a full report or only the messages
reports=yes
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Add a comment according to your evaluation note. This is used by the global
# evaluation report (RP0004).
comment=no
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject
# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=no
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
generated-members=REQUEST,acl_users,aq_parent
[BASIC]
# Required attributes for module, separated by a comma
required-attributes=
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,apply,input
# Regular expression which should only match correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression which should only match correct module level names
const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$
# Regular expression which should only match correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Regular expression which should only match correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct instance attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct list comprehension /
# generator expression variable names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Regular expression which should only match functions or classes name which do
# not require a docstring
no-docstring-rgx=__.*__
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the beginning of the name of dummy variables
# (i.e. not used).
dummy-variables-rgx=_|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=800
# Maximum number of lines in a module
max-module-lines=1000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=\t
[CLASSES]
# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defines in Zope's Interface base class.
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branchs=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20

View file

@ -1,21 +0,0 @@
language: python
before_install:
- sudo apt-get update && sudo apt-get --reinstall install -qq language-pack-pt
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
install:
- pip install coverage
- pip install codecov
script:
- cd tests
- nosetests --with-coverage .
after_success:
- codecov

View file

@ -1,214 +0,0 @@
* Changelog
All notable changes to this project will be documented in this file.
This log is kept according to the [[http://keepachangelog.com/][Keep a CHANGELOG]] manifesto
** 0.7.0 :unreleased:
*** Added
- Subtracting when entering dates (PR #276)
*** Fixed
- =ir= text object now works with most operations (PR #284, closes #273)
** 0.6.0 <2017-11-06 Mon> :released:
*** Added
- Introduced sphinx documentation to Python modules. (PR #237)
- Add =Python3= support. (PR #231, closes #226)
- Implementing agenda overview for current buffer. (PR #229)
- =g:org_aggressive_conceal=, if value =1=, will conceal all simple format
identifying characters, default =0=. (PR #188)
- (testing on `g:org_aggressive_conceal=1' mode) Add possibility to escape
format indicating characters from leading inline markup, by escaping with
"\".
- Add alternative behavior: refrain from entering insert mode after
heading/checkbox creation through keybindings. Activate by setting
=g:org_prefer_insert_mode= to 0. (closes #211)
- Add export as LaTeX beamer slides (PR #206)
- Keybinding to create plainlist item directly. (closes #190)
- Make % jump between < and >. (PR #251, closes #250)
*** Changed
- Changed default value for =g:org_indent= from =1= to =0=. (closes #243)
- Revamped TODO keyword cycling rules. (PR #237)
- In [[syntax/org.vim][syntax/org.vim]], changed `\@<=' with computational faster `\zs'
- Using =<localleader>c[n/N]= to create new plainlist item following
current plainlist item. Now these keybindings will unconditionally
create empty checkbox. (closes #190)
*** Deprecated
- Nothing
*** Removed
- Removed the requirement for TODO state keywords to be upper-case.
(PR #235)
*** Fixed
- Avoid duplicate =InsertLeave= handlers (PR #222, closes #223)
- Fix python3 compatibility issue with regexes
(PR #266, closes #263, #265)
- Fixed python3 compatible issue within =CalendarAction=.
(PR #242, closes #241)
- Tree promoting/demoting no longer destroy list and checkbox structure.
(closes #217)
- Fixed bug when promote/demote headings when it contain lists.
(PR #239, partly fixes #217)
- Silenced =W18= warning when non-ASCII coded TODO keywords are used.
(PR #236)
- Fix non-English locale support issue in OrgDate and Agenda. (PR #234,
closes #230)
- Fix =concealcursor= mis-setting. (from ="nc"= to =nc=)
- Fix duplicate =InsertLeave= autocmd for =tag_complete=. (closes #223)
- Fix utl error when =\= or white space is in the link by auto-escaping.
(closes #220)
- Fix typo vbm -> vmb (PR #219)
- Fix toggling checkboxes with plain embedded lists (PR #212, closes #209)
- Return to right window before setting todo (closes #202)
- Fix link to calendar-vim (closes #197)
- Fix =out of bound= issue when creating heading/checkbox after last
instance in document on NeoVim. (closes #213)
** 0.5.0 <2015-10-10 Sat> :released:
*** Added
- show link description in headings when folded, instead of the whole
link
- add simplified mappings to create new headings with
[<localleader>|<leader>]<CR>
- improve incrementing and decrementing of list items
- moved changelog information to its own file
- add tests for the tags plugin
- copy type and indentation when creating new list items
- increase/decrease ordered list when adding new items
- add support for alphanumeric ordered lists
- add test cases for overlapping mappings
- add three dots after folded text, like in orgmode
- improve highlighting of org-mode properties (closes issue #130)
- implement global visibility as it works in Emacs org-mode (closes issue
#119)
- improve detection of speeddating plugin (closes issue #121)
- add support for high speed searching of headings that use certain tags
(closes issue #58)
- make echo, echom and echoe split messages a line ends and execute a
single vim command for each line
- add export commands OrgExportToPDF and OrgExportToHTML (closes issue
#107)
- add variables for customizing the export via Emacs: g:org_export_emacs,
g:org_export_verbose, g:org_export_init_script (closes issue #107)
- switch to subprocess.Popen for Emcas export (closes issue #107)
- add defaults and examples for all variables
- add support for inserting new checkboxes with the same keybinging as
inserting new headings (thanks to Powen Tan)
- implemented support for markdown export (issue #185)
*** Deprecated
- Nothing
*** Removed
- Nothing
*** Fixed
- allow checkbox status to be toggled when there is no indicator present
([])
- improve installation instructions (related to issues #111 and #176)
- optimize checkbox regex to match also just the type without status and
title
- fix broken unordered lists
- set org_tag_column to textwidth
- change commentstring to "# %s"
- fix syntax highlighting of list items
- fix indentation of first checkbox of a heading
- fix indentation of first checkbox of a heading
- disable highlighting of non-printable characters in todo state
selection window
- fix highlighting of todo keywords that are followed by additional
characters, i.e. TODOs
- omit status when entering new checkbox item if current checkbox doesn't
have one
- fix broken indentation of checkboxes (closes issue #146)
- fix CalendarAction is undefined (closes issue #142)
- correct overlapping mappings in PluginDate
- fix cache problems when inserting a new heading, together with multi
line text (closes issue #116)
- rename plug to OrgTodoToggleNonInteractive (closes issue #114)
- fix jumping to the first character within the body of a heading
- use Ignore highlighting instead of NonText for shaded stars (closes
issues #173)
- fix broken buffer number (closes issue #177)
- make exports work with emacs 24.4 (closes issue #178)
- improve comments
- fix syntax for #+BEGIN_* blocks (issue #186)
** 0.4.0-0 <2011-10-16 Sun> :released:
- fix broken repeat settings for moving a heading
- improve performance when moving a heading upward or downward (closes
issue #108)
- improve performance when changing the level of a heading (related to
issue #108)
- extend liborgmode.headings.HeadingList to allow headings to not be
tainted when moving them around
- change heading tree text object to ir/ar... because of vim's it/at text
object (closes issue #106)
- improve performance when inserting a new heading below (closes issue
#105)
- remove duplicate tags (closes issue #104)
- improve performance in insert mode (closes issue #103)
- improve performance when opening larger org files (closes issue #103)
- replace org.txt by orgguide.txt (closes issue #77)
- replace g:org_leader by <LocalLeader> (closes issue #101)
To restore the previous behavior add the following line to your vimrc:
>
let maplocalleader = ','
<
- change normal command execution to not remap any key (related to issue
#85)
- fix regression timeout when opening folds (closes issue #100)
- vim-orgmode multistate documentation (closes issue #77)
- add support for @-signs in tags (closes issue #98)
- enable file completion for hyperlinks by default (closes issue #97)
- fix traceback when pressing <Esc> while editing a link (closes issue
#96)
- implement reverse visibility cycling using <S-Tab> (closes issue #95)
- change ,, and ,. to remap zr and zm. (closes issue #73)
- add .cnf files to the vimball archive (closes #93)
- integrate pylint code checker (closes issue #87)
- solve encoding issues in the agenda plugin (closes issue #86)
- add description for writing test cases
- add coverage report target (closes issue #74)
- add support for plain lists, thanks to Aleksandar Dimitrov (closes issue
#81)
- add agenda view, many thanks to Stefan Otte (closes issue #34)
- move cursor to the current todo state when selecting the todo state
interactively (closes issue #61)
- add parameter scope to method settings.get
- add method settings.unset
- fix cursor positioning when selecting todo states
- improve date plugin
- update vba targets to its new name vmb
- demoting a newly created second level heading doesn't cause all children
to
be deleted anymore (closes issue #65)
- add error message for missing dependencies (closes issue #59)
- rename tests directory
- change licensing of the documentation to GNU Free Documentation License
- integrate orgguide (closes issue #57)
- replace DIRECTION_* with an enum (closes issue #56 and issue #49)
** 0.3.1-0 <2011-08-14 Sun> :released:
- demoting a newly created second level heading doesn't cause all children
to be deleted anymore (closes issue #65)
- add error message for missing dependencies (closes issue #59)
** 0.3.0-0 <2011-08-09 Tue> :released:
- fix completion menu popup that disappeared because of the usage of
vim.command (closes issue #48)
- implement interactive todo state selection (closes issue #5)
- add orgmode group to au commands in TagProperties plugin (closes issue
#53)
- allow demotion of first level headings (closes issue #27)
- fix encoding issues in Date plugin
- add general support for multiple todo sequences (closes Issue #46)
- fix folded text for headings containing backslashes or double quotes
(closes issue #26)
- add Document.get_todo_states() and Document.get_all_todo_states()
- don't confuse upper case words at the beginning of a heading with a todo
state (closes issue #28)
- fix error in setting tags (issue #25)
- improve split of heading (issue #24)
- add variable g:org_improve_split_heading to enable/disable improve the
split of headings (issue #24)
- implement shortcut for moving to the partent's next sibling (g}) (issue
#22)
- fix duplication of children when inserting a new heading (issue #20)
- always start insert mode when adding a new heading (issue #21)
** 0.2.1-0 <2011-06-26 Sun> :released:
- fix encoding of todo states set by the Todo plugin (thanks to Daniel
Carl and kien for pointing out the issue)
- add documentation for remapping shortcuts
- add documentation for customizing syntax highlighting
** 0.2.0-0 <2011-06-25 Sat> :released:
- initial release

View file

@ -1,60 +0,0 @@
---------------------------------------------------------------------
All source code is licensed under the terms of the following license:
---------------------------------------------------------------------
Copyright (C) 2010,2011 Jan Christoph Ebersbach
http://www.e-jc.de/
All rights reserved.
The source code of this program is made available under the terms of the
GNU Affero General Public License version 3 (GNU AGPL V3) as published
by the Free Software Foundation.
Binary versions of this program provided by Univention to you as well as
other copyrighted, protected or trademarked materials like Logos,
graphics, fonts, specific documentations and configurations,
cryptographic keys etc. are subject to a license agreement between you
and Univention and not subject to the GNU AGPL V3.
In the case you use this program under the terms of the GNU AGPL V3, the
program is provided in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
License for more details.
You should have received a copy of the GNU Affero General Public License
with the Debian GNU/Linux or Univention distribution in file
/usr/share/common-licenses/AGPL-3; if not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------
All documentation found in the directories doc and documentation are
licensed under the terms of the following license:
--------------------------------------------------------------------
doc/org.txt
Copyright (C) 2010,2011 Jan Christoph Ebersbach
doc/orgguide.txt
documentation/emacs_orgguide.org
documentation/emacs_orgguide.texi
Copyright (C) 2010 Free Software Foundation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover texts being “A GNU Manual,” and
with the Back-Cover Texts as in (a) below. A copy of the license is
included in the section entitled “GNU Free Documentation License.”
(a) The FSFs Back-Cover Text is: “You have the freedom to copy and
modify this GNU manual. Buying copies from the FSF supports it in
developing GNU and promoting software freedom.”
This document is part of a collection distributed under the GNU Free
Documentation License. If you want to distribute this document
separately from the collection, you can do so by adding a copy of the
license to the document, as described in section 6 of the license.

View file

@ -1,91 +0,0 @@
PLUGIN = orgmode
PREFIX = /usr/local
VIMDIR = $(PREFIX)/share/vim
all: build
build:
# install plugin at destination
install: doc indent ftdetect ftplugin syntax
for i in doc indent ftdetect ftplugin syntax; do \
find $$i -type f -name \*.txt -o -type f -name \*.cnf -o -type f -name \*.py -o -type f -name \*.vim | while read f; do \
install -m 0755 -d $(DESTDIR)$(VIMDIR)/$$(dirname "$$f"); \
install -m 0644 $$f $(DESTDIR)$(VIMDIR)/$$f; \
done; \
done
# cleanup
clean: documentation
@find . -name \*.pyc -o -name \*.py,cover -exec rm {} \;
@rm -rf ${PLUGIN}.vmb ${PLUGIN}.vmb.gz tmp files
cd $< && $(MAKE) $@
# generate the vim ball package
${PLUGIN}.vmb: check build_vmb.vim clean
$(MAKE) DESTDIR=$(PWD)/tmp VIMDIR= install
find tmp -type f | sed -e 's/^tmp\///' > files
cp build_vmb.vim tmp
cd tmp && vim --cmd 'let g:plugin_name="${PLUGIN}"' -s build_vmb.vim
[ -e tmp/${PLUGIN}.vba ] && mv tmp/${PLUGIN}.vba tmp/$@ || true
mv tmp/$@ .
${PLUGIN}.vmb.gz: ${PLUGIN}.vmb
@rm -f ${PLUGIN}.vmb.gz
gzip $<
vmb: ${PLUGIN}.vmb
vmb.gz: ${PLUGIN}.vmb.gz
${PLUGIN}.vba: ${PLUGIN}.vmb
mv $< $@
${PLUGIN}.vba.gz: ${PLUGIN}.vba
@rm -f ${PLUGIN}.vba.gz
gzip $<
vba: ${PLUGIN}.vba
vba.gz: ${PLUGIN}.vba.gz
# run unit tests
test: check
check: tests/run_tests.py
cd tests && python2 run_tests.py
# generate documentation
docs: documentation
cd $< && $(MAKE)
# generate a test coverage report for all python files
coverage:
@echo ">>> Coverage depends on the package python-nose and python-coverage, make sure they are installed!"
cd tests && nosetests2 --with-coverage --cover-html .
# run a static code checker
lint:
@echo ">>> Lint depends on the package pylint make sure it's installed!"
pylint --rcfile .pylintrc --disable=C0301,C0103,C0111,C0322,C0323,C0324,W0703,W0612,W0603 orgmode
lintall:
@echo ">>> Lint depends on the package pylint make sure it's installed!"
pylint --rcfile .pylintrc orgmode
# install vim-orgmode in the .vim/bundle directory for test purposes
VIMPLUGINDIR = $(HOME)/.vim/bundle/orgmode
installvmb: ${PLUGIN}.vmb install_vmb.vim
rm -rvf ${VIMPLUGINDIR}
mkdir -p "${VIMPLUGINDIR}"
vim --cmd "let g:installdir='${VIMPLUGINDIR}'" -s install_vmb.vim $<
@echo "Plugin was installed in ${VIMPLUGINDIR}. Make sure you are using a plugin loader like pathegon, otherwise the ${PLUGIN} might not work properly."
installvba: ${PLUGIN}.vba install_vba.vim
rm -rvf ${VIMPLUGINDIR}
mkdir -p "${VIMPLUGINDIR}"
vim --cmd "let g:installdir='${VIMPLUGINDIR}'" -s install_vba.vim $<
@echo "Plugin was installed in ${VIMPLUGINDIR}. Make sure you are using a plugin loader like pathegon, otherwise the ${PLUGIN} might not work properly."
.PHONY: all build test check install clean vmb vmb.gz docs installvmb

View file

@ -1,43 +0,0 @@
* Vim-OrgMode
#+ATTR_HTML: title="Join the chat at https://gitter.im/jceb/vim-orgmode"
[[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]]
[[https://travis-ci.org/jceb/vim-orgmode][file:https://travis-ci.org/jceb/vim-orgmode.svg]]
[[https://codecov.io/gh/jceb/vim-orgmode][file:https://codecov.io/gh/jceb/vim-orgmode/branch/master/graph/badge.svg]]
Text outlining and task management for Vim based on [[http://orgmode.org/][Emacs' Org-Mode]].
The idea for this plugin was born by listening to the
[[http://twit.tv/floss136][Floss Weekly podcast]] introducing Emacs Org-Mode.
Org-Mode has a lot of strong features like folding, views (sparse tree) and
scheduling of tasks. These are completed by hyperlinks, tags, todo states,
priorities aso.
vim-orgmode aims at providing the same functionality for Vim.
[[https://github.com/jceb/vim-orgmode/blob/master/examples/mylife.org][file:examples/mylife.gif]]
** Features
Currently vim-orgmode does not support all orgmode features but is quite
usable. Short list of the already supported features:
- Syntax highlighting
- Cycle visibility of headings (folding)
- Navigate between headings
- Edit the structure of the document: add, move, promote, denote headings
and more
- Hyperlinks within vim-orgmode and outside (files, webpages, etc.)
- TODO list management
- Tags for headings
- Lists in alphanumeric and bullet item notation and checkbox support
- Basic date handling
- Export to other formats (via Emacs' Org-Mode)
* Installation and Usage
Installation and usage instructions are found in the file [[doc/orgguide.txt][doc/orgguide.txt]].
* License
Information about the license is found in file [[LICENSE]].
* Changelog
All changes are found in file [[https://github.com/jceb/vim-orgmode/blob/master/CHANGELOG.org][CHANGELOG.org]]

View file

@ -1,4 +0,0 @@
:let g:vimball_home = "."
:e ../files
:execute '%MkVimball!' . g:plugin_name
:q!

View file

@ -1,869 +0,0 @@
vim-orgmode (0.3.0-2) unstable; urgency=low
* update documentation
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 09 Aug 2011 21:13:40 +0200
vim-orgmode (0.3.0-1) unstable; urgency=low
* update documentation
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 09 Aug 2011 08:37:25 +0200
vim-orgmode (0.3.0-0) unstable; urgency=low
* fix completion menu popup that disappeared because of the usage of
vim.command
* closes issue #48
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 09 Aug 2011 08:25:03 +0200
vim-orgmode (0.2.1-25) unstable; urgency=low
* playing around with ftdetect vs. setfiletype
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 08 Aug 2011 08:11:23 +0200
vim-orgmode (0.2.1-24) unstable; urgency=low
* improve implementation of todo state selection (issue #5)
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 07 Aug 2011 19:55:06 +0200
vim-orgmode (0.2.1-23) unstable; urgency=low
* more precise regex for dates - pull request by sotte
* closes issue #52
-- Roman Asendorf <roman.asendorf@gmail.com> Wed, 03 Aug 2011 22:40:48 +0200
vim-orgmode (0.2.1-22) unstable; urgency=low
* implement interactive todo state selection
* closes issue #5
-- Jan Christoph Ebersbach <jceb@e-jc.de> Wed, 03 Aug 2011 22:23:14 +0200
vim-orgmode (0.2.1-21) unstable; urgency=low
* added emacs as suggested package - pull request by sotte
* closes issue #54
-- Roman Asendorf <roman.asendorf@gmail.com> Wed, 03 Aug 2011 21:52:15 +0200
vim-orgmode (0.2.1-20) unstable; urgency=low
* simple export via emacs for pdf and html - pull request by sotte
* closes issue #54
-- Roman Asendorf <roman.asendorf@gmail.com> Wed, 03 Aug 2011 21:43:15 +0200
vim-orgmode (0.2.1-19) unstable; urgency=low
* add orgmode group to au commands in TagProperties plugin
* closes issue #53
-- Jan Christoph Ebersbach <jceb@e-jc.de> Wed, 03 Aug 2011 20:02:08 +0200
vim-orgmode (0.2.1-18) unstable; urgency=low
* allow demotion of first level headings
* closes issue #27
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 01 Aug 2011 21:59:32 +0200
vim-orgmode (0.2.1-17) unstable; urgency=low
* fix encoding issues in Date plugin
-- Jan Christoph Ebersbach <ebersbach@univention.de> Tue, 12 Jul 2011 17:59:41 +0200
vim-orgmode (0.2.1-16) unstable; urgency=low
* update installvba target to also work with older vim version
-- Jan Christoph Ebersbach <ebersbach@univention.de> Mon, 11 Jul 2011 08:23:18 +0200
vim-orgmode (0.2.1-15) unstable; urgency=low
* make switching to the next todo sequence more convenient
* fix issue in offset calculation when old and new state are None
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 09 Jul 2011 17:54:46 +0200
vim-orgmode (0.2.1-14) unstable; urgency=low
* make switching to the next todo sequence more consistent
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 09 Jul 2011 17:38:18 +0200
vim-orgmode (0.2.1-13) unstable; urgency=low
* fix minor issues related to switching to the next todo sequence
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 09 Jul 2011 17:33:56 +0200
vim-orgmode (0.2.1-12) unstable; urgency=low
* add general support for multiple todo sequences
* closes issue #46
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 09 Jul 2011 16:39:49 +0200
vim-orgmode (0.2.1-11) unstable; urgency=low
* update documentation
* update clean target
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 09 Jul 2011 11:29:57 +0200
vim-orgmode (0.2.1-10) unstable; urgency=low
* fix todo tests broken by version 0.2.1-8
* fix DONE result of VimBuffer.get_todo_states.parse_states
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 09 Jul 2011 09:49:07 +0200
vim-orgmode (0.2.1-9) unstable; urgency=low
* fix folded text for headings containing backslashes or double quotes
* closes issue #26
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 08 Jul 2011 23:21:07 +0200
vim-orgmode (0.2.1-8) unstable; urgency=low
* add Document.get_todo_states() and Document.get_all_todo_states()
* don't confuse upper case words at the beginning of a heading with a todo
state
* closes issue #28
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 08 Jul 2011 22:30:29 +0200
vim-orgmode (0.2.1-7) unstable; urgency=low
* fix error in setting tags
* closes issue #25
-- Jan Christoph Ebersbach <ebersbach@univention.de> Mon, 04 Jul 2011 12:56:27 +0200
vim-orgmode (0.2.1-6) unstable; urgency=low
* improve split of heading
* add variable g:org_improve_split_heading to enable/disable improve
the split of headings
* closes issue #24
* change Makefile to be more generic
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 04 Jul 2011 07:54:17 +0200
vim-orgmode (0.2.1-5) unstable; urgency=low
* implement shortcut for moving to the partent's next sibling
* closes issue #22
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 03 Jul 2011 13:21:04 +0200
vim-orgmode (0.2.1-4) unstable; urgency=low
* fix duplication of children when inserting a new heading
* closes issue #20
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 03 Jul 2011 12:43:32 +0200
vim-orgmode (0.2.1-3) unstable; urgency=low
* add support for new vimball file extension .vmb
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 03 Jul 2011 12:27:07 +0200
vim-orgmode (0.2.1-2) unstable; urgency=low
* always start insert mode when adding a new heading
* closes issue #21
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 03 Jul 2011 12:25:20 +0200
vim-orgmode (0.2.1-1) unstable; urgency=low
* make target installvba create the VIMPLUGINDIR before attempting the
installation
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 21:07:54 +0200
vim-orgmode (0.2.1-0) unstable; urgency=low
* add documentation for customizing syntax highlighting
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 19:08:59 +0200
vim-orgmode (0.2.0-6) unstable; urgency=low
* add dependency to clean target to orgmode.vba
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 14:03:18 +0200
vim-orgmode (0.2.0-5) unstable; urgency=low
* add documentation for remapping shortcuts
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 13:47:30 +0200
vim-orgmode (0.2.0-4) unstable; urgency=low
* fix <Plug> names for Todo plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 13:24:07 +0200
vim-orgmode (0.2.0-3) unstable; urgency=low
* fix encoding of todo states set by the Todo plugin (thanks to Daniel Carl
for pointing out the issue)
* add target installvba to locally install orgmode.vba
* cleanup Makefile
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 13:15:34 +0200
vim-orgmode (0.2.0-2) unstable; urgency=low
* add hint for updateing vim-orgmode from a previous version
* move all documentation related to installation and usage to doc/org.txt
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 26 Jun 2011 12:46:55 +0200
vim-orgmode (0.2.0-1) unstable; urgency=low
* minor changes to the build files
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 17:43:48 +0200
vim-orgmode (0.2.0-0) unstable; urgency=low
* remove unused echo command in Makefile
* add vim help file doc/org.txt
* first release
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 17:35:31 +0200
vim-orgmode (0.1.0-89) unstable; urgency=low
* add separate target to generate the vba.gz archive
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 16:47:23 +0200
vim-orgmode (0.1.0-88) unstable; urgency=low
* improve error message in case ditaa is not available
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 16:42:36 +0200
vim-orgmode (0.1.0-87) unstable; urgency=low
* update README and diagram
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 16:38:31 +0200
vim-orgmode (0.1.0-86) unstable; urgency=low
* fix issue in EditStructure._move_heading that caused the current heading
not to be removed from the list of heading
* improve error messages for non-allowed characters in tags or todo states
* allow \t and space in tags because of an automatic replacement by _ later
on
* fix issue when creating the debian package an not all path components
exist
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 16:36:39 +0200
vim-orgmode (0.1.0-85) unstable; urgency=low
* add support and tests for splitting a headings title in insert mode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 15:55:16 +0200
vim-orgmode (0.1.0-84) unstable; urgency=low
* correct test cases for Navigator plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 14:05:17 +0200
vim-orgmode (0.1.0-83) unstable; urgency=low
* remove LoggingWork from loaded plugins
* fix a problem when positioning the cursor on a newly created heading
* fix a problem when positioning the cursor on the first character of a
non-heading line
* fix a problem when indenting non-heading lines in insert mode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 13:13:41 +0200
vim-orgmode (0.1.0-82) unstable; urgency=low
* change global function insert_at_cursor to append text after cursor
* add support for insert mode to insert_at_cursor
* fix traceback in Date plugin caused by conversion to unicode
* change insert date mappings to ,si and ,sa
* add submenu Change Date to Date plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 25 Jun 2011 13:00:54 +0200
vim-orgmode (0.1.0-81) unstable; urgency=low
* fix error in TagsProperties.set_tags when None type object is returned
* change TagsProperties.realign_tags to use VimBuffer.write_heading instead
of VimBuffer.write method
* add convenience function VimBuffer.find_current_heading
* remove trailing spaces when a heading contains a single uppercase word
(pseudo TODO state)
* change Heading.copy to create a completely detached heading even without a
connection to a document
* change Heading.start to reture Heading._orig_start when the heading has no
connection to a document
* add parameter connect_with_document to Document.find_heading
* convert plugins and global functions to use VimBuffer.find_current_heading
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 21 Jun 2011 23:26:25 +0200
vim-orgmode (0.1.0-80) unstable; urgency=low
* update README
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 21 Jun 2011 07:46:04 +0200
vim-orgmode (0.1.0-79) unstable; urgency=low
* implement VimBuffer.write_heading to just update a single heading
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 22:19:00 +0200
vim-orgmode (0.1.0-78) unstable; urgency=low
* fix assignment to vim.current.buffer in test cases
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 15:21:39 +0200
vim-orgmode (0.1.0-77) unstable; urgency=low
* improve memory usage by removing unused document objects
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 14:33:10 +0200
vim-orgmode (0.1.0-76) unstable; urgency=low
* improve speed by implementing a better reuse of document objects
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 14:18:26 +0200
vim-orgmode (0.1.0-75) unstable; urgency=low
* fix issue with tag recognition in headings that contain zero or just one
word
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 14:07:29 +0200
vim-orgmode (0.1.0-74) unstable; urgency=low
* change EditStructure mappings back to using the shift key
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 13:29:50 +0200
vim-orgmode (0.1.0-73) unstable; urgency=low
* fix regression introduced in version 0.1.0-71
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 13:28:43 +0200
vim-orgmode (0.1.0-72) unstable; urgency=low
* change default value of g:org_tag_completion_ignorecase to &ignorecase
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 13:20:55 +0200
vim-orgmode (0.1.0-71) unstable; urgency=low
* convert vim.eval return values to unicode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 19 Jun 2011 13:15:51 +0200
vim-orgmode (0.1.0-70) unstable; urgency=low
* update README
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 18 Jun 2011 19:21:04 +0200
vim-orgmode (0.1.0-69) unstable; urgency=low
* add support for tagbar plugin
* move ctags support to file ftplugin/org.cnf
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 18 Jun 2011 19:15:13 +0200
vim-orgmode (0.1.0-68) unstable; urgency=low
* fix encoding error for plugins that directly access vim.current.buffer
-- Jan Christoph Ebersbach <ebersbach@univention.de> Thu, 16 Jun 2011 12:44:06 +0200
vim-orgmode (0.1.0-67) unstable; urgency=low
* change regex strings to raw strings
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 17 Jun 2011 08:09:23 +0200
vim-orgmode (0.1.0-66) unstable; urgency=low
* remove highlighting group Question from title colors
* fix utf-8 encoding for vim.command calls
-- Jan Christoph Ebersbach <ebersbach@univention.de> Thu, 16 Jun 2011 12:39:46 +0200
vim-orgmode (0.1.0-65) unstable; urgency=low
* fix error when aktivating lazyredraw and hidden for the current buffer
* set commentstring to "# %s"
* fix error when switching buffers to get current changetick
* fix error when running get_document with bufnr 0 that opened to the first
document that was queried instead of return the current document
-- Jan Christoph Ebersbach <ebersbach@univention.de> Wed, 15 Jun 2011 12:42:03 +0200
vim-orgmode (0.1.0-64) unstable; urgency=low
* remove parameter mode from function change_visual_selection
* add more test cases for Navigator plugin, current this plugin is somehow
broken
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 14 Jun 2011 20:30:45 +0200
vim-orgmode (0.1.0-63) unstable; urgency=low
* convert LoggingWork plugin to unicode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 14 Jun 2011 18:47:52 +0200
vim-orgmode (0.1.0-62) unstable; urgency=low
* move initialization of speeddating commands to __init__ method
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 14 Jun 2011 18:45:16 +0200
vim-orgmode (0.1.0-61) unstable; urgency=low
* convert Date plugin to unicode
* correct a typo in mapping for May
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 14 Jun 2011 18:36:18 +0200
vim-orgmode (0.1.0-60) unstable; urgency=low
* add missing counter to test_edit_structure.py
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 14 Jun 2011 18:34:51 +0200
vim-orgmode (0.1.0-59) unstable; urgency=low
* convert Todo plugin to unicode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 14 Jun 2011 18:32:01 +0200
vim-orgmode (0.1.0-58) unstable; urgency=low
* fix indentation of docstring in VimBuffer
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 13 Jun 2011 21:51:16 +0200
vim-orgmode (0.1.0-57) unstable; urgency=low
* convert TagsProperties to liborgmode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 13 Jun 2011 21:48:07 +0200
vim-orgmode (0.1.0-56) unstable; urgency=low
* add missing % when doing string formatting in EditStructure plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 13 Jun 2011 19:27:38 +0200
vim-orgmode (0.1.0-55) unstable; urgency=low
* fix encoding error in keybinding.py when evaluation self.overwrite_exisiting
* convert Hyperlink plugin to unicode
* add hint to current plugin when a traceback occures during initialization
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 13 Jun 2011 19:23:13 +0200
vim-orgmode (0.1.0-54) unstable; urgency=low
* add copy method to Heading class to make a copy of the object
* track orig_start in Document.write method instead of the heading objects
* convert EditStructure plugin to liborgmode
* swap promote/demote meaning
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 13 Jun 2011 18:59:21 +0200
vim-orgmode (0.1.0-53) unstable; urgency=low
* fix performance issue when identing/folding text
* rename method load to init_dom
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 28 May 2011 15:21:58 +0200
vim-orgmode (0.1.0-52) unstable; urgency=low
* fix performance issue by introducing static computation of start value
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 28 May 2011 14:51:38 +0200
vim-orgmode (0.1.0-51) unstable; urgency=low
* add support for multiple color definitions for :foreground and :background
-- Jan Christoph Ebersbach <ebersbach@univention.de> Fri, 20 May 2011 08:29:59 +0200
vim-orgmode (0.1.0-50) unstable; urgency=low
* add support for org-todo-keyword-faces
* add support for nested org-todo-keyword lists
* add descriptions and examples for variables
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 15 May 2011 12:00:41 +0200
vim-orgmode (0.1.0-49) unstable; urgency=low
* general cleanup in syntax file
* add keyword default to all highlighting statements
* add syntax support for comments
* clear highlighting for org_shade_stars group if
g:org_heading_shade_leading_stars is not set
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 14 May 2011 23:33:50 +0200
vim-orgmode (0.1.0-48) unstable; urgency=low
* add syntax support for tables
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 14 May 2011 23:04:46 +0200
vim-orgmode (0.1.0-47) unstable; urgency=low
* add syntax support for DEADLINE and SCHEDULED
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 14 May 2011 21:27:07 +0200
vim-orgmode (0.1.0-46) unstable; urgency=low
* add syntax support for timestamps
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 14 May 2011 21:11:13 +0200
vim-orgmode (0.1.0-45) unstable; urgency=low
* add syntax support for properties
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sat, 14 May 2011 20:52:29 +0200
vim-orgmode (0.1.0-44) unstable; urgency=low
* convert tests to unicode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 13 May 2011 23:39:38 +0200
vim-orgmode (0.1.0-43) unstable; urgency=low
* change comparison of None to "is" instead of "=="
* add function flatten_list to prevent sublists
* add convenience methods get_index_in_parent_list and get_parent_list to Heading class
* add __unicode__ and __str__ methods to Document
* started porting of EditStructure plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 13 May 2011 22:59:41 +0200
vim-orgmode (0.1.0-42) unstable; urgency=low
* fix syntax error in syntax/org.vim
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 13 May 2011 19:30:44 +0200
vim-orgmode (0.1.0-41) unstable; urgency=low
* replace hbsitz's org syntax file
* change highlighting to integrate much better with colorschemes
* change license to AGPL 3
-- Jan Christoph Ebersbach <ebersbach@univention.de> Thu, 12 May 2011 18:46:13 +0200
vim-orgmode (0.1.0-40) unstable; urgency=low
* add tag_column and tabstop implementation to VimBuffer
* rename setting org_tags_column to org_tag_column
* rename setting org_tags_completion_ignorecase to
org_tag_completion_ignorecase
* fix unicode settings in test cases
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 10 May 2011 13:16:35 +0900
vim-orgmode (0.1.0-39) unstable; urgency=low
* fix bug in echo function - use echo command
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 21:17:50 +0900
vim-orgmode (0.1.0-38) unstable; urgency=low
* convert Navigator plugin to unicode and liborgmode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 21:17:17 +0900
vim-orgmode (0.1.0-37) unstable; urgency=low
* change echo function to use vim echo function
* add missing unicode parameter to string in ShowHide keybinding
* enable Misc plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 20:32:22 +0900
vim-orgmode (0.1.0-36) unstable; urgency=low
* convert Misc plugin to unicode and liborgmode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 20:14:04 +0900
vim-orgmode (0.1.0-35) unstable; urgency=low
* fix a bug in ShowHide.toggle_folding when folding the first heading in
document when it doesn't have a child heading
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 19:55:52 +0900
vim-orgmode (0.1.0-34) unstable; urgency=low
* enable tests for ShowHide plugin
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 18:40:11 +0900
vim-orgmode (0.1.0-33) unstable; urgency=low
* optimize update_changedtick to not run through all but just the wanted
buffer
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 18:33:14 +0900
vim-orgmode (0.1.0-32) unstable; urgency=low
* remove debug infomation from liborgmode.py
* add __str__ method for for Heading class
* port base functionality of orgmode to unicode
* echo a message instead of an error when no plugins are definied
* add heading parameter to VimBuffer methods
* add functionality to reuse VimBuffer objects and recognise user changes
* add BufNotInSync exception
* disable all but ShowHide plugin
* port ShowHide plugin to unicode and liborgmode
* port PluginExample to unicode and liborgmode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 18:20:59 +0900
vim-orgmode (0.1.0-31) unstable; urgency=low
* add vim swap files to gitignore list
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 14:29:41 +0900
vim-orgmode (0.1.0-30) unstable; urgency=low
* add support for unicode
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 14:27:37 +0900
vim-orgmode (0.1.0-29) unstable; urgency=low
* remove unsued import from liborgmode
* add heading parameter to VimBuffer.loag function
* update tests to use renamed liborgmode/document files
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 11:49:25 +0900
vim-orgmode (0.1.0-28) unstable; urgency=low
* rename ftplugin/orgmode/liborgmode.py to ftplugin/liborgmode.py
* rename ftplugin/orgmode/vimbuffer.py to ftplugin/orgmode/document.py
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 09 May 2011 11:46:39 +0900
vim-orgmode (0.1.0-27) unstable; urgency=low
* update README
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 06 May 2011 21:40:48 +0900
vim-orgmode (0.1.0-26) unstable; urgency=low
* add load method to documents for initializing the DOM
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 06 May 2011 21:21:39 +0900
vim-orgmode (0.1.0-25) unstable; urgency=low
* fix heading initialization (Heading.parse_heading_from_data) when orig_start == 0
* fix comparing of deleted headings
* fix overwriting a single item in a heading
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 06 May 2011 21:12:49 +0900
vim-orgmode (0.1.0-24) unstable; urgency=low
* add support for tags and todo
* externalize heading create to a separate classmethod
* add all relevant parameters to the heading constructor
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 06 May 2011 20:20:37 +0900
vim-orgmode (0.1.0-23) unstable; urgency=low
* make Document.is_dirty function test all headings not just the first two
levels
* add more tests for replacing headings
-- Jan Christoph Ebersbach <jceb@e-jc.de> Thu, 05 May 2011 21:37:27 +0900
vim-orgmode (0.1.0-22) unstable; urgency=low
* distinguish between heading and body changes
* make writing the VimBuffer more efficient
-- Jan Christoph Ebersbach <jceb@e-jc.de> Thu, 05 May 2011 21:03:28 +0900
vim-orgmode (0.1.0-21) unstable; urgency=low
* use functionality of UserList in MultiPurposeList
-- Jan Christoph Ebersbach <jceb@e-jc.de> Thu, 05 May 2011 20:13:26 +0900
vim-orgmode (0.1.0-20) unstable; urgency=low
* update README
-- Jan Christoph Ebersbach <jceb@e-jc.de> Thu, 05 May 2011 10:51:12 +0900
vim-orgmode (0.1.0-19) unstable; urgency=low
* major refactoring of liborgmode
* tests and plugins are currently broken
-- Jan Christoph Ebersbach <jceb@e-jc.de> Thu, 05 May 2011 10:48:44 +0900
vim-orgmode (0.1.0-18) unstable; urgency=low
* install -D doesn't work on BSD based systems; migrate commands to install -d
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 02 May 2011 15:41:17 +0900
vim-orgmode (0.1.0-17) unstable; urgency=low
* merge date-plugin from sotte
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 02 May 2011 15:40:40 +0900
vim-orgmode (0.1.0-16) unstable; urgency=low
* rename heading.py to liborgmode.py
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 26 Apr 2011 21:55:17 +0900
vim-orgmode (0.1.0-15) unstable; urgency=low
* add variable g:org_syntax_highlight_leading_stars to customize
highlighting of leading stars
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 26 Apr 2011 21:30:31 +0900
vim-orgmode (0.1.0-14) unstable; urgency=low
* merge todo_refactoring from sotte
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 26 Apr 2011 21:16:19 +0900
vim-orgmode (0.1.0-13) unstable; urgency=low
* add documentation in form of a diagram describing the functionality of
vim-orgmode, liborgmode and orgcmd
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 26 Apr 2011 20:41:20 +0900
vim-orgmode (0.1.0-12) unstable; urgency=low
* update todos
-- Jan Christoph Ebersbach <jceb@e-jc.de> Mon, 28 Mar 2011 00:07:37 +0200
vim-orgmode (0.1.0-11) unstable; urgency=low
* move initialization to start method
-- Jan Christoph Ebersbach <jceb@e-jc.de> Thu, 24 Mar 2011 20:39:49 +0100
vim-orgmode (0.1.0-10) unstable; urgency=low
* fix problem with the order of decorators (@classmethod must be first)
* remove silence from
-- Jan Christoph Ebersbach <ebersbach@univention.de> Thu, 24 Mar 2011 17:36:55 +0100
vim-orgmode (0.1.0-9) unstable; urgency=low
* rename update_tag_alignment
-- Jan Christoph Ebersbach <ebersbach@univention.de> Wed, 23 Mar 2011 19:40:44 +0100
vim-orgmode (0.1.0-8) unstable; urgency=low
* make edit tasks update tags alignment
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 22 Mar 2011 22:28:59 +0100
vim-orgmode (0.1.0-7) unstable; urgency=low
* clean up of unused imports
* change a bunch of methods into classmethods
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 22 Mar 2011 22:17:44 +0100
vim-orgmode (0.1.0-6) unstable; urgency=low
* add vim as build dependency
* update Installation and Building information in README
* update todos
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 22 Mar 2011 21:35:02 +0100
vim-orgmode (0.1.0-5) unstable; urgency=low
* fix passing of function arguments
* fix empty links creation
* update todos for Hyperlinks plugin
-- Jan Christoph Ebersbach <ebersbach@univention.de> Mon, 21 Mar 2011 12:35:14 +0100
vim-orgmode (0.1.0-4) unstable; urgency=low
* implement Hyperlinks plugin (closes: #11)
-- Jan Christoph Ebersbach <jceb@e-jc.de> Sun, 20 Mar 2011 00:07:04 +0100
vim-orgmode (0.1.0-3) unstable; urgency=low
* fix syntax issue in PluginExample.py
-- Jan Christoph Ebersbach <jceb@e-jc.de> Fri, 11 Mar 2011 08:47:34 +0100
vim-orgmode (0.1.0-2) unstable; urgency=low
* correct filename of PluginExample.py (closes: #3)
-- Jan Christoph Ebersbach <jceb@e-jc.de> Wed, 09 Mar 2011 22:02:49 +0100
vim-orgmode (0.1.0-1) unstable; urgency=low
* Initial release.
-- Jan Christoph Ebersbach <jceb@e-jc.de> Tue, 22 Feb 2011 22:14:01 +0100

View file

@ -1 +0,0 @@
5

View file

@ -1,14 +0,0 @@
Source: vim-orgmode
Priority: extra
Section: editors
Maintainer: Jan Christoph Ebersbach <jceb@e-jc.de>
Build-Depends: debhelper (>= 7), vim
Standards-Version: 3.7.3
Homepage: http://www.e-jc.de/
Package: vim-orgmode
Architecture: all
Depends: python, vim-common, vim
Suggests: emacs
Description: Clone of Org-mode for Vim
Clone of Org-mode for Vim

View file

@ -1,28 +0,0 @@
Copyright (C) 2010,2011 Jan Christoph Ebersbach
http://www.e-jc.de/
All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
Binary versions of this file provided by Univention to you as
well as other copyrighted, protected or trademarked materials like
Logos, graphics, fonts, specific documentations and configurations,
cryptographic keys etc. are subject to a license agreement between
you and Univention.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Except file syntax/org.vim which was copied from Herbert Sitz and
changed later on by Jan Christoph Ebersbach.

View file

@ -1 +0,0 @@
usr/share/vim/addons

View file

@ -1,2 +0,0 @@
README.org
LICENSE

View file

@ -1 +0,0 @@
examples/plugins/PluginExample.py

View file

@ -1,11 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
DESTDIR=$(CURDIR)/debian/vim-orgmode
ADDONSDIR=/usr/share/vim/addons
override_dh_auto_install:
dh_auto_install -- DESTDIR=$(DESTDIR) VIMDIR=$(ADDONSDIR)
%:
dh $@

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
diagram: diagram.png
diagram.png: diagram.txt
if [ -n "$(shell which ditaa)" ]; then ditaa $^ $@; elif [ -f ditaa0_9.jar ]; then java -jar ditaa0_9.jar $^ $@; else echo "Unable to find ditaa, please install ditaa or download ditaa0_9.jar (http://ditaa.sf.net/)and place it in folder documentation"; exit 1 ; fi
clean:
@rm -f diagram.png
.PHONY: diagram clean

View file

@ -1,75 +0,0 @@
/------------------------------\ +-----------------------------------+
| Legend | | vim-orgmode |
| cCCC | | cBLU |
| | | o support for plugins |
| | | o plugins implement orgmode |
+--------------+---------------+ | functionality in vim |
| vim-orgmode | liborgmode | | o mainly plugins implement |
| cBLU | cYEL | | keybindings for interactively |
| | | | changing org-mode files |
| | | | |
+--------------+---------------+ | |
| orgcmd | doesn't exist | +---+-------------------------------+
| cRED | yet | |1
| | | |
| | | |
\--------------+-=-------------/ |x
v
+-----------------------------------+
| Plugins |
| cBLU |
| o manipulate headings |
| o change tags, todo states, lists |
| o integrate with orgcmd |
| o reusable functionality doesn't |
| belong here but into liborgmode!|
| o timer, time tracking |
| |
| |
+---+-------------------------------+ +------------+
| | VimBuffer |
| | {d} |
| /---------+ cBLU |
| | | |
v | +------------+
+-----------------------------------+ +---------------++
1 | Document | | Extend Document| +-=------------+
/-----+ cYEL |<-------+ cYEL | |+------------+|
| | o represents an org-mode document | | o abstraction | || file ||
| | o contains links to other | | of data/file | || {d} ||
| x | documents | | access +-------+| cYEL ||
\---->| o contains meta information | | o read | || ||
| o contains headings | | o write | |+------------+|
| | | | +--------------+
| | | |
| | +---------------++ +-=------------+
+----+------------------------------+ | |+------------+|
|1 ^ | || stdin/ ||
| | \--------+| stdout ||
| | || {d} ||
| \------------\ || cRED ||
|x | |+------------+|
v | +--------------+
+-----------------------------------+ +-+=--------------------------+
1 | Heading | |+---------------------------+|
/-----+ cYEL | || orgcmd ||
| | o represents a single heading | || cRED ||
| | o contains links to other headings| || o implement command line ||
| x | o parent heading | || tool for processing org ||
\---->| o siblings | || files ||
| o children | || o provide output filter ||
| | || o convert org-mode docs ||
| o title | || to other formats ||
| o level | |+---------------------------+|
| o body | +-----------------------------+
| o tags |
| o todo state |
| o closing date |
| o scheduled date |
| o priority |
| o item lists (class hierarchy) |
| |
| |
| |
+-----------------------------------+

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

View file

@ -1,26 +0,0 @@
* My Life in plain text
- [X] birth
- [-] life [50%]
- [X] use vim
- [ ] get everything else done
* Write minutes of last meeting <2014-08-08 Fri> :work:
** DONE John said
this
** TODO Mary said
that
** WAITING What did Mark say?
[[http://example.com/here/is/the/recording][1st recording]]
[[http://example.com/here/is/the/recording][2nd recording]]
* Some folding headline 1 :one:
** Folded
*** Even more folded
* Some folding headline 2
** Folded :two:
*** Even more folded
* Some folding headline 3
** Folded
*** Even more folded :three:
* Some folding headline 4
** Folded
*** Even more folded
completely unfolded

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

View file

@ -1,53 +0,0 @@
# -*- coding: utf-8 -*-
from orgmode import echo, echom, echoe, ORGMODE, apply_count, repeat
from orgmode.menu import Submenu, Separator, ActionEntry
from orgmode.keybinding import Keybinding, Plug, Command
import vim
class Example(object):
u"""
Example plugin.
TODO: Extend this doc!
"""
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Example')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
@classmethod
def action(cls):
u"""
Some kind of action.
:returns: TODO
"""
pass
def register(self):
u"""
Registration of the plugin.
Key bindings and other initialization should be done here.
"""
# an Action menu entry which binds "keybinding" to action ":action"
self.commands.append(Command(u'OrgActionCommand',
u':py ORGMODE.plugins["Example"].action()'))
self.keybindings.append(Keybinding(u'keybinding',
Plug(u'OrgAction', self.commands[-1])))
self.menu + ActionEntry(u'&Action', self.keybindings[-1])
# vim: set noexpandtab:

View file

@ -1,2 +0,0 @@
autocmd BufNewFile,BufRead *.org setfiletype org
"autocmd BufNewFile,BufReadPost org:todo* setfiletype orgtodo

View file

@ -1,5 +0,0 @@
--langdef=org
--langmap=org:.org
--regex-org=/^(\*+)[[:space:]]+(.*)([[:space:]]+:[^\t ]*:)?$/\1 \2/s,sections/
--regex-org=/\[\[([^][]+)\]\]/\1/h,hyperlinks/
--regex-org=/\[\[[^][]+\]\[([^][]+)\]\]/\1/h,hyperlinks/

View file

@ -1,169 +0,0 @@
" org.vim -- Text outlining and task management for Vim based on Emacs' Org-Mode
" @Author : Jan Christoph Ebersbach (jceb@e-jc.de)
" @License : AGPL3 (see http://www.gnu.org/licenses/agpl.txt)
" @Created : 2010-10-03
" @Last Modified: Tue 13. Sep 2011 20:52:57 +0200 CEST
" @Revision : 0.4
" vi: ft=vim:tw=80:sw=4:ts=4:fdm=marker
if v:version > 702
if has('python3')
let s:py_version = 'python3 '
let s:py_env = 'python3 << EOF'
elseif has('python')
let s:py_version = 'python '
let s:py_env = 'python << EOF'
else
echoerr "Unable to start orgmode. Orgmode depends on Vim >= 7.3 with Python support complied in."
finish
endif
else
echoerr "Unable to start orgmode. Orgmode depends on Vim >= 7.3 with Python support complied in."
finish
endif
" Init buffer for file {{{1
if ! exists('b:did_ftplugin')
" default emacs settings
setlocal comments=fb:*,b:#,fb:-
setlocal commentstring=#\ %s
setlocal conceallevel=2 concealcursor=nc
" original emacs settings are: setlocal tabstop=6 shiftwidth=6, but because
" of checkbox indentation the following settings are used:
setlocal tabstop=6 shiftwidth=6
if exists('g:org_tag_column')
exe 'setlocal textwidth='.g:org_tag_column
else
setlocal textwidth=77
endif
" expand tab for counting level of checkbox
setlocal expandtab
" enable % for angle brackets < >
setlocal matchpairs+=<:>
" register keybindings if they don't have been registered before
if exists("g:loaded_org")
exe s:py_version . 'ORGMODE.register_keybindings()'
endif
endif
" Load orgmode just once {{{1
if &cp || exists("g:loaded_org")
finish
endif
let g:loaded_org = 1
" Default org plugins that will be loaded (in the given order) {{{2
if ! exists('g:org_plugins') && ! exists('b:org_plugins')
let g:org_plugins = ['ShowHide', '|', 'Navigator', 'EditStructure', 'EditCheckbox', '|', 'Hyperlinks', '|', 'Todo', 'TagsProperties', 'Date', 'Agenda', 'Misc', '|', 'Export']
endif
" Default org plugin settings {{{2
" What does this do?
if ! exists('g:org_syntax_highlight_leading_stars') && ! exists('b:org_syntax_highlight_leading_stars')
let g:org_syntax_highlight_leading_stars = 1
endif
" setting to conceal aggresively
if ! exists('g:org_aggressive_conceal') && ! exists('b:org_aggressive_conceal')
let g:org_aggressive_conceal = 0
endif
" Defined in separate plugins
" Adding Behavior preference:
" 1: go into insert-mode when new heading/checkbox/plainlist added
" 0: retain original mode when new heading/checkbox/plainlist added
if ! exists('g:org_prefer_insert_mode') && ! exists('b:org_prefer_insert_mode')
let g:org_prefer_insert_mode = 1
endif
" Menu and document handling {{{1
function! <SID>OrgRegisterMenu()
exe s:py_version . 'ORGMODE.register_menu()'
endfunction
function! <SID>OrgUnregisterMenu()
exe s:py_version . 'ORGMODE.unregister_menu()'
endfunction
function! <SID>OrgDeleteUnusedDocument(bufnr)
exe s:py_env
b = int(vim.eval('a:bufnr'))
if b in ORGMODE._documents:
del ORGMODE._documents[b]
EOF
endfunction
" show and hide Org menu depending on the filetype
augroup orgmode
au BufEnter * :if &filetype == "org" | call <SID>OrgRegisterMenu() | endif
au BufLeave * :if &filetype == "org" | call <SID>OrgUnregisterMenu() | endif
au BufDelete * :call <SID>OrgDeleteUnusedDocument(expand('<abuf>'))
augroup END
" Start orgmode {{{1
" Expand our path
exec s:py_env
import vim, os, sys
for p in vim.eval("&runtimepath").split(','):
dname = os.path.join(p, "ftplugin")
if os.path.exists(os.path.join(dname, "orgmode")):
if dname not in sys.path:
sys.path.append(dname)
break
from orgmode._vim import ORGMODE, insert_at_cursor, get_user_input, date_to_str
ORGMODE.start()
from Date import Date
import datetime
EOF
" 3rd Party Plugin Integration {{{1
" * Repeat {{{2
try
call repeat#set()
catch
endtry
" * Tagbar {{{2
let g:tagbar_type_org = {
\ 'ctagstype' : 'org',
\ 'kinds' : [
\ 's:sections',
\ 'h:hyperlinks',
\ ],
\ 'sort' : 0,
\ 'deffile' : expand('<sfile>:p:h') . '/org.cnf'
\ }
" * Taglist {{{2
if exists('g:Tlist_Ctags_Cmd')
" Pass parameters to taglist
let g:tlist_org_settings = 'org;s:section;h:hyperlinks'
let g:Tlist_Ctags_Cmd .= ' --options=' . expand('<sfile>:p:h') . '/org.cnf '
endif
" * Calendar.vim {{{2
fun CalendarAction(day, month, year, week, dir)
let g:org_timestamp = printf("%04d-%02d-%02d Fri", a:year, a:month, a:day)
let datetime_date = printf("datetime.date(%d, %d, %d)", a:year, a:month, a:day)
exe s:py_version . "selected_date = " . datetime_date
" get_user_input
let msg = printf("Inserting %s | Modify date", g:org_timestamp)
exe s:py_version . "modifier = get_user_input('" . msg . "')"
" change date according to user input
exe s:py_version . "newdate = Date._modify_time(selected_date, modifier)"
exe s:py_version . "newdate = date_to_str(newdate)"
" close Calendar
exe "q"
" goto previous window
exe "wincmd p"
exe s:py_version . "timestamp = '" . g:org_timestamp_template . "' % newdate"
exe s:py_version . "insert_at_cursor(timestamp)"
" restore calendar_action
let g:calendar_action = g:org_calendar_action_backup
endf

View file

@ -1 +0,0 @@
# -*- coding: utf-8 -*-

View file

@ -1,411 +0,0 @@
# -*- coding: utf-8 -*-
"""
VIM ORGMODE
~~~~~~~~~~~~
TODO
"""
import imp
import re
import sys
import vim
from datetime import datetime
import orgmode.keybinding
import orgmode.menu
import orgmode.plugins
import orgmode.settings
from orgmode.exceptions import PluginError
from orgmode.vimbuffer import VimBuffer
from orgmode.liborgmode.agenda import AgendaManager
REPEAT_EXISTS = bool(int(vim.eval('exists("*repeat#set()")')))
TAGSPROPERTIES_EXISTS = False
cache_heading = None
from orgmode.py3compat.unicode_compatibility import *
from orgmode.py3compat.encode_compatibility import *
def realign_tags(f):
u"""
Update tag alignment, dependency to TagsProperties plugin!
"""
def r(*args, **kwargs):
global TAGSPROPERTIES_EXISTS
res = f(*args, **kwargs)
if not TAGSPROPERTIES_EXISTS and u'TagsProperties' in ORGMODE.plugins:
TAGSPROPERTIES_EXISTS = True
if TAGSPROPERTIES_EXISTS:
ORGMODE.plugins[u'TagsProperties'].realign_tags()
return res
return r
def repeat(f):
u"""
Integrate with the repeat plugin if available
The decorated function must return the name of the <Plug> command to
execute by the repeat plugin.
"""
def r(*args, **kwargs):
res = f(*args, **kwargs)
if REPEAT_EXISTS and isinstance(res, basestring):
vim.command(u_encode(u'silent! call repeat#set("\\<Plug>%s")' % res))
return res
return r
def apply_count(f):
u"""
Decorator which executes function v:count or v:prevount (not implemented,
yet) times. The decorated function must return a value that evaluates to
True otherwise the function is not repeated.
"""
def r(*args, **kwargs):
count = 0
try:
count = int(vim.eval(u_encode(u'v:count')))
# visual count is not implemented yet
#if not count:
# count = int(vim.eval(u'v:prevcount'.encode(u'utf-8')))
except BaseException as e:
pass
res = f(*args, **kwargs)
count -= 1
while res and count > 0:
f(*args, **kwargs)
count -= 1
return res
return r
def echo(message):
u"""
Print a regular message that will not be visible to the user when
multiple lines are printed
"""
for m in message.split(u'\n'):
vim.command(u_encode(u':echo "%s"' % m))
def echom(message):
u"""
Print a regular message that will be visible to the user, even when
multiple lines are printed
"""
# probably some escaping is needed here
for m in message.split(u'\n'):
vim.command(u_encode(u':echomsg "%s"' % m))
def echoe(message):
u"""
Print an error message. This should only be used for serious errors!
"""
# probably some escaping is needed here
for m in message.split(u'\n'):
vim.command(u_encode(u':echoerr "%s"' % m))
def insert_at_cursor(text, move=True, start_insertmode=False):
u"""Insert text at the position of the cursor.
If move==True move the cursor with the inserted text.
"""
d = ORGMODE.get_document(allow_dirty=True)
line, col = vim.current.window.cursor
_text = d._content[line - 1]
d._content[line - 1] = _text[:col + 1] + text + _text[col + 1:]
if move:
vim.current.window.cursor = (line, col + len(text))
if start_insertmode:
vim.command(u_encode(u'startinsert'))
def get_user_input(message):
u"""Print the message and take input from the user.
Return the input or None if there is no input.
"""
vim.command(u_encode(u'call inputsave()'))
vim.command(u_encode(u"let user_input = input('" + message + u": ')"))
vim.command(u_encode(u'call inputrestore()'))
try:
return u_decode(vim.eval(u_encode(u'user_input')))
except:
return None
def get_bufnumber(bufname):
"""
Return the number of the buffer for the given bufname if it exist;
else None.
"""
for b in vim.buffers:
if b.name == bufname:
return int(b.number)
def get_bufname(bufnr):
"""
Return the name of the buffer for the given bufnr if it exist; else None.
"""
for b in vim.buffers:
if b.number == bufnr:
return b.name
def indent_orgmode():
u""" Set the indent value for the current line in the variable
b:indent_level
Vim prerequisites:
:setlocal indentexpr=Method-which-calls-indent_orgmode
:returns: None
"""
line = int(vim.eval(u_encode(u'v:lnum')))
d = ORGMODE.get_document()
heading = d.current_heading(line - 1)
if heading and line != heading.start_vim:
heading.init_checkboxes()
checkbox = heading.current_checkbox()
level = heading.level + 1
if checkbox:
if line != checkbox.start_vim:
# indent body up to the beginning of the checkbox' text
# if checkbox isn't indented to the proper location, the body
# won't be indented either
level = checkbox.level + len(checkbox.type) + 1 + \
(4 if checkbox.status else 0)
vim.command(u_encode((u'let b:indent_level = %d' % level)))
def fold_text(allow_dirty=False):
u""" Set the fold text
:setlocal foldtext=Method-which-calls-foldtext
:allow_dirty: Perform a query without (re)building the DOM if True
:returns: None
"""
line = int(vim.eval(u_encode(u'v:foldstart')))
d = ORGMODE.get_document(allow_dirty=allow_dirty)
heading = None
if allow_dirty:
heading = d.find_current_heading(line - 1)
else:
heading = d.current_heading(line - 1)
if heading:
str_heading = unicode(heading)
# expand tabs
ts = int(vim.eval(u_encode(u'&ts')))
idx = str_heading.find(u'\t')
if idx != -1:
tabs, spaces = divmod(idx, ts)
str_heading = str_heading.replace(u'\t', u' ' * (ts - spaces), 1)
str_heading = str_heading.replace(u'\t', u' ' * ts)
# Workaround for vim.command seems to break the completion menu
vim.eval(u_encode(u'SetOrgFoldtext("%s...")' % (re.sub(r'\[\[([^[\]]*\]\[)?([^[\]]+)\]\]', r'\2',
str_heading).replace( u'\\', u'\\\\').replace(u'"', u'\\"'), )))
def fold_orgmode(allow_dirty=False):
u""" Set the fold expression/value for the current line in the variable
b:fold_expr
Vim prerequisites:
:setlocal foldmethod=expr
:setlocal foldexpr=Method-which-calls-fold_orgmode
:allow_dirty: Perform a query without (re)building the DOM if True
:returns: None
"""
line = int(vim.eval(u_encode(u'v:lnum')))
d = ORGMODE.get_document(allow_dirty=allow_dirty)
heading = None
if allow_dirty:
heading = d.find_current_heading(line - 1)
else:
heading = d.current_heading(line - 1)
# if cache_heading != heading:
# heading.init_checkboxes()
# checkbox = heading.current_checkbox()
# cache_heading = heading
if heading:
# if checkbox:
# vim.command((u'let b:fold_expr = ">%d"' % heading.level + checkbox.level).encode(u'utf-8'))
if 0:
pass
elif line == heading.start_vim:
vim.command(u_encode(u'let b:fold_expr = ">%d"' % heading.level))
#elif line == heading.end_vim:
# vim.command((u'let b:fold_expr = "<%d"' % heading.level).encode(u'utf-8'))
# end_of_last_child_vim is a performance junky and is actually not needed
#elif line == heading.end_of_last_child_vim:
# vim.command((u'let b:fold_expr = "<%d"' % heading.level).encode(u'utf-8'))
else:
vim.command(u_encode(u'let b:fold_expr = %d' % heading.level))
def date_to_str(date):
if isinstance(date, datetime):
date = date.strftime(u_decode(u_encode(u'%Y-%m-%d %a %H:%M')))
else:
date = date.strftime(u_decode(u_encode(u'%Y-%m-%d %a')))
return date
class OrgMode(object):
u""" Vim Buffer """
def __init__(self):
object.__init__(self)
self.debug = bool(int(orgmode.settings.get(u'org_debug', False)))
self.orgmenu = orgmode.menu.Submenu(u'&Org')
self._plugins = {}
# list of vim buffer objects
self._documents = {}
# agenda manager
self.agenda_manager = AgendaManager()
def get_document(self, bufnr=0, allow_dirty=False):
""" Retrieve instance of vim buffer document. This Document should be
used for manipulating the vim buffer.
:bufnr: Retrieve document with bufnr
:allow_dirty: Allow the retrieved document to be dirty
:returns: vim buffer instance
"""
if bufnr == 0:
bufnr = vim.current.buffer.number
if bufnr in self._documents:
if allow_dirty or self._documents[bufnr].is_insync:
return self._documents[bufnr]
self._documents[bufnr] = VimBuffer(bufnr).init_dom()
return self._documents[bufnr]
@property
def plugins(self):
return self._plugins.copy()
@orgmode.keybinding.register_keybindings
@orgmode.keybinding.register_commands
@orgmode.menu.register_menu
def register_plugin(self, plugin):
if not isinstance(plugin, basestring):
raise ValueError(u'Parameter plugin is not of type string')
if plugin == u'|':
self.orgmenu + orgmode.menu.Separator()
self.orgmenu.children[-1].create()
return
if plugin in self._plugins:
raise PluginError(u'Plugin %s has already been loaded')
# a python module
module = None
# actual plugin class
_class = None
# locate module and initialize plugin class
try:
module = imp.find_module(plugin, orgmode.plugins.__path__)
except ImportError as e:
echom(u'Plugin not found: %s' % plugin)
if self.debug:
raise e
return
if not module:
echom(u'Plugin not found: %s' % plugin)
return
try:
module = imp.load_module(plugin, *module)
if not hasattr(module, plugin):
echoe(u'Unable to find plugin: %s' % plugin)
if self.debug:
raise PluginError(u'Unable to find class %s' % plugin)
return
_class = getattr(module, plugin)
self._plugins[plugin] = _class()
self._plugins[plugin].register()
if self.debug:
echo(u'Plugin registered: %s' % plugin)
return self._plugins[plugin]
except BaseException as e:
echoe(u'Unable to activate plugin: %s' % plugin)
echoe(u"%s" % e)
if self.debug:
import traceback
echoe(traceback.format_exc())
def register_keybindings(self):
@orgmode.keybinding.register_keybindings
def dummy(plugin):
return plugin
if sys.version_info < (3, ):
for p in self.plugins.itervalues():
dummy(p)
else:
for p in self.plugins.values():
dummy(p)
def register_menu(self):
self.orgmenu.create()
def unregister_menu(self):
vim.command(u_encode(u'silent! aunmenu Org'))
def start(self):
u""" Start orgmode and load all requested plugins
"""
plugins = orgmode.settings.get(u"org_plugins")
if not plugins:
echom(u'orgmode: No plugins registered.')
if isinstance(plugins, basestring):
try:
self.register_plugin(plugins)
except BaseException as e:
import traceback
traceback.print_exc()
elif isinstance(plugins, list) or \
isinstance(plugins, tuple):
for p in plugins:
try:
self.register_plugin(p)
except BaseException as e:
echoe('Error in %s plugin:' % p)
import traceback
traceback.print_exc()
return plugins
ORGMODE = OrgMode()
# vim: set noexpandtab:

View file

@ -1,230 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(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/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/orgmode.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/orgmode.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/orgmode"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/orgmode"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."

View file

@ -1,387 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# orgmode documentation build configuration file, created by
# sphinx-quickstart on Sat May 21 15:51:55 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
import mock
# Mock vim
MOCK_MODULES = ['vim']
for m in MOCK_MODULES:
sys.modules[m] = mock.Mock()
import vim
vim.eval = mock.MagicMock(return_value=1)
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('../..'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.viewcode',
'sphinx.ext.doctest',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
]
# Napoleon config
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_private_with_doc = True
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = True
napoleon_use_rtype = True
# Add any paths that contain templates here, relative to this directory.
#templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'orgmode'
copyright = '2016, Author'
author = 'Author'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = ''
# The full version, including alpha/beta/rc tags.
release = ''
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
html_title = 'orgmode v0.5'
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'orgmodedoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'orgmode.tex', 'orgmode Documentation',
'Author', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'orgmode', 'orgmode Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'orgmode', 'orgmode Documentation',
author, 'orgmode', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# -- Options for Epub output ----------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# The basename for the epub file. It defaults to the project name.
#epub_basename = project
# The HTML theme for the epub output. Since the default themes are not
# optimized for small screen space, using the same theme for HTML and epub
# output is usually not wise. This defaults to 'epub', a theme designed to save
# visual space.
#epub_theme = 'epub'
# The language of the text. It defaults to the language option
# or 'en' if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# A tuple containing the cover image and cover page html template filenames.
#epub_cover = ()
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
#epub_guide = ()
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# HTML files that should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
# Choose between 'default' and 'includehidden'.
#epub_tocscope = 'default'
# Fix unsupported image types using the Pillow.
#epub_fix_images = False
# Scale large images.
#epub_max_image_width = 0
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#epub_show_urls = 'inline'
# If false, no index is generated.
#epub_use_index = True

View file

@ -1,22 +0,0 @@
.. orgmode documentation master file, created by
sphinx-quickstart on Sat May 21 16:35:00 2016.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to orgmode's documentation!
===================================
Contents:
.. toctree::
:maxdepth: 4
orgmode
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View file

@ -1,281 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. epub3 to make an epub3
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
echo. dummy to check syntax errors of document sources
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\orgmode.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\orgmode.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "epub3" (
%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
if "%1" == "dummy" (
%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
if errorlevel 1 exit /b 1
echo.
echo.Build finished. Dummy builder generates no files.
goto end
)
:end

View file

@ -1,78 +0,0 @@
orgmode.liborgmode package
==========================
Submodules
----------
orgmode.liborgmode.agenda module
--------------------------------
.. automodule:: orgmode.liborgmode.agenda
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.agendafilter module
--------------------------------------
.. automodule:: orgmode.liborgmode.agendafilter
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.base module
------------------------------
.. automodule:: orgmode.liborgmode.base
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.checkboxes module
------------------------------------
.. automodule:: orgmode.liborgmode.checkboxes
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.documents module
-----------------------------------
.. automodule:: orgmode.liborgmode.documents
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.dom_obj module
---------------------------------
.. automodule:: orgmode.liborgmode.dom_obj
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.headings module
----------------------------------
.. automodule:: orgmode.liborgmode.headings
:members:
:undoc-members:
:show-inheritance:
orgmode.liborgmode.orgdate module
---------------------------------
.. automodule:: orgmode.liborgmode.orgdate
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: orgmode.liborgmode
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,110 +0,0 @@
orgmode.plugins package
=======================
Submodules
----------
orgmode.plugins.Agenda module
-----------------------------
.. automodule:: orgmode.plugins.Agenda
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.Date module
---------------------------
.. automodule:: orgmode.plugins.Date
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.EditCheckbox module
-----------------------------------
.. automodule:: orgmode.plugins.EditCheckbox
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.EditStructure module
------------------------------------
.. automodule:: orgmode.plugins.EditStructure
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.Export module
-----------------------------
.. automodule:: orgmode.plugins.Export
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.Hyperlinks module
---------------------------------
.. automodule:: orgmode.plugins.Hyperlinks
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.LoggingWork module
----------------------------------
.. automodule:: orgmode.plugins.LoggingWork
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.Misc module
---------------------------
.. automodule:: orgmode.plugins.Misc
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.Navigator module
--------------------------------
.. automodule:: orgmode.plugins.Navigator
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.ShowHide module
-------------------------------
.. automodule:: orgmode.plugins.ShowHide
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.TagsProperties module
-------------------------------------
.. automodule:: orgmode.plugins.TagsProperties
:members:
:undoc-members:
:show-inheritance:
orgmode.plugins.Todo module
---------------------------
.. automodule:: orgmode.plugins.Todo
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: orgmode.plugins
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,46 +0,0 @@
orgmode.py3compat package
=========================
Submodules
----------
orgmode.py3compat.encode_compatibility module
---------------------------------------------
.. automodule:: orgmode.py3compat.encode_compatibility
:members:
:undoc-members:
:show-inheritance:
orgmode.py3compat.py_py3_string module
--------------------------------------
.. automodule:: orgmode.py3compat.py_py3_string
:members:
:undoc-members:
:show-inheritance:
orgmode.py3compat.unicode_compatibility module
----------------------------------------------
.. automodule:: orgmode.py3compat.unicode_compatibility
:members:
:undoc-members:
:show-inheritance:
orgmode.py3compat.xrange_compatibility module
---------------------------------------------
.. automodule:: orgmode.py3compat.xrange_compatibility
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: orgmode.py3compat
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,71 +0,0 @@
orgmode package
===============
Subpackages
-----------
.. toctree::
orgmode.liborgmode
orgmode.plugins
orgmode.py3compat
Submodules
----------
orgmode._vim module
-------------------
.. automodule:: orgmode._vim
:members:
:undoc-members:
:show-inheritance:
orgmode.exceptions module
-------------------------
.. automodule:: orgmode.exceptions
:members:
:undoc-members:
:show-inheritance:
orgmode.keybinding module
-------------------------
.. automodule:: orgmode.keybinding
:members:
:undoc-members:
:show-inheritance:
orgmode.menu module
-------------------
.. automodule:: orgmode.menu
:members:
:undoc-members:
:show-inheritance:
orgmode.settings module
-----------------------
.. automodule:: orgmode.settings
:members:
:undoc-members:
:show-inheritance:
orgmode.vimbuffer module
------------------------
.. automodule:: orgmode.vimbuffer
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: orgmode
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,23 +0,0 @@
# -*- coding: utf-8 -*-
class PluginError(BaseException):
def __init__(self, message):
BaseException.__init__(self, message)
class BufferNotFound(BaseException):
def __init__(self, message):
BaseException.__init__(self, message)
class BufferNotInSync(BaseException):
def __init__(self, message):
BaseException.__init__(self, message)
class HeadingDomError(BaseException):
def __init__(self, message):
BaseException.__init__(self, message)
# vim: set noexpandtab:

View file

@ -1,217 +0,0 @@
# -*- coding: utf-8 -*-
import vim
MODE_ALL = u'a'
MODE_NORMAL = u'n'
MODE_VISUAL = u'v'
MODE_INSERT = u'i'
MODE_OPERATOR = u'o'
OPTION_BUFFER_ONLY = u'<buffer>'
OPTION_SLIENT = u'<silent>'
from orgmode.py3compat.encode_compatibility import *
def _register(f, name):
def r(*args, **kwargs):
p = f(*args, **kwargs)
if hasattr(p, name) and isinstance(getattr(p, name), list):
for i in getattr(p, name):
i.create()
return p
return r
def register_keybindings(f):
return _register(f, u'keybindings')
def register_commands(f):
return _register(f, u'commands')
class Command(object):
u""" A vim command """
def __init__(self, name, command, arguments=u'0', complete=None, overwrite_exisiting=False):
u"""
:name: The name of command, first character must be uppercase
:command: The actual command that is executed
:arguments: See :h :command-nargs, only the arguments need to be specified
:complete: See :h :command-completion, only the completion arguments need to be specified
"""
object.__init__(self)
self._name = name
self._command = command
self._arguments = arguments
self._complete = complete
self._overwrite_exisiting = overwrite_exisiting
def __unicode__(self):
return u':%s<CR>' % self.name
def __str__(self):
return u_encode(self.__unicode__())
@property
def name(self):
return self._name
@property
def command(self):
return self._command
@property
def arguments(self):
return self._arguments
@property
def complete(self):
return self._complete
@property
def overwrite_exisiting(self):
return self._overwrite_exisiting
def create(self):
u""" Register/create the command
"""
vim.command(u_encode(':command%(overwrite)s -nargs=%(arguments)s %(complete)s %(name)s %(command)s' %
{u'overwrite': '!' if self.overwrite_exisiting else '',
u'arguments': u_encode(self.arguments),
u'complete': '-complete=%s' % u_encode(self.complete) if self.complete else '',
u'name': self.name,
u'command': self.command}
))
class Plug(object):
u""" Represents a <Plug> to an abitrary command """
def __init__(self, name, command, mode=MODE_NORMAL):
u"""
:name: the name of the <Plug> should be ScriptnameCommandname
:command: the actual command
"""
object.__init__(self)
if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR):
raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR')
self._mode = mode
self.name = name
self.command = command
self.created = False
def __unicode__(self):
return u'<Plug>%s' % self.name
def __str__(self):
return u_encode(self.__unicode__())
def create(self):
if not self.created:
self.created = True
cmd = self._mode
if cmd == MODE_ALL:
cmd = u''
vim.command(u_encode(u':%snoremap %s %s' % (cmd, str(self), self.command)))
@property
def mode(self):
return self._mode
class Keybinding(object):
u""" Representation of a single key binding """
def __init__(self, key, action, mode=None, options=None, remap=True, buffer_only=True, silent=True):
u"""
:key: the key(s) action is bound to
:action: the action triggered by key(s)
:mode: definition in which vim modes the key binding is valid. Should be one of MODE_*
:option: list of other options like <silent>, <buffer> ...
:repmap: allow or disallow nested mapping
:buffer_only: define the key binding only for the current buffer
"""
object.__init__(self)
self._key = key
self._action = action
# grab mode from plug if not set otherwise
if isinstance(self._action, Plug) and not mode:
mode = self._action.mode
if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR):
raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR')
self._mode = mode
self._options = options
if self._options is None:
self._options = []
self._remap = remap
self._buffer_only = buffer_only
self._silent = silent
if self._buffer_only and OPTION_BUFFER_ONLY not in self._options:
self._options.append(OPTION_BUFFER_ONLY)
if self._silent and OPTION_SLIENT not in self._options:
self._options.append(OPTION_SLIENT)
@property
def key(self):
return self._key
@property
def action(self):
return str(self._action)
@property
def mode(self):
return self._mode
@property
def options(self):
return self._options[:]
@property
def remap(self):
return self._remap
@property
def buffer_only(self):
return self._buffer_only
@property
def silent(self):
return self._silent
def create(self):
from orgmode._vim import ORGMODE, echom
cmd = self._mode
if cmd == MODE_ALL:
cmd = u''
if not self._remap:
cmd += u'nore'
try:
create_mapping = True
if isinstance(self._action, Plug):
# create plug
self._action.create()
if int(vim.eval(u_encode(u'hasmapto("%s")' % (self._action, )))):
create_mapping = False
if isinstance(self._action, Command):
# create command
self._action.create()
if create_mapping:
vim.command(u_encode(u':%smap %s %s %s' % (cmd, u' '.join(self._options), self._key, self._action)))
except BaseException as e:
if ORGMODE.debug:
echom(u'Failed to register key binding %s %s' % (self._key, self._action))
# vim: set noexpandtab:

View file

@ -1 +0,0 @@
# -*- coding: utf-8 -*-

View file

@ -1,63 +0,0 @@
# -*- coding: utf-8 -*-
u"""
Agenda
~~~~~~~~~~~~~~~~~~
The agenda is one of the main concepts of orgmode. It allows to
collect TODO items from multiple org documents in an agenda view.
Features:
* filtering
* sorting
"""
from orgmode.liborgmode.agendafilter import filter_items
from orgmode.liborgmode.agendafilter import is_within_week_and_active_todo
from orgmode.liborgmode.agendafilter import contains_active_todo
from orgmode.liborgmode.agendafilter import contains_active_date
class AgendaManager(object):
u"""Simple parsing of Documents to create an agenda."""
# TODO Move filters in this file, they do the same thing
def __init__(self):
super(AgendaManager, self).__init__()
def get_todo(self, documents):
u"""
Get the todo agenda for the given documents (list of document).
"""
filtered = []
for document in iter(documents):
# filter and return headings
filtered.extend(filter_items(document.all_headings(),
[contains_active_todo]))
return sorted(filtered)
def get_next_week_and_active_todo(self, documents):
u"""
Get the agenda for next week for the given documents (list of
document).
"""
filtered = []
for document in iter(documents):
# filter and return headings
filtered.extend(filter_items(document.all_headings(),
[is_within_week_and_active_todo]))
return sorted(filtered)
def get_timestamped_items(self, documents):
u"""
Get all time-stamped items in a time-sorted way for the given
documents (list of document).
"""
filtered = []
for document in iter(documents):
# filter and return headings
filtered.extend(filter_items(document.all_headings(),
[contains_active_date]))
return sorted(filtered)
# vim: set noexpandtab:

View file

@ -1,93 +0,0 @@
# -*- coding: utf-8 -*-
u"""
agendafilter
~~~~~~~~~~~~~~~~
AgendaFilter contains all the filters that can be applied to create the
agenda.
All functions except filter_items() in the module are filters. Given a
heading they return if the heading meets the critera of the filter.
The function filter_items() can combine different filters and only returns
the filtered headings.
"""
from datetime import datetime
from datetime import timedelta
try:
from itertools import ifilter as filter
except:
pass
def filter_items(headings, filters):
u""" Filter the given headings.
Args:
headings (list): Contains headings
filters (list): Filters that will be applied. All functions in
this module (except this function) are filters.
Returns:
filter iterator: Headings which were not filtered.
Examples:
>>> filtered = filter_items(headings, [contains_active_date,
contains_active_todo])
"""
filtered = headings
for f in filters:
filtered = filter(f, filtered)
return filtered
def is_within_week(heading):
u""" Test if headings date is withing a week
Returns:
bool: True if the date in the deading is within a week in the future (or
older False otherwise.
"""
if contains_active_date(heading):
next_week = datetime.today() + timedelta(days=7)
if heading.active_date < next_week:
return True
def is_within_week_and_active_todo(heading):
u"""
Returns:
bool: True if heading contains an active TODO and the date is within a
week.
"""
return is_within_week(heading) and contains_active_todo(heading)
def contains_active_todo(heading):
u"""
Returns:
bool: True if heading contains an active TODO.
"""
# TODO make this more efficient by checking some val and not calling the
# function
# TODO why is this import failing at top level? circular dependecy...
from orgmode._vim import ORGMODE
active = []
for act in ORGMODE.get_document().get_todo_states():
active.extend(act[0])
return heading.todo in active
def contains_active_date(heading):
u"""
Returns:
bool: True if heading contains an active date.
"""
return not(heading.active_date is None)
# vim: set noexpandtab:

View file

@ -1,190 +0,0 @@
# -*- coding: utf-8 -*-
"""
base
~~~~~~~~~~
Here are some really basic data structures that are used throughout
the liborgmode.
"""
try:
from collections import UserList
except:
from UserList import UserList
import collections
import sys
from orgmode.py3compat.unicode_compatibility import *
def flatten_list(lst):
""" Flattens a list
Args:
lst (iterable): An iterable that will is non-flat
Returns:
list: Flat list
"""
# TODO write tests
def gen_lst(item):
if isinstance(item, basestring) or isinstance(item, bytes):
yield item
elif isinstance(item, collections.Iterable):
# yield from would be so nice... but c'est la vie
for val in item:
for final in gen_lst(val):
yield final
else:
yield item
return [i for i in gen_lst(lst)]
class Direction():
u"""
Direction is used to indicate the direction of certain actions.
Example: it defines the direction headings get parted in.
"""
FORWARD = 1
BACKWARD = 2
class MultiPurposeList(UserList):
u"""
A Multi Purpose List is a list that calls a user defined hook on
change. The implementation is very basic - the hook is called without any
parameters. Otherwise the Multi Purpose List can be used like any other
list.
The member element "data" can be used to fill the list without causing the
list to be marked dirty. This should only be used during initialization!
"""
def __init__(self, initlist=None, on_change=None):
UserList.__init__(self, initlist)
self._on_change = on_change
def _changed(self):
u""" Call hook """
if callable(self._on_change):
self._on_change()
def __setitem__(self, i, item):
if sys.version_info < (3, ) and isinstance(i, slice):
start, stop, _ = i.indices(len(self))
UserList.__setslice__(self, start, stop, item)
else:
UserList.__setitem__(self, i, item)
self._changed()
def __delitem__(self, i):
if sys.version_info < (3, ) and isinstance(i, slice):
start, stop, _ = i.indices(len(self))
UserList.__delslice__(self, start, stop)
else:
UserList.__delitem__(self, i)
self._changed()
def __getitem__(self, i):
if sys.version_info < (3, ):
if isinstance(i, slice):
# TODO Return just a list. Why?
return [self[i] for i in range(*i.indices(len(self)))]
# return UserList([self[i] for i in range(*i.indices(len(self)))])
return UserList.__getitem__(self, i)
# NOTE: These wrappers are necessary because of python 2
def __setslice__(self, i, j, other):
self.__setitem__(slice(i, j), other)
def __delslice__(self, i, j):
self.__delitem__(slice(i, j))
def __getslice__(self, i, j):
return self.__getitem__(slice(i, j))
def __iadd__(self, other):
res = UserList.__iadd__(self, other)
self._changed()
return res
def __imul__(self, n):
res = UserList.__imul__(self, n)
self._changed()
return res
def append(self, item):
UserList.append(self, item)
self._changed()
def insert(self, i, item):
UserList.insert(self, i, item)
self._changed()
def pop(self, i=-1):
item = self[i]
del self[i]
return item
def remove(self, item):
self.__delitem__(self.index(item))
def reverse(self):
UserList.reverse(self)
self._changed()
def sort(self, *args, **kwds):
UserList.sort(self, *args, **kwds)
self._changed()
def extend(self, other):
UserList.extend(self, other)
self._changed()
def get_domobj_range(content=[], position=0, direction=Direction.FORWARD, identify_fun=None):
u"""
Get the start and end line number of the dom obj lines from content.
:content: String to be recognized dom obj
:positon: Line number in content
:direction: Search direction
:identify_fun: A identify function to recognize dom obj(Heading, Checkbox) title string.
:return: Start and end line number for the recognized dom obj.
"""
len_cb = len(content)
if position < 0 or position > len_cb:
return (None, None)
tmp_line = position
start = None
end = None
if direction == Direction.FORWARD:
while tmp_line < len_cb:
if identify_fun(content[tmp_line]) is not None:
if start is None:
start = tmp_line
elif end is None:
end = tmp_line - 1
if start is not None and end is not None:
break
tmp_line += 1
else:
while tmp_line >= 0 and tmp_line < len_cb:
if identify_fun(content[tmp_line]) is not None:
if start is None:
start = tmp_line
elif end is None:
end = tmp_line - 1
if start is not None and end is not None:
break
tmp_line -= 1 if start is None else -1
return (start, end)
# vim: set noexpandtab:

View file

@ -1,406 +0,0 @@
# -*- coding: utf-8 -*-
"""
checkboxes
~~~~~~~~~~
TODO: explain this :)
"""
import re
try:
from collections import UserList
except:
from UserList import UserList
import vim
from orgmode.liborgmode.base import MultiPurposeList, flatten_list
from orgmode.liborgmode.orgdate import OrgTimeRange
from orgmode.liborgmode.orgdate import get_orgdate
from orgmode.liborgmode.dom_obj import DomObj, DomObjList, REGEX_SUBTASK, REGEX_SUBTASK_PERCENT, REGEX_HEADING, REGEX_CHECKBOX
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *
class Checkbox(DomObj):
u""" Structural checkbox object """
STATUS_ON = u'[X]'
STATUS_OFF = u'[ ]'
# intermediate status
STATUS_INT = u'[-]'
def __init__(self, level=1, type=u'-', title=u'', status=u'[ ]', body=None):
u"""
:level: Indent level of the checkbox
:type: Type of the checkbox list (-, +, *)
:title: Title of the checkbox
:status: Status of the checkbox ([ ], [X], [-])
:body: Body of the checkbox
"""
DomObj.__init__(self, level=level, title=title, body=body)
# heading
self._heading = None
self._children = CheckboxList(obj=self)
self._dirty_checkbox = False
# list type
self._type = u'-'
if type:
self.type = type
# status
self._status = Checkbox.STATUS_OFF
if status:
self.status = status
def __unicode__(self):
return u' ' * self.level + self.type + u' ' + \
(self.status + u' ' if self.status else u'') + self.title
def __str__(self):
return u_encode(self.__unicode__())
def __len__(self):
# 1 is for the heading's title
return 1 + len(self.body)
def copy(self, including_children=True, parent=None):
u"""
Create a copy of the current checkbox. The checkbox will be completely
detached and not even belong to a document anymore.
:including_children: If True a copy of all children is create as
well. If False the returned checkbox doesn't
have any children.
:parent: Don't use this parameter. It's set
automatically.
"""
checkbox = self.__class__(
level=self.level, title=self.title,
body=self.body[:])
if parent:
parent.children.append(checkbox)
if including_children and self.children:
for item in self.children:
item.copy(
including_children=including_children,
parent=checkbox)
checkbox._orig_start = self._orig_start
checkbox._orig_len = self._orig_len
checkbox._dirty_heading = self.is_dirty_checkbox
return checkbox
@classmethod
def parse_checkbox_from_data(cls, data, heading=None, orig_start=None):
u""" Construct a new checkbox from the provided data
:data: List of lines
:heading: The heading object this checkbox belongs to
:orig_start: The original start of the heading in case it was read
from a document. If orig_start is provided, the
resulting heading will not be marked dirty.
:returns: The newly created checkbox
"""
def parse_title(heading_line):
# checkbox is not heading
if REGEX_HEADING.match(heading_line) is not None:
return None
m = REGEX_CHECKBOX.match(heading_line)
if m:
r = m.groupdict()
return (len(r[u'level']), r[u'type'], r[u'status'], r[u'title'])
return None
if not data:
raise ValueError(u'Unable to create checkbox, no data provided.')
# create new checkbox
nc = cls()
nc.level, nc.type, nc.status, nc.title = parse_title(data[0])
nc.body = data[1:]
if orig_start is not None:
nc._dirty_heading = False
nc._dirty_body = False
nc._orig_start = orig_start
nc._orig_len = len(nc)
if heading:
nc._heading = heading
return nc
def update_subtasks(self, total=0, on=0):
if total != 0:
percent = (on * 100) / total
else:
percent = 0
count = "%d/%d" % (on, total)
self.title = REGEX_SUBTASK.sub("[%s]" % (count), self.title)
self.title = REGEX_SUBTASK_PERCENT.sub("[%d%%]" % (percent), self.title)
d = self._heading.document.write_checkbox(self, including_children=False)
@classmethod
def identify_checkbox(cls, line):
u""" Test if a certain line is a checkbox or not.
:line: the line to check
:returns: indent_level
"""
# checkbox is not heading
if REGEX_HEADING.match(line) is not None:
return None
m = REGEX_CHECKBOX.match(line)
if m:
r = m.groupdict()
return len(r[u'level'])
return None
@property
def is_dirty(self):
u""" Return True if the heading's body is marked dirty """
return self._dirty_checkbox or self._dirty_body
@property
def is_dirty_checkbox(self):
u""" Return True if the heading is marked dirty """
return self._dirty_checkbox
def get_index_in_parent_list(self):
""" Retrieve the index value of current checkbox in the parents list of
checkboxes. This works also for top level checkboxes.
:returns: Index value or None if heading doesn't have a
parent/document or is not in the list of checkboxes
"""
if self.parent:
return super(Checkbox, self).get_index_in_parent_list()
elif self.document:
l = self.get_parent_list()
if l:
return l.index(self)
def get_parent_list(self):
""" Retrieve the parents' list of headings. This works also for top
level headings.
:returns: List of headings or None if heading doesn't have a
parent/document or is not in the list of headings
"""
if self.parent:
return super(Checkbox, self).get_parent_list()
elif self.document:
if self in self.document.checkboxes:
return self.document.checkboxes
def set_dirty(self):
u""" Mark the heading and body dirty so that it will be rewritten when
saving the document """
self._dirty_checkbox = True
self._dirty_body = True
if self._document:
self._document.set_dirty_document()
def set_dirty_checkbox(self):
u""" Mark the checkbox dirty so that it will be rewritten when saving the
document """
self._dirty_checkbox = True
if self._document:
self._document.set_dirty_document()
@property
def previous_checkbox(self):
u""" Serialized access to the previous checkbox """
return super(Checkbox, self).previous_item
@property
def next_checkbox(self):
u""" Serialized access to the next checkbox """
return super(Checkbox, self).next_item
@property
def first_checkbox(self):
u""" Access to the first child heading or None if no children exist """
if self.children:
return self.children[0]
@property
def start(self):
u""" Access to the starting line of the checkbox """
return super(Checkbox, self).start
def toggle(self):
u""" Toggle status of this checkbox """
if self.status == Checkbox.STATUS_OFF or self.status is None:
self.status = Checkbox.STATUS_ON
else:
self.status = Checkbox.STATUS_OFF
self.set_dirty()
def all_siblings(self):
if not self.parent:
p = self._heading
else:
p = self.parent
if not p.children:
return
c = p.first_checkbox
while c:
yield c
c = c.next_sibling
return
def all_children(self):
if not self.children:
return
c = self.first_checkbox
while c:
yield c
for d in c.all_children():
yield d
c = c.next_sibling
return
def all_children_status(self):
u""" Return checkboxes status for currnet checkbox's all children
:return: (total, on)
total: total # of checkboxes
on: # of checkboxes which are on
"""
total, on = 0, 0
for c in self.all_children():
if c.status is not None:
total += 1
if c.status == Checkbox.STATUS_ON:
on += 1
return (total, on)
def all_siblings_status(self):
u""" Return checkboxes status for currnet checkbox's all siblings
:return: (total, on)
total: total # of checkboxes
on: # of checkboxes which are on
"""
total, on = 0, 0
for c in self.all_siblings():
if c.status is not None:
total += 1
if c.status == Checkbox.STATUS_ON:
on += 1
return (total, on)
def are_children_all(self, status):
u""" Check all children checkboxes status """
clen = len(self.children)
for i in range(clen):
if self.children[i].status != status:
return False
# recursively check children's status
if not self.children[i].are_children_all(status):
return False
return True
def is_child_one(self, status):
u""" Return true, if there is one child with given status """
clen = len(self.children)
for i in range(clen):
if self.children[i].status == status:
return True
return False
def are_siblings_all(self, status):
u""" Check all sibling checkboxes status """
for c in self.all_siblings():
if c.status != status:
return False
return True
@DomObj.level.setter
def level(self, value):
u""" Set the checkbox level and mark the checkbox and the document
dirty """
self._level = int(value)
self.set_dirty_checkbox()
@DomObj.title.setter
def title(self, value):
u""" Set the title and mark the document and the checkbox dirty """
if type(value) not in (unicode, str):
raise ValueError(u'Title must be a string.')
v = value
if type(v) == str:
v = u_decode(v)
self._title = v.strip()
self.set_dirty_checkbox()
@property
def status(self):
u""" status of current checkbox """
return self._status
@status.setter
def status(self, value):
self._status = value
self.set_dirty()
@status.deleter
def status(self):
self._status = u''
@property
def type(self):
u""" type of current checkbox list type """
return self._type
@type.setter
def type(self, value):
self._type = value
@type.deleter
def type(self):
self._type = u''
class CheckboxList(DomObjList):
u"""
Checkbox List
"""
def __init__(self, initlist=None, obj=None):
"""
:initlist: Initial data
:obj: Link to a concrete Checkbox or Document object
"""
# it's not necessary to register a on_change hook because the heading
# list will itself take care of marking headings dirty or adding
# headings to the deleted headings list
DomObjList.__init__(self, initlist, obj)
@classmethod
def is_checkbox(cls, obj):
return CheckboxList.is_domobj(obj)
def _get_heading(self):
if self.__class__.is_checkbox(self._obj):
return self._obj._document
return self._obj
# vim: set noexpandtab:

View file

@ -1,315 +0,0 @@
# -*- coding: utf-8 -*-
"""
documents
~~~~~~~~~
TODO: explain this :)
"""
try:
from collections import UserList
except:
from UserList import UserList
from orgmode.liborgmode.base import MultiPurposeList, flatten_list, Direction, get_domobj_range
from orgmode.liborgmode.headings import Heading, HeadingList
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *
class Document(object):
u"""
Representation of a whole org-mode document.
A Document consists basically of headings (see Headings) and some metadata.
TODO: explain the 'dirty' mechanism
"""
def __init__(self):
u"""
Don't call this constructor directly but use one of the concrete
implementations.
TODO: what are the concrete implementatiions?
"""
object.__init__(self)
# is a list - only the Document methods should work on this list!
self._content = None
self._dirty_meta_information = False
self._dirty_document = False
self._meta_information = MultiPurposeList(
on_change=self.set_dirty_meta_information)
self._orig_meta_information_len = None
self._headings = HeadingList(obj=self)
self._deleted_headings = []
# settings needed to align tags properly
self._tabstop = 8
self._tag_column = 77
# TODO this doesn't differentiate between ACTIVE and FINISHED todo's
self.todo_states = [u'TODO', u'DONE']
def __unicode__(self):
if self.meta_information is None:
return u'\n'.join(self.all_headings())
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()])
def __str__(self):
return u_encode(self.__unicode__())
def get_all_todo_states(self):
u""" Convenience function that returns all todo and done states and
sequences in one big list.
Returns:
list: [all todo/done states]
"""
# TODO This is not necessary remove
return flatten_list(self.get_todo_states())
def get_todo_states(self):
u""" Returns a list containing a tuple of two lists of allowed todo
states split by todo and done states. Multiple todo-done state
sequences can be defined.
Returns:
list: [([todo states], [done states]), ..]
"""
# TODO this should be made into property so todo states can be set like
# this too.. or there was also some todo property around... oh well..
# TODO there is the same method in vimbuffer
return self.todo_states
@property
def tabstop(self):
u""" Tabstop for this document """
return self._tabstop
@tabstop.setter
def tabstop(self, value):
self._tabstop = value
@property
def tag_column(self):
u""" The column all tags are right-aligned to """
return self._tag_column
@tag_column.setter
def tag_column(self, value):
self._tag_column = value
def init_dom(self, heading=Heading):
u""" Initialize all headings in document - build DOM. This method
should be call prior to accessing the document.
Returns:
self
"""
def init_heading(_h):
u"""
:returns the initialized heading
"""
start = _h.end + 1
prev_heading = None
while True:
new_heading = self.find_heading(start, heading=heading)
# * Heading 1 <- heading
# * Heading 1 <- sibling
# or
# * Heading 2 <- heading
# * Heading 1 <- parent's sibling
if not new_heading or \
new_heading.level <= _h.level:
break
# * Heading 1 <- heading
# * Heading 2 <- first child
# * Heading 2 <- another child
new_heading._parent = _h
if prev_heading:
prev_heading._next_sibling = new_heading
new_heading._previous_sibling = prev_heading
_h.children.data.append(new_heading)
# the start and end computation is only
# possible when the new heading was properly
# added to the document structure
init_heading(new_heading)
if new_heading.children:
# skip children
start = new_heading.end_of_last_child + 1
else:
start = new_heading.end + 1
prev_heading = new_heading
return _h
h = self.find_heading(heading=heading)
# initialize meta information
if h:
self._meta_information.data.extend(self._content[:h._orig_start])
else:
self._meta_information.data.extend(self._content[:])
self._orig_meta_information_len = len(self.meta_information)
# initialize dom tree
prev_h = None
while h:
if prev_h:
prev_h._next_sibling = h
h._previous_sibling = prev_h
self.headings.data.append(h)
init_heading(h)
prev_h = h
h = self.find_heading(h.end_of_last_child + 1, heading=heading)
return self
@property
def meta_information(self):
u""" Meta information is text that precedes all headings in an org-mode
document. It might contain additional information about the document,
e.g. author
"""
return self._meta_information
@meta_information.setter
def meta_information(self, value):
if self._orig_meta_information_len is None:
self._orig_meta_information_len = len(self.meta_information)
if type(value) in (list, tuple) or isinstance(value, UserList):
self._meta_information[:] = flatten_list(value)
elif type(value) in (str, ):
self._meta_information[:] = u_decode(value).split(u'\n')
elif type(value) in (unicode, ):
self._meta_information[:] = value.split(u'\n')
self.set_dirty_meta_information()
@meta_information.deleter
def meta_information(self):
self.meta_information = u''
@property
def headings(self):
u""" List of top level headings """
return self._headings
@headings.setter
def headings(self, value):
self._headings[:] = value
@headings.deleter
def headings(self):
del self.headings[:]
def write(self):
u""" Write the document
Returns:
bool: True if something was written, otherwise False
"""
raise NotImplementedError(u'Abstract method, please use concrete impelementation!')
def set_dirty_meta_information(self):
u""" Mark the meta information dirty.
Note:
Causes meta information to be rewritten when saving the document
"""
self._dirty_meta_information = True
def set_dirty_document(self):
u""" Mark the whole document dirty.
Note:
When changing a heading this method must be executed in order to
changed computation of start and end positions from a static to a
dynamic computation
"""
self._dirty_document = True
@property
def is_dirty(self):
u""" Return information about unsaved changes for the document and all
related headings.
Returns:
bool: True if document contains unsaved changes.
"""
if self.is_dirty_meta_information:
return True
if self.is_dirty_document:
return True
if self._deleted_headings:
return True
return False
@property
def is_dirty_meta_information(self):
u""" Return True if the meta information is marked dirty """
return self._dirty_meta_information
@property
def is_dirty_document(self):
u""" Return True if the document is marked dirty """
return self._dirty_document
def all_headings(self):
u""" Iterate over all headings of the current document in serialized
order
:returns: Returns an iterator object which returns all headings of
the current file in serialized order
"""
if not self.headings:
return
h = self.headings[0]
while h:
yield h
h = h.next_heading
return
def find_heading(
self, position=0, direction=Direction.FORWARD, heading=Heading,
connect_with_document=True):
u""" Find heading in the given direction
Args:
position (int): starting line, counting from 0 (in vim you start
counting from 1, don't forget)
direction: downwards == Direction.FORWARD,
upwards == Direction.BACKWARD
heading: Heading class from which new heading objects will be
instanciated
connect_with_document: if True, the newly created heading will be
connected with the document, otherwise not
Returns:
heading or None: New heading
"""
start, end = get_domobj_range(
content=self._content, position=position, direction=direction,
identify_fun=heading.identify_heading)
if start is None:
return None
if end is None:
end = len(self._content) - 1
document = self if connect_with_document else None
return heading.parse_heading_from_data(
self._content[start:end + 1], self.get_all_todo_states(),
document=document, orig_start=start)
# vim: set noexpandtab:

View file

@ -1,505 +0,0 @@
# -*- coding: utf-8 -*-
"""
dom object
~~~~~~~~~~
TODO: explain this :)
"""
import re
from orgmode.liborgmode.base import MultiPurposeList, flatten_list
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *
try:
from collections import UserList
except:
from UserList import UserList
# breaking down tasks regex
REGEX_SUBTASK = re.compile(r'\[(\d*)/(\d*)\]')
REGEX_SUBTASK_PERCENT = re.compile(r'\[(\d*)%\]')
# heading regex
REGEX_HEADING = re.compile(
r'^(?P<level>\*+)(\s+(?P<title>.*?))?\s*(\s(?P<tags>:[\w_:@]+:))?$',
flags=re.U)
REGEX_TAG = re.compile(
r'^\s*((?P<title>[^\s]*?)\s+)?(?P<tags>:[\w_:@]+:)$',
flags=re.U)
REGEX_TODO = re.compile(r'^[^\s]*$')
# checkbox regex:
# - [ ] checkbox item
# - [X] checkbox item
# - [ ]
# - no status checkbox
UnOrderListType = [u'-', u'+', u'*']
OrderListType = [u'.', u')']
REGEX_CHECKBOX = re.compile(
r'^(?P<level>\s*)(?P<type>[%s]|([a-zA-Z]|[\d]+)[%s])(\s+(?P<status>\[.\]))?\s*(?P<title>.*)$'
% (''.join(UnOrderListType), ''.join(OrderListType)), flags=re.U)
class DomObj(object):
u"""
A DomObj is DOM structure element, like Heading and Checkbox.
Its purpose is to abstract the same parts of Heading and Checkbox objects,
and make code reusable.
All methods and properties are extracted from Heading object.
Heading and Checkbox objects inherit from DomObj, and override some specific
methods in their own objects.
Normally, we don't intend to use DomObj directly. However, we can add some more
DOM structure element based on this class to make code more concise.
"""
# TODO should this and DomObj_list be abstract methods? If so use ABC to
# force abstract methods
def __init__(self, level=1, title=u'', body=None):
u"""
:level: Level of the dom object
:title: Title of the dom object
:body: Body of the dom object
"""
object.__init__(self)
self._document = None
self._parent = None
self._previous_sibling = None
self._next_sibling = None
self._children = MultiPurposeList()
self._orig_start = None
self._orig_len = 0
self._level = level
# title
self._title = u''
if title:
self.title = title
# body
self._dirty_body = False
self._body = MultiPurposeList(on_change=self.set_dirty_body)
if body:
self.body = body
def __unicode__(self):
return u'<dom obj level=%s, title=%s>' % (level, title)
def __str__(self):
return u_encode(self.__unicode__())
def __len__(self):
# 1 is for the heading's title
return 1 + len(self.body)
@property
def is_dirty(self):
u""" Return True if the dom obj body is marked dirty """
return self._dirty_body
@property
def is_dirty_body(self):
u""" Return True if the dom obj body is marked dirty """
return self._dirty_body
def get_index_in_parent_list(self):
""" Retrieve the index value of current dom obj in the parents list of
dom objs. This works also for top level dom objs.
:returns: Index value or None if dom obj doesn't have a
parent/document or is not in the list of dom objs
"""
l = self.get_parent_list()
if l:
return l.index(self)
def get_parent_list(self):
""" Retrieve the parents list of dom objs. This works also for top
level dom objs.
:returns: List of dom objs or None if dom objs doesn't have a
parent/document or is not in the list of dom objs
"""
if self.parent:
if self in self.parent.children:
return self.parent.children
def set_dirty(self):
u""" Mark the dom objs and body dirty so that it will be rewritten when
saving the document """
if self._document:
self._document.set_dirty_document()
def set_dirty_body(self):
u""" Mark the dom objs' body dirty so that it will be rewritten when
saving the document """
self._dirty_body = True
if self._document:
self._document.set_dirty_document()
@property
def document(self):
u""" Read only access to the document. If you want to change the
document, just assign the dom obj to another document """
return self._document
@property
def parent(self):
u""" Access to the parent dom obj """
return self._parent
@property
def number_of_parents(self):
u""" Access to the number of parent dom objs before reaching the root
document """
def count_parents(h):
if h.parent:
return 1 + count_parents(h.parent)
else:
return 0
return count_parents(self)
@property
def previous_sibling(self):
u""" Access to the previous dom obj that's a sibling of the current one
"""
return self._previous_sibling
@property
def next_sibling(self):
u""" Access to the next dom obj that's a sibling of the current one """
return self._next_sibling
@property
def previous_item(self):
u""" Serialized access to the previous dom obj """
if self.previous_sibling:
h = self.previous_sibling
while h.children:
h = h.children[-1]
return h
elif self.parent:
return self.parent
@property
def next_item(self):
u""" Serialized access to the next dom obj """
if self.children:
return self.children[0]
elif self.next_sibling:
return self.next_sibling
else:
h = self.parent
while h:
if h.next_sibling:
return h.next_sibling
else:
h = h.parent
@property
def start(self):
u""" Access to the starting line of the dom obj """
if self.document is None or not self.document.is_dirty:
return self._orig_start
def item_len_generator(h):
while h:
yield len(h)
h = h.previous_item
return sum(item for item in item_len_generator(self.previous_item))
@property
def start_vim(self):
if self.start is not None:
return self.start + 1
@property
def end(self):
u""" Access to the ending line of the dom obj """
if self.start is not None:
return self.start + len(self.body)
@property
def end_vim(self):
if self.end is not None:
return self.end + 1
@property
def end_of_last_child(self):
u""" Access to end of the last child """
if self.children:
child = self.children[-1]
while child.children:
child = child.children[-1]
return child.end
return self.end
@property
def end_of_last_child_vim(self):
return self.end_of_last_child + 1
@property
def children(self):
u""" MultiPurposeList[dom_objects??]: subheadings of the current DomObj
Setter method takes list, tuple or userlist with DOMObjects
"""
return self._children
@children.setter
def children(self, value):
v = value
if type(v) in (list, tuple) or isinstance(v, UserList):
v = flatten_list(v)
self._children[:] = v
@children.deleter
def children(self):
del self.children[:]
@property
def first_child(self):
u""" Access to the first child dom obj or None if no children exist """
if self.children:
return self.children[0]
@property
def last_child(self):
u""" Access to the last child dom obj or None if no children exist """
if self.children:
return self.children[-1]
@property
def level(self):
u""" int: Access the the dom obj level
Setter sets the DOM object and the document as dirty if invoked.
"""
return self._level
@level.setter
def level(self, value):
# TODO Shouldn't there be and error when values is not int?
self._level = int(value)
self.set_dirty()
@level.deleter
def level(self):
self.level = None
@property
def title(self):
u""" str: Get the title of current dom object
Setter sets the DOM object and the document as dirty if invoked.
"""
return self._title.strip()
@title.setter
def title(self, value):
if type(value) not in (unicode, str):
raise ValueError(u'Title must be a string.')
v = value
if type(v) == str:
v = u_decode(v)
self._title = v.strip()
self.set_dirty()
@title.deleter
def title(self):
self._title = u''
@property
def body(self):
u""" MultiPurposeList[]: Holds the content belonging to the heading """
return self._body
@body.setter
def body(self, value):
if type(value) in (list, tuple) or isinstance(value, UserList):
self._body[:] = flatten_list(value)
elif type(value) in (str, ):
self._body[:] = u_decode(value).split(u'\n')
elif type(value) in (unicode, ):
self._body[:] = value.split(u'\n')
else:
self.body = list(unicode(value))
@body.deleter
def body(self):
# TODO write this as del self._body[:] because there is no reason to
# call so much code for deleting a list
self.body = []
class DomObjList(MultiPurposeList):
u"""
A Dom Obj List
"""
def __init__(self, initlist=None, obj=None):
"""
:initlist: Initial data
:obj: Link to a concrete Heading or Document object
"""
# it's not necessary to register a on_change hook because the heading
# list will itself take care of marking headings dirty or adding
# headings to the deleted headings list
MultiPurposeList.__init__(self)
self._obj = obj
# initialization must be done here, because
# self._document is not initialized when the
# constructor of MultiPurposeList is called
if initlist:
self.extend(initlist)
@classmethod
def is_domobj(cls, obj):
# TODO no reason for it to be class method. Does it even need to exist
# because it is quite clear what isinstance does and in derived methods
# isinstance(Heading, DomObj) would return True anyway.
return isinstance(obj, DomObj)
# TODO this should be made into a property
def _get_document(self):
if self.__class__.is_domobj(self._obj):
return self._obj._document
return self._obj
def __setitem__(self, i, item):
if isinstance(i, slice):
o = item
if self.__class__.is_domobj(o):
o = (o, )
o = flatten_list(o)
for item in o:
if not self.__class__.is_domobj(item):
raise ValueError(u'List contains items that are not a Dom obj!')
# self._add_to_deleted_domobjs(self[i:j])
# self._associate_domobj(o, \
# self[i - 1] if i - 1 >= 0 and i < len(self) else None, \
# self[j] if j >= 0 and j < len(self) else None)
MultiPurposeList.__setitem__(self, i, o)
else:
if not self.__class__.is_domobj(item):
raise ValueError(u'Item is not a Dom obj!')
if item in self:
raise ValueError(u'Dom obj is already part of this list!')
# self._add_to_deleted_domobjs(self[i])
# self._associate_domobj(item, \
# self[i - 1] if i - 1 >= 0 else None, \
# self[i + 1] if i + 1 < len(self) else None)
MultiPurposeList.__setitem__(self, i, item)
def __delitem__(self, i, taint=True):
if isinstance(i, slice):
items = self[i]
if items:
first = items[0]
last = items[-1]
if first.previous_sibling:
first.previous_sibling._next_sibling = last.next_sibling
if last.next_sibling:
last.next_sibling._previous_sibling = first.previous_sibling
# if taint:
# self._add_to_deleted_domobjs(items)
else:
item = self[i]
if item.previous_sibling:
item.previous_sibling._next_sibling = item.next_sibling
if item.next_sibling:
item.next_sibling._previous_sibling = item.previous_sibling
# if taint:
# self._add_to_deleted_domobjs(item)
MultiPurposeList.__delitem__(self, i)
def __setslice__(self, i, j, other):
self.__setitem__(slice(i, j), other)
def __delslice__(self, i, j, taint=True):
self.__delitem__(slice(i, j), taint=taint)
def __iadd__(self, other):
o = other
if self.__class__.is_domobj(o):
o = (o, )
for item in flatten_list(o):
if not self.__class__.is_domobj(item):
raise ValueError(u'List contains items that are not a Dom obj!')
# self._associate_domobj(o, self[-1] if len(self) > 0 else None, None)
return MultiPurposeList.__iadd__(self, o)
def __imul__(self, n):
# TODO das müsste eigentlich ein klonen von objekten zur Folge haben
return MultiPurposeList.__imul__(self, n)
def append(self, item, taint=True):
if not self.__class__.is_domobj(item):
raise ValueError(u'Item is not a heading!')
if item in self:
raise ValueError(u'Heading is already part of this list!')
# self._associate_domobj(
# item, self[-1] if len(self) > 0 else None,
# None, taint=taint)
MultiPurposeList.append(self, item)
def insert(self, i, item, taint=True):
# self._associate_domobj(
# item,
# self[i - 1] if i - 1 >= 0 and i - 1 < len(self) else None,
# self[i] if i >= 0 and i < len(self) else None, taint=taint)
MultiPurposeList.insert(self, i, item)
def pop(self, i=-1):
item = self[i]
# self._add_to_deleted_domobjs(item)
del self[i]
return item
def remove_slice(self, i, j, taint=True):
self.__delitem__(slice(i, j), taint=taint)
def remove(self, item, taint=True):
self.__delitem__(self.index(item), taint=taint)
def reverse(self):
MultiPurposeList.reverse(self)
prev_h = None
for h in self:
h._previous_sibling = prev_h
h._next_sibling = None
prev_h._next_sibling = h
h.set_dirty()
prev_h = h
def sort(self, *args, **kwds):
MultiPurposeList.sort(*args, **kwds)
prev_h = None
for h in self:
h._previous_sibling = prev_h
h._next_sibling = None
prev_h._next_sibling = h
h.set_dirty()
prev_h = h
def extend(self, other):
o = other
if self.__class__.is_domobj(o):
o = (o, )
for item in o:
if not self.__class__.is_domobj(item):
raise ValueError(u'List contains items that are not a heading!')
# self._associate_domobj(o, self[-1] if len(self) > 0 else None, None)
MultiPurposeList.extend(self, o)
# vim: set noexpandtab:

View file

@ -1,889 +0,0 @@
# -*- coding: utf-8 -*-
"""
headings
~~~~~~~~~
TODO: explain this :)
"""
import re
import vim
from orgmode.liborgmode.base import MultiPurposeList, flatten_list, Direction, get_domobj_range
from orgmode.liborgmode.orgdate import OrgTimeRange
from orgmode.liborgmode.orgdate import get_orgdate
from orgmode.liborgmode.checkboxes import Checkbox, CheckboxList
from orgmode.liborgmode.dom_obj import DomObj, DomObjList, REGEX_SUBTASK, REGEX_SUBTASK_PERCENT, REGEX_HEADING, REGEX_TAG, REGEX_TODO
from orgmode.py3compat.xrange_compatibility import *
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *
try:
from collections import UserList
except:
from UserList import UserList
from itertools import ifilter as filter
class Heading(DomObj):
u""" Structural heading object """
def __init__(self, level=1, title=u'', tags=None, todo=None, body=None, active_date=None):
u"""
:level: Level of the heading
:title: Title of the heading
:tags: Tags of the heading
:todo: Todo state of the heading
:body: Body of the heading
:active_date: active date that is used in the agenda
"""
DomObj.__init__(self, level=level, title=title, body=body)
self._children = HeadingList(obj=self)
self._dirty_heading = False
# todo
self._todo = None
if todo:
self.todo = todo
# tags
self._tags = MultiPurposeList(on_change=self.set_dirty_heading)
if tags:
self.tags = tags
# active date
self._active_date = active_date
if active_date:
self.active_date = active_date
# checkboxes
self._checkboxes = CheckboxList(obj=self)
self._cached_checkbox = None
def __unicode__(self):
res = u'*' * self.level
if self.todo:
res = u' '.join((res, self.todo))
if self.title:
res = u' '.join((res, self.title))
# compute position of tags
if self.tags:
tabs = 0
spaces = 2
tags = u':%s:' % (u':'.join(self.tags), )
# FIXME this is broken because of missing associations for headings
ts = 6
tag_column = 77
if self.document:
ts = self.document.tabstop
tag_column = self.document.tag_column
len_heading = len(res)
len_tags = len(tags)
if len_heading + spaces + len_tags < tag_column:
spaces_to_next_tabstop = ts - divmod(len_heading, ts)[1]
if len_heading + spaces_to_next_tabstop + len_tags < tag_column:
tabs, spaces = divmod(
tag_column - (len_heading + spaces_to_next_tabstop + len_tags),
ts)
if spaces_to_next_tabstop:
tabs += 1
else:
spaces = tag_column - (len_heading + len_tags)
res += u'\t' * tabs + u' ' * spaces + tags
# append a trailing space when there are just * and no text
if len(res) == self.level:
res += u' '
return res
def __str__(self):
return u_encode(self.__unicode__())
def __len__(self):
# 1 is for the heading's title
return 1 + len(self.body)
def __lt__(self, other):
"""
Headings can be sorted by date.
"""
try:
if self.active_date < other.active_date:
return True
elif self.active_date == other.active_date:
return False
elif self.active_date > other.active_date:
return False
except:
if self.active_date and not other.active_date:
return True
elif not self.active_date and other.active_date:
return False
elif not self.active_date and not other.active_date:
return False
def __le__(self, other):
"""
Headings can be sorted by date.
"""
try:
if self.active_date < other.active_date:
return True
elif self.active_date == other.active_date:
return True
elif self.active_date > other.active_date:
return False
except:
if self.active_date and not other.active_date:
return True
elif not self.active_date and other.active_date:
return False
elif not self.active_date and not other.active:
return True
def __ge__(self, other):
"""
Headings can be sorted by date.
"""
try:
if self.active_date > other.active_date:
return True
elif self.active_date == other.active_date:
return True
elif self.active_date < other.active_date:
return False
except:
if not self.active_date and other.active_date:
return True
elif self.active_date and not other.active_date:
return False
elif not self.active_date and not other.active:
return True
def __gt__(self, other):
"""
Headings can be sorted by date.
"""
try:
if self.active_date > other.active_date:
return True
elif self.active_date == other.active_date:
return False
elif self.active_date < other.active_date:
return False
except:
if not self.active_date and other.active_date:
return True
elif self.active_date and not other.active_date:
return False
elif not self.active_date and not other.active:
return False
def copy(self, including_children=True, parent=None):
u"""
Create a copy of the current heading. The heading will be completely
detached and not even belong to a document anymore.
:including_children: If True a copy of all children is create as
well. If False the returned heading doesn't
have any children.
:parent: Don't use this parameter. It's set
automatically.
"""
heading = self.__class__(
level=self.level, title=self.title,
tags=self.tags, todo=self.todo, body=self.body[:])
if parent:
parent.children.append(heading)
if including_children and self.children:
for item in self.children:
item.copy(
including_children=including_children,
parent=heading)
heading._orig_start = self._orig_start
heading._orig_len = self._orig_len
heading._dirty_heading = self.is_dirty_heading
return heading
def all_checkboxes(self):
u""" Iterate over all checkboxes of the current heading in serialized
order
:returns: Returns an iterator object which returns all checkboxes of
the current heading in serialized order
"""
if not self.checkboxes:
return
c = self.first_checkbox
while c:
yield c
c = c.next_checkbox
return
def all_toplevel_checkboxes(self):
u""" return all top level checkboxes for current heading """
if not self.checkboxes:
return
c = self.first_checkbox
while c:
yield c
c = c.next_sibling
return
def find_checkbox(self, position=0, direction=Direction.FORWARD,
checkbox=Checkbox, connect_with_heading=True):
u""" Find checkbox in the given direction
:postition: starting line, counting from 0 (in vim you start
counting from 1, don't forget)
:direction: downwards == Direction.FORWARD,
upwards == Direction.BACKWARD
:checkbox: Checkbox class from which new checkbox objects will be
instanciated
:connect_with_heading: if True, the newly created checkbox will be
connected with the heading, otherwise not
:returns: New checkbox object or None
"""
doc = self.document
(start, end) = get_domobj_range(content=doc._content, position=position, direction=direction, identify_fun=checkbox.identify_checkbox)
# if out of current headinig range, reutrn None
heading_end = self.start + len(self) - 1
if start is not None and start > heading_end:
return None
if end is not None and end > heading_end:
end = heading_end
if start is not None and end is None:
end = heading_end
if start is not None and end is not None:
return checkbox.parse_checkbox_from_data(
doc._content[start:end + 1],
heading=self if connect_with_heading else None, orig_start=start)
def init_checkboxes(self, checkbox=Checkbox):
u""" Initialize all checkboxes in current heading - build DOM.
:returns: self
"""
def init_checkbox(_c):
u"""
:returns the initialized checkbox
"""
start = _c.end + 1
prev_checkbox = None
while True:
new_checkbox = self.find_checkbox(start, checkbox=checkbox)
# * Checkbox 1 <- checkbox
# * Checkbox 1 <- sibling
# or
# * Checkbox 2 <- checkbox
# * Checkbox 1 <- parent's sibling
if not new_checkbox or \
new_checkbox.level <= _c.level:
break
# * Checkbox 1 <- heading
# * Checkbox 2 <- first child
# * Checkbox 2 <- another child
new_checkbox._parent = _c
if prev_checkbox:
prev_checkbox._next_sibling = new_checkbox
new_checkbox._previous_sibling = prev_checkbox
_c.children.data.append(new_checkbox)
# the start and end computation is only
# possible when the new checkbox was properly
# added to the document structure
init_checkbox(new_checkbox)
if new_checkbox.children:
# skip children
start = new_checkbox.end_of_last_child + 1
else:
start = new_checkbox.end + 1
prev_checkbox = new_checkbox
return _c
c = self.find_checkbox(checkbox=checkbox, position=self.start)
# initialize dom tree
prev_c = None
while c:
if prev_c and prev_c.level == c.level:
prev_c._next_sibling = c
c._previous_sibling = prev_c
self.checkboxes.data.append(c)
init_checkbox(c)
prev_c = c
c = self.find_checkbox(c.end_of_last_child + 1, checkbox=checkbox)
return self
def current_checkbox(self, position=None):
u""" Find the current checkbox (search backward) and return the related object
:returns: Checkbox object or None
"""
if position is None:
position = vim.current.window.cursor[0] - 1
if not self.checkboxes:
return
def binaryFindInHeading():
hi = len(self.checkboxes)
lo = 0
while lo < hi:
mid = (lo + hi) // 2
c = self.checkboxes[mid]
if c.end_of_last_child < position:
lo = mid + 1
elif c.start > position:
hi = mid
else:
return binaryFindCheckbox(c)
def binaryFindCheckbox(checkbox):
if not checkbox.children or checkbox.end >= position:
return checkbox
hi = len(checkbox.children)
lo = 0
while lo < hi:
mid = (lo + hi) // 2
c = checkbox.children[mid]
if c.end_of_last_child < position:
lo = mid + 1
elif c.start > position:
hi = mid
else:
return binaryFindCheckbox(c)
# look at the cache to find the heading
c_tmp = self._cached_checkbox
if c_tmp is not None:
if c_tmp.end_of_last_child > position and \
c_tmp.start < position:
if c_tmp.end < position:
self._cached_checkbox = binaryFindCheckbox(c_tmp)
return self._cached_checkbox
self._cached_checkbox = binaryFindInHeading()
return self._cached_checkbox
@property
def first_checkbox(self):
u""" Access to the first child checkbox or None if no children exist """
if self.checkboxes:
return self.checkboxes[0]
@classmethod
def parse_heading_from_data(
cls, data, allowed_todo_states, document=None,
orig_start=None):
u""" Construct a new heading from the provided data
:data: List of lines
:allowed_todo_states: TODO???
:document: The document object this heading belongs to
:orig_start: The original start of the heading in case it was read
from a document. If orig_start is provided, the
resulting heading will not be marked dirty.
:returns: The newly created heading
"""
test_not_empty = lambda x: x != u''
def parse_title(heading_line):
# WARNING this regular expression fails if there is just one or no
# word in the heading but a tag!
m = REGEX_HEADING.match(heading_line)
if m:
r = m.groupdict()
level = len(r[u'level'])
todo = None
title = u''
tags = filter(test_not_empty, r[u'tags'].split(u':')) if r[u'tags'] else []
tags = list(tags)
# if there is just one or no word in the heading, redo the parsing
mt = REGEX_TAG.match(r[u'title'])
if not tags and mt:
r = mt.groupdict()
tags = filter(test_not_empty, r[u'tags'].split(u':')) if r[u'tags'] else []
tags = list(tags)
if r[u'title'] is not None:
_todo_title = [i.strip() for i in r[u'title'].split(None, 1)]
if _todo_title and _todo_title[0] in allowed_todo_states:
todo = _todo_title[0]
if len(_todo_title) > 1:
title = _todo_title[1]
else:
title = r[u'title'].strip()
return (level, todo, title, tags)
raise ValueError(u'Data doesn\'t start with a heading definition.')
if not data:
raise ValueError(u'Unable to create heading, no data provided.')
# create new heaing
new_heading = cls()
new_heading.level, new_heading.todo, new_heading.title, new_heading.tags = parse_title(data[0])
new_heading.body = data[1:]
if orig_start is not None:
new_heading._dirty_heading = False
new_heading._dirty_body = False
new_heading._orig_start = orig_start
new_heading._orig_len = len(new_heading)
if document:
new_heading._document = document
# try to find active dates
tmp_orgdate = get_orgdate(data)
if tmp_orgdate and tmp_orgdate.active \
and not isinstance(tmp_orgdate, OrgTimeRange):
new_heading.active_date = tmp_orgdate
else:
new_heading.active_date = None
return new_heading
def update_subtasks(self, total=0, on=0):
u""" Update subtask information for current heading
:total: total # of top level checkboxes
:on: # of top level checkboxes which are on
"""
if total != 0:
percent = (on * 100) / total
else:
percent = 0
count = "%d/%d" % (on, total)
self.title = REGEX_SUBTASK.sub("[%s]" % (count), self.title)
self.title = REGEX_SUBTASK_PERCENT.sub("[%d%%]" % (percent), self.title)
self.document.write_heading(self, including_children=False)
@staticmethod
def identify_heading(line):
u""" Test if a certain line is a heading or not.
Args:
line (str): the line to check
Returns:
int or None: level of heading or None if line is not heading
"""
# TODO would it make sense to return 0 for heading level?
# TODO add tests e.g. '*** abc', '**', '', '* ', '*\t', '*'
for i, item in enumerate(line):
if item == '*':
continue
elif i and item in ('\t', ' '):
return i
break
return None
@property
def is_dirty(self):
u""" Return True if the heading's body is marked dirty """
return self._dirty_heading or self._dirty_body
@property
def is_dirty_heading(self):
u""" Return True if the heading is marked dirty """
return self._dirty_heading
def get_index_in_parent_list(self):
""" Retrieve the index value of current heading in the parents list of
headings. This works also for top level headings.
:returns: Index value or None if heading doesn't have a
parent/document or is not in the list of headings
"""
if self.parent:
return super(Heading, self).get_index_in_parent_list()
elif self.document:
l = self.get_parent_list()
if l:
return l.index(self)
def get_parent_list(self):
""" Retrieve the parents' list of headings. This works also for top
level headings.
:returns: List of headings or None if heading doesn't have a
parent/document or is not in the list of headings
"""
if self.parent:
return super(Heading, self).get_parent_list()
elif self.document:
if self in self.document.headings:
return self.document.headings
def set_dirty(self):
u""" Mark the heading and body dirty so that it will be rewritten when
saving the document """
self._dirty_heading = True
self._dirty_body = True
if self._document:
self._document.set_dirty_document()
def set_dirty_heading(self):
u""" Mark the heading dirty so that it will be rewritten when saving the
document """
self._dirty_heading = True
if self._document:
self._document.set_dirty_document()
@property
def previous_heading(self):
u""" Serialized access to the previous heading """
return super(Heading, self).previous_item
@property
def next_heading(self):
u""" Serialized access to the next heading """
return super(Heading, self).next_item
@property
def start(self):
u""" Access to the starting line of the heading """
if self.document is None or not self.document.is_dirty:
return self._orig_start
meta_len = len(self.document.meta_information) if \
self.document.meta_information else 0
return super(Heading, self).start + meta_len
@DomObj.level.setter
def level(self, value):
u""" Set the heading level and mark the heading and the document dirty """
self._level = int(value)
self.set_dirty_heading()
@property
def todo(self):
u""" Todo state of current heading. When todo state is set"""
# extract todo state from heading
return self._todo
@todo.setter
def todo(self, value):
# update todo state
if type(value) not in (unicode, str, type(None)):
raise ValueError(u'Todo state must be a string or None.')
if value and not REGEX_TODO.match(value):
raise ValueError(u'Found non allowed character in todo state! %s' % value)
if not value:
self._todo = None
else:
v = value
if type(v) == str:
v = u_decode(v)
self._todo = v
self.set_dirty_heading()
@todo.deleter
def todo(self):
self.todo = None
@property
def active_date(self):
u"""
active date of the hearing.
active dates are used in the agenda view. they can be part of the
heading and/or the body.
"""
return self._active_date
@active_date.setter
def active_date(self, value):
self._active_date = value
@active_date.deleter
def active_date(self):
self._active_date = None
@DomObj.title.setter
def title(self, value):
u""" Set the title and mark the document and the heading dirty """
# TODO these setter should be rewriten to also reuse code from DOM OBJ
if type(value) not in (unicode, str):
raise ValueError(u'Title must be a string.')
v = value
if type(v) == str:
v = u_decode(v)
self._title = v.strip()
self.set_dirty_heading()
@property
def tags(self):
u""" Tags of the current heading """
return self._tags
@tags.setter
def tags(self, value):
v = value
if type(v) in (unicode, str):
v = list(unicode(v))
if type(v) not in (list, tuple) and not isinstance(v, UserList):
v = list(unicode(v))
v = flatten_list(v)
v_decoded = []
for i in v:
if type(i) not in (unicode, str):
raise ValueError(u'Found non string value in tags! %s' % unicode(i))
if u':' in i:
raise ValueError(u'Found non allowed character in tag! %s' % i)
i_tmp = i.strip().replace(' ', '_').replace('\t', '_')
if type(i) == str:
i_tmp = u_decode(i)
v_decoded.append(i_tmp)
self._tags[:] = v_decoded
@tags.deleter
def tags(self):
self.tags = []
@property
def checkboxes(self):
u""" All checkboxes in current heading """
return self._checkboxes
@checkboxes.setter
def checkboxes(self, value):
self._checkboxes[:] = value
@checkboxes.deleter
def checkboxes(self):
del self.checkboxes[:]
class HeadingList(DomObjList):
u"""
A Heading List just contains headings. It's used for documents to store top
level headings and for headings to store subheadings.
A Heading List must be linked to a Document or Heading!
See documenatation of MultiPurposeList for more information.
"""
def __init__(self, initlist=None, obj=None):
"""
:initlist: Initial data
:obj: Link to a concrete Heading or Document object
"""
# it's not necessary to register a on_change hook because the heading
# list will itself take care of marking headings dirty or adding
# headings to the deleted headings list
DomObjList.__init__(self, initlist, obj)
@classmethod
def is_heading(cls, obj):
# TODO no need to make this or is_domobj a class methods
return HeadingList.is_domobj(obj)
def _get_document(self):
if self.__class__.is_heading(self._obj):
return self._obj._document
return self._obj
def _add_to_deleted_headings(self, item):
u"""
Serialize headings so that all subheadings are also marked for deletion
"""
if not self._get_document():
# HeadingList has not yet been associated
return
if type(item) in (list, tuple) or isinstance(item, UserList):
for i in flatten_list(item):
self._add_to_deleted_headings(i)
else:
self._get_document()._deleted_headings.append(
item.copy(including_children=False))
self._add_to_deleted_headings(item.children)
self._get_document().set_dirty_document()
def _associate_heading(
self, heading, previous_sibling, next_sibling,
children=False, taint=True):
"""
:heading: The heading or list to associate with the current heading
:previous_sibling: The previous sibling of the current heading. If
heading is a list the first heading will be
connected with the previous sibling and the last
heading with the next sibling. The items in between
will be linked with one another.
:next_sibling: The next sibling of the current heading. If
heading is a list the first heading will be
connected with the previous sibling and the last
heading with the next sibling. The items in between
will be linked with one another.
:children: Marks whether children are processed in the current
iteration or not (should not be use, it's set
automatically)
:taint: If not True, the heading is not marked dirty at the end
of the association process and its orig_start and
orig_len values are not updated.
"""
# TODO this method should be externalized and moved to the Heading class
# TODO should this method work with slice?
if type(heading) in (list, tuple) or isinstance(heading, UserList):
prev = previous_sibling
current = None
for _next in flatten_list(heading):
if current:
self._associate_heading(
current, prev, _next,
children=children, taint=taint)
prev = current
current = _next
if current:
self._associate_heading(
current, prev, next_sibling,
children=children, taint=taint)
else:
if taint:
heading._orig_start = None
heading._orig_len = None
d = self._get_document()
if heading._document != d:
heading._document = d
if not children:
# connect heading with previous and next headings
heading._previous_sibling = previous_sibling
if previous_sibling:
previous_sibling._next_sibling = heading
heading._next_sibling = next_sibling
if next_sibling:
next_sibling._previous_sibling = heading
if d == self._obj:
# self._obj is a Document
heading._parent = None
elif heading._parent != self._obj:
# self._obj is a Heading
heading._parent = self._obj
if taint:
heading.set_dirty()
self._associate_heading(
heading.children, None, None,
children=True, taint=taint)
def __setitem__(self, i, item):
if isinstance(i, slice):
start, stop, step = i.indices(len(self))
items = item
if self.__class__.is_heading(items):
items = (items, )
items = flatten_list(items)
for head in items:
if not self.__class__.is_heading(head):
raise ValueError(u'List contains items that are not a heading!')
self._add_to_deleted_headings(self[i])
self._associate_heading(
items,
self[start - 1] if start - 1 >= 0 else None,
self[stop] if stop < len(self) else None)
MultiPurposeList.__setitem__(self, i, items)
else:
if not self.__class__.is_heading(item):
raise ValueError(u'Item is not a heading!')
if item in self:
raise ValueError(u'Heading is already part of this list!')
self._add_to_deleted_headings(self[i])
self._associate_heading(
item,
self[i - 1] if i - 1 >= 0 else None,
self[i + 1] if i + 1 < len(self) else None)
MultiPurposeList.__setitem__(self, i, item)
def __delitem__(self, i, taint=True):
# TODO refactor this item, it works the same in dom_obj except taint?
if isinstance(i, slice):
items = self[i]
if items:
first = items[0]
last = items[-1]
if first.previous_sibling:
first.previous_sibling._next_sibling = last.next_sibling
if last.next_sibling:
last.next_sibling._previous_sibling = first.previous_sibling
if taint:
self._add_to_deleted_headings(items)
MultiPurposeList.__delitem__(self, i)
else:
item = self[i]
if item.previous_sibling:
item.previous_sibling._next_sibling = item.next_sibling
if item.next_sibling:
item.next_sibling._previous_sibling = item.previous_sibling
if taint:
self._add_to_deleted_headings(item)
MultiPurposeList.__delitem__(self, i)
def __iadd__(self, other):
o = other
if self.__class__.is_heading(o):
o = (o, )
for item in flatten_list(o):
if not self.__class__.is_heading(item):
raise ValueError(u'List contains items that are not a heading!')
self._associate_heading(o, self[-1] if len(self) > 0 else None, None)
return MultiPurposeList.__iadd__(self, o)
def append(self, item, taint=True):
if not self.__class__.is_heading(item):
raise ValueError(u'Item is not a heading!')
if item in self:
raise ValueError(u'Heading is already part of this list!')
self._associate_heading(
item, self[-1] if len(self) > 0 else None,
None, taint=taint)
MultiPurposeList.append(self, item)
def insert(self, i, item, taint=True):
self._associate_heading(
item,
self[i - 1] if i - 1 >= 0 and i - 1 < len(self) else None,
self[i] if i >= 0 and i < len(self) else None, taint=taint)
MultiPurposeList.insert(self, i, item)
def pop(self, i=-1):
item = self[i]
self._add_to_deleted_headings(item)
del self[i]
return item
def extend(self, other):
o = other
if self.__class__.is_heading(o):
o = (o, )
for item in o:
if not self.__class__.is_heading(item):
raise ValueError(u'List contains items that are not a heading!')
self._associate_heading(o, self[-1] if len(self) > 0 else None, None)
MultiPurposeList.extend(self, o)
# vim: set noexpandtab:

View file

@ -1,296 +0,0 @@
# -*- coding: utf-8 -*-
u"""
OrgDate
~~~~~~~~~~~~~~~~~~
This module contains all date/time/timerange representations that exist in
orgmode.
There exist three different kinds:
* OrgDate: is similar to a date object in python and it looks like
'2011-09-07 Wed'.
* OrgDateTime: is similar to a datetime object in python and looks like
'2011-09-07 Wed 10:30'
* OrgTimeRange: indicates a range of time. It has a start and and end date:
* <2011-09-07 Wed>--<2011-09-08 Fri>
* <2011-09-07 Wed 10:00-13:00>
All OrgTime oblects can be active or inactive.
"""
import datetime
import re
from orgmode.py3compat.encode_compatibility import *
# <2011-09-12 Mon>
_DATE_REGEX = re.compile(r"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w>", re.UNICODE)
# [2011-09-12 Mon]
_DATE_PASSIVE_REGEX = re.compile(r"\[(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w\]", re.UNICODE)
# <2011-09-12 Mon 10:20>
_DATETIME_REGEX = re.compile(
r"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w (\d{1,2}):(\d\d)>", re.UNICODE)
# [2011-09-12 Mon 10:20]
_DATETIME_PASSIVE_REGEX = re.compile(
r"\[(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w (\d{1,2}):(\d\d)\]", re.UNICODE)
# <2011-09-12 Mon>--<2011-09-13 Tue>
_DATERANGE_REGEX = re.compile(
# <2011-09-12 Mon>--
r"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w>--"
# <2011-09-13 Tue>
"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w>", re.UNICODE)
# <2011-09-12 Mon 10:00>--<2011-09-12 Mon 11:00>
_DATETIMERANGE_REGEX = re.compile(
# <2011-09-12 Mon 10:00>--
r"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w (\d\d):(\d\d)>--"
# <2011-09-12 Mon 11:00>
"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w (\d\d):(\d\d)>", re.UNICODE)
# <2011-09-12 Mon 10:00--12:00>
_DATETIMERANGE_SAME_DAY_REGEX = re.compile(
r"<(\d\d\d\d)-(\d\d)-(\d\d) [A-Z]\w\w (\d\d):(\d\d)-(\d\d):(\d\d)>", re.UNICODE)
def get_orgdate(data):
u"""
Parse the given data (can be a string or list). Return an OrgDate if data
contains a string representation of an OrgDate; otherwise return None.
data can be a string or a list containing strings.
"""
# TODO maybe it should be checked just for iterable? Does it affect here if
# in base __getitem__(slice(i,j)) doesn't return a list but userlist...
if isinstance(data, list):
return _findfirst(_text2orgdate, data)
else:
return _text2orgdate(data)
# if no dates found
return None
def _findfirst(f, seq):
u"""
Return first item in sequence seq where f(item) == True.
TODO: this is a general help function and it should be moved somewhere
else; preferably into the standard lib :)
"""
for found in (f(item) for item in seq if f(item)):
return found
def _text2orgdate(string):
u"""
Transform the given string into an OrgDate.
Return an OrgDate if data contains a string representation of an OrgDate;
otherwise return None.
"""
# handle active datetime with same day
result = _DATETIMERANGE_SAME_DAY_REGEX.search(string)
if result:
try:
(syear, smonth, sday, shour, smin, ehour, emin) = \
[int(m) for m in result.groups()]
start = datetime.datetime(syear, smonth, sday, shour, smin)
end = datetime.datetime(syear, smonth, sday, ehour, emin)
return OrgTimeRange(True, start, end)
except BaseException:
return None
# handle active datetime
result = _DATETIMERANGE_REGEX.search(string)
if result:
try:
tmp = [int(m) for m in result.groups()]
(syear, smonth, sday, shour, smin, eyear, emonth, eday, ehour, emin) = tmp
start = datetime.datetime(syear, smonth, sday, shour, smin)
end = datetime.datetime(eyear, emonth, eday, ehour, emin)
return OrgTimeRange(True, start, end)
except BaseException:
return None
# handle active datetime
result = _DATERANGE_REGEX.search(string)
if result:
try:
tmp = [int(m) for m in result.groups()]
syear, smonth, sday, eyear, emonth, ehour = tmp
start = datetime.date(syear, smonth, sday)
end = datetime.date(eyear, emonth, ehour)
return OrgTimeRange(True, start, end)
except BaseException:
return None
# handle active datetime
result = _DATETIME_REGEX.search(string)
if result:
try:
year, month, day, hour, minutes = [int(m) for m in result.groups()]
return OrgDateTime(True, year, month, day, hour, minutes)
except BaseException:
return None
# handle passive datetime
result = _DATETIME_PASSIVE_REGEX.search(string)
if result:
try:
year, month, day, hour, minutes = [int(m) for m in result.groups()]
return OrgDateTime(False, year, month, day, hour, minutes)
except BaseException:
return None
# handle passive dates
result = _DATE_PASSIVE_REGEX.search(string)
if result:
try:
year, month, day = [int(m) for m in result.groups()]
return OrgDate(False, year, month, day)
except BaseException:
return None
# handle active dates
result = _DATE_REGEX.search(string)
if result:
try:
year, month, day = [int(m) for m in result.groups()]
return OrgDate(True, year, month, day)
except BaseException:
return None
class OrgDate(datetime.date):
u"""
OrgDate represents a normal date like '2011-08-29 Mon'.
OrgDates can be active or inactive.
NOTE: date is immutable. Thats why there needs to be __new__().
See: http://docs.python.org/reference/datamodel.html#object.__new__
"""
def __init__(self, active, year, month, day):
self.active = active
pass
def __new__(cls, active, year, month, day):
return datetime.date.__new__(cls, year, month, day)
def __unicode__(self):
u"""
Return a string representation.
"""
if self.active:
return self.strftime(u'<%Y-%m-%d %a>')
else:
return self.strftime(u'[%Y-%m-%d %a]')
def __str__(self):
return u_encode(self.__unicode__())
def strftime(self, fmt):
return u_decode(datetime.date.strftime(self, u_encode(fmt)))
class OrgDateTime(datetime.datetime):
u"""
OrgDateTime represents a normal date like '2011-08-29 Mon'.
OrgDateTime can be active or inactive.
NOTE: date is immutable. Thats why there needs to be __new__().
See: http://docs.python.org/reference/datamodel.html#object.__new__
"""
def __init__(self, active, year, month, day, hour, mins):
self.active = active
def __new__(cls, active, year, month, day, hour, minute):
return datetime.datetime.__new__(cls, year, month, day, hour, minute)
def __unicode__(self):
u"""
Return a string representation.
"""
if self.active:
return self.strftime(u'<%Y-%m-%d %a %H:%M>')
else:
return self.strftime(u'[%Y-%m-%d %a %H:%M]')
def __str__(self):
return u_encode(self.__unicode__())
def strftime(self, fmt):
return u_decode(datetime.datetime.strftime(self, u_encode(fmt)))
class OrgTimeRange(object):
u"""
OrgTimeRange objects have a start and an end. Start and ent can be date
or datetime. Start and end have to be the same type.
OrgTimeRange objects look like this:
* <2011-09-07 Wed>--<2011-09-08 Fri>
* <2011-09-07 Wed 20:00>--<2011-09-08 Fri 10:00>
* <2011-09-07 Wed 10:00-13:00>
"""
def __init__(self, active, start, end):
u"""
stat and end must be datetime.date or datetime.datetime (both of the
same type).
"""
super(OrgTimeRange, self).__init__()
self.start = start
self.end = end
self.active = active
def __unicode__(self):
u"""
Return a string representation.
"""
# active
if self.active:
# datetime
if isinstance(self.start, datetime.datetime):
# if start and end are on same the day
if self.start.year == self.end.year and\
self.start.month == self.end.month and\
self.start.day == self.end.day:
return u"<%s-%s>" % (
self.start.strftime(u'%Y-%m-%d %a %H:%M'),
self.end.strftime(u'%H:%M'))
else:
return u"<%s>--<%s>" % (
self.start.strftime(u'%Y-%m-%d %a %H:%M'),
self.end.strftime(u'%Y-%m-%d %a %H:%M'))
# date
if isinstance(self.start, datetime.date):
return u"<%s>--<%s>" % (
self.start.strftime(u'%Y-%m-%d %a'),
self.end.strftime(u'%Y-%m-%d %a'))
# inactive
else:
if isinstance(self.start, datetime.datetime):
# if start and end are on same the day
if self.start.year == self.end.year and\
self.start.month == self.end.month and\
self.start.day == self.end.day:
return u"[%s-%s]" % (
self.start.strftime(u'%Y-%m-%d %a %H:%M'),
self.end.strftime(u'%H:%M'))
else:
return u"[%s]--[%s]" % (
self.start.strftime(u'%Y-%m-%d %a %H:%M'),
self.end.strftime(u'%Y-%m-%d %a %H:%M'))
if isinstance(self.start, datetime.date):
return u"[%s]--[%s]" % (
self.start.strftime(u'%Y-%m-%d %a'),
self.end.strftime(u'%Y-%m-%d %a'))
def __str__(self):
return u_encode(self.__unicode__())
# vim: set noexpandtab:

View file

@ -1,173 +0,0 @@
# -*- coding: utf-8 -*-
import vim
from orgmode.keybinding import Command, Plug, Keybinding
from orgmode.keybinding import MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT
from orgmode.py3compat.encode_compatibility import *
def register_menu(f):
def r(*args, **kwargs):
p = f(*args, **kwargs)
def create(entry):
if isinstance(entry, Submenu) or isinstance(entry, Separator) \
or isinstance(entry, ActionEntry):
entry.create()
if hasattr(p, u'menu'):
if isinstance(p.menu, list) or isinstance(p.menu, tuple):
for e in p.menu:
create(e)
else:
create(p.menu)
return p
return r
def add_cmd_mapping_menu(plugin, name, function, key_mapping, menu_desrc):
u"""A helper function to create a vim command and keybinding and add these
to the menu for a given plugin.
:plugin: the plugin to operate on.
:name: the name of the vim command (and the name of the Plug)
:function: the actual python function which is called when executing the
vim command.
:key_mapping: the keymapping to execute the command.
:menu_desrc: the text which appears in the menu.
"""
cmd = Command(name, function)
keybinding = Keybinding(key_mapping, Plug(name, cmd))
plugin.commands.append(cmd)
plugin.keybindings.append(keybinding)
plugin.menu + ActionEntry(menu_desrc, keybinding)
class Submenu(object):
u""" Submenu entry """
def __init__(self, name, parent=None):
object.__init__(self)
self.name = name
self.parent = parent
self._children = []
def __add__(self, entry):
if entry not in self._children:
self._children.append(entry)
entry.parent = self
return entry
def __sub__(self, entry):
if entry in self._children:
idx = self._children.index(entry)
del self._children[idx]
@property
def children(self):
return self._children[:]
def get_menu(self):
n = self.name.replace(u' ', u'\\ ')
if self.parent:
return u'%s.%s' % (self.parent.get_menu(), n)
return n
def create(self):
for c in self.children:
c.create()
def __str__(self):
res = self.name
for c in self.children:
res += str(c)
return res
class Separator(object):
u""" Menu entry for a Separator """
def __init__(self, parent=None):
object.__init__(self)
self.parent = parent
def __unicode__(self):
return u'-----'
def __str__(self):
return u_encode(self.__unicode__())
def create(self):
if self.parent:
menu = self.parent.get_menu()
vim.command(u_encode(u'menu %s.-%s- :' % (menu, id(self))))
class ActionEntry(object):
u""" ActionEntry entry """
def __init__(self, lname, action, rname=None, mode=MODE_NORMAL, parent=None):
u"""
:lname: menu title on the left hand side of the menu entry
:action: could be a vim command sequence or an actual Keybinding
:rname: menu title that appears on the right hand side of the menu
entry. If action is a Keybinding this value ignored and is
taken from the Keybinding
:mode: defines when the menu entry/action is executable
:parent: the parent instance of this object. The only valid parent is Submenu
"""
object.__init__(self)
self._lname = lname
self._action = action
self._rname = rname
if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT):
raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT')
self._mode = mode
self.parent = parent
def __str__(self):
return u'%s\t%s' % (self.lname, self.rname)
@property
def lname(self):
return self._lname.replace(u' ', u'\\ ')
@property
def action(self):
if isinstance(self._action, Keybinding):
return self._action.action
return self._action
@property
def rname(self):
if isinstance(self._action, Keybinding):
return self._action.key.replace(u'<Tab>', u'Tab')
return self._rname
@property
def mode(self):
if isinstance(self._action, Keybinding):
return self._action.mode
return self._mode
def create(self):
menucmd = u':%smenu ' % self.mode
menu = u''
cmd = u''
if self.parent:
menu = self.parent.get_menu()
menu += u'.%s' % self.lname
if self.rname:
cmd = u'%s %s<Tab>%s %s' % (menucmd, menu, self.rname, self.action)
else:
cmd = u'%s %s %s' % (menucmd, menu, self.action)
vim.command(u_encode(cmd))
# keybindings should be stored in the plugin.keybindings property and be registered by the appropriate keybinding registrar
#if isinstance(self._action, Keybinding):
# self._action.create()
# vim: set noexpandtab:

View file

@ -1,314 +0,0 @@
# -*- coding: utf-8 -*-
from datetime import date
import os
import glob
import vim
from orgmode._vim import ORGMODE, get_bufnumber, get_bufname, echoe
from orgmode import settings
from orgmode.keybinding import Keybinding, Plug, Command
from orgmode.menu import Submenu, ActionEntry, add_cmd_mapping_menu
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *
from orgmode.py3compat.py_py3_string import *
class Agenda(object):
u"""
The Agenda Plugin uses liborgmode.agenda to display the agenda views.
The main task is to format the agenda from liborgmode.agenda.
Also all the mappings: jump from agenda to todo, etc are realized here.
"""
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Agenda')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
@classmethod
def _switch_to(cls, bufname, vim_commands=None):
u"""
Swicht to the buffer with bufname.
A list of vim.commands (if given) gets executed as well.
TODO: this should be extracted and imporved to create an easy to use
way to create buffers/jump to buffers. Otherwise there are going to be
quite a few ways to open buffers in vimorgmode.
"""
cmds = [
u'botright split org:%s' % bufname,
u'setlocal buftype=nofile',
u'setlocal modifiable',
u'setlocal nonumber',
# call opendoc() on enter the original todo item
u'nnoremap <silent> <buffer> <CR> :exec "%s ORGMODE.plugins[u\'Agenda\'].opendoc()"<CR>' % VIM_PY_CALL,
u'nnoremap <silent> <buffer> <TAB> :exec "%s ORGMODE.plugins[u\'Agenda\'].opendoc(switch=True)"<CR>' % VIM_PY_CALL,
u'nnoremap <silent> <buffer> <S-CR> :exec "%s ORGMODE.plugins[u\'Agenda\'].opendoc(split=True)"<CR>' % VIM_PY_CALL,
# statusline
u'setlocal statusline=Org\\ %s' % bufname]
if vim_commands:
cmds.extend(vim_commands)
for cmd in cmds:
vim.command(u_encode(cmd))
@classmethod
def _get_agendadocuments(self):
u"""
Return the org documents of the agenda files; return None if no
agenda documents are defined.
TODO: maybe turn this into an decorator?
"""
# load org files of agenda
agenda_files = settings.get(u'org_agenda_files', u',')
if not agenda_files or agenda_files == ',':
echoe(
u"No org_agenda_files defined. Use :let "
u"g:org_agenda_files=['~/org/index.org'] to add "
u"files to the agenda view.")
return
return self._load_agendafiles(agenda_files)
@classmethod
def _load_agendafiles(self, agenda_files):
# glob for files in agenda_files
resolved_files = []
for f in agenda_files:
f = glob.glob(os.path.join(
os.path.expanduser(os.path.dirname(f)),
os.path.basename(f)))
resolved_files.extend(f)
agenda_files = [os.path.realpath(f) for f in resolved_files]
# load the agenda files into buffers
for agenda_file in agenda_files:
vim.command(u_encode(u'badd %s' % agenda_file.replace(" ", "\ ")))
# determine the buffer nr of the agenda files
agenda_nums = [get_bufnumber(fn) for fn in agenda_files]
# collect all documents of the agenda files and create the agenda
return [ORGMODE.get_document(i) for i in agenda_nums if i is not None]
@classmethod
def opendoc(cls, split=False, switch=False):
u"""
If you are in the agenda view jump to the document the item in the
current line belongs to. cls.line2doc is used for that.
:split: if True, open the document in a new split window.
:switch: if True, switch to another window and open the the document
there.
"""
row, _ = vim.current.window.cursor
try:
bufname, bufnr, destrow = cls.line2doc[row]
except:
return
# reload source file if it is not loaded
if get_bufname(bufnr) is None:
vim.command(u_encode(u'badd %s' % bufname))
bufnr = get_bufnumber(bufname)
tmp = cls.line2doc[row]
cls.line2doc[bufnr] = tmp
# delete old endry
del cls.line2doc[row]
if split:
vim.command(u_encode(u"sbuffer %s" % bufnr))
elif switch:
vim.command(u_encode(u"wincmd w"))
vim.command(u_encode(u"buffer %d" % bufnr))
else:
vim.command(u_encode(u"buffer %s" % bufnr))
vim.command(u_encode(u"normal! %dgg <CR>" % (destrow + 1)))
@classmethod
def list_next_week(cls):
agenda_documents = cls._get_agendadocuments()
if not agenda_documents:
return
cls.list_next_week_for(agenda_documents)
@classmethod
def list_next_week_for_buffer(cls):
agenda_documents = vim.current.buffer.name
loaded_agendafiles = cls._load_agendafiles([agenda_documents])
cls.list_next_week_for(loaded_agendafiles)
@classmethod
def list_next_week_for(cls, agenda_documents):
raw_agenda = ORGMODE.agenda_manager.get_next_week_and_active_todo(
agenda_documents)
# if raw_agenda is empty, return directly
if not raw_agenda:
vim.command('echom "All caught-up. No agenda or active todo next week."')
return
# create buffer at bottom
cmd = [u'setlocal filetype=orgagenda', ]
cls._switch_to(u'AGENDA', cmd)
# line2doc is a dic with the mapping:
# line in agenda buffer --> source document
# It's easy to jump to the right document this way
cls.line2doc = {}
# format text for agenda
last_date = raw_agenda[0].active_date
final_agenda = [u'Week Agenda:', unicode(last_date)]
for i, h in enumerate(raw_agenda):
# insert date information for every new date (not datetime)
if unicode(h.active_date)[1:11] != unicode(last_date)[1:11]:
today = date.today()
# insert additional "TODAY" string
if h.active_date.year == today.year and \
h.active_date.month == today.month and \
h.active_date.day == today.day:
section = unicode(h.active_date) + u" TODAY"
today_row = len(final_agenda) + 1
else:
section = unicode(h.active_date)
final_agenda.append(section)
# update last_date
last_date = h.active_date
bufname = os.path.basename(vim.buffers[h.document.bufnr].name)
bufname = bufname[:-4] if bufname.endswith(u'.org') else bufname
formated = u" %(bufname)s (%(bufnr)d) %(todo)s %(title)s" % {
'bufname': bufname,
'bufnr': h.document.bufnr,
'todo': h.todo,
'title': h.title
}
final_agenda.append(formated)
cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)
# show agenda
vim.current.buffer[:] = [u_encode(i) for i in final_agenda]
vim.command(u_encode(u'setlocal nomodifiable conceallevel=2 concealcursor=nc'))
# try to jump to the positon of today
try:
vim.command(u_encode(u'normal! %sgg<CR>' % today_row))
except:
pass
@classmethod
def list_all_todos(cls, current_buffer=False):
u""" List all todos in one buffer.
Args:
current_buffer (bool):
False: all agenda files
True: current org_file
"""
if current_buffer:
agenda_documents = vim.current.buffer.name
loaded_agendafiles = cls._load_agendafiles([agenda_documents])
else:
loaded_agendafiles = cls._get_agendadocuments()
if not loaded_agendafiles:
return
raw_agenda = ORGMODE.agenda_manager.get_todo(loaded_agendafiles)
cls.line2doc = {}
# create buffer at bottom
cmd = [u'setlocal filetype=orgagenda']
cls._switch_to(u'AGENDA', cmd)
# format text of agenda
final_agenda = []
for i, h in enumerate(raw_agenda):
tmp = u"%s %s" % (h.todo, h.title)
final_agenda.append(tmp)
cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)
# show agenda
vim.current.buffer[:] = [u_encode(i) for i in final_agenda]
vim.command(u_encode(u'setlocal nomodifiable conceallevel=2 concealcursor=nc'))
@classmethod
def list_timeline(cls):
"""
List a timeline of the current buffer to get an overview of the
current file.
"""
raw_agenda = ORGMODE.agenda_manager.get_timestamped_items(
[ORGMODE.get_document()])
# create buffer at bottom
cmd = [u'setlocal filetype=orgagenda']
cls._switch_to(u'AGENDA', cmd)
cls.line2doc = {}
# format text of agenda
final_agenda = []
for i, h in enumerate(raw_agenda):
tmp = u"%s %s" % (h.todo, h.title)
final_agenda.append(tmp)
cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)
# show agenda
vim.current.buffer[:] = [u_encode(i) for i in final_agenda]
vim.command(u_encode(u'setlocal nomodifiable conceallevel=2 concealcursor=nc'))
def register(self):
u"""
Registration of the plugin.
Key bindings and other initialization should be done here.
"""
add_cmd_mapping_menu(
self,
name=u"OrgAgendaTodo",
function=u'%s ORGMODE.plugins[u"Agenda"].list_all_todos()' % VIM_PY_CALL,
key_mapping=u'<localleader>cat',
menu_desrc=u'Agenda for all TODOs'
)
add_cmd_mapping_menu(
self,
name=u"OrgBufferAgendaTodo",
function=u'%s ORGMODE.plugins[u"Agenda"].list_all_todos(current_buffer=True)' % VIM_PY_CALL,
key_mapping=u'<localleader>caT',
menu_desrc=u'Agenda for all TODOs based on current buffer'
)
add_cmd_mapping_menu(
self,
name=u"OrgAgendaWeek",
function=u'%s ORGMODE.plugins[u"Agenda"].list_next_week()' % VIM_PY_CALL,
key_mapping=u'<localleader>caa',
menu_desrc=u'Agenda for the week'
)
add_cmd_mapping_menu(
self,
name=u"OrgBufferAgendaWeek",
function=u'%s ORGMODE.plugins[u"Agenda"].list_next_week_for_buffer()' % VIM_PY_CALL,
key_mapping=u'<localleader>caA',
menu_desrc=u'Agenda for the week based on current buffer'
)
add_cmd_mapping_menu(
self,
name=u'OrgAgendaTimeline',
function=u'%s ORGMODE.plugins[u"Agenda"].list_timeline()' % VIM_PY_CALL,
key_mapping=u'<localleader>caL',
menu_desrc=u'Timeline for this buffer'
)
# vim: set noexpandtab:

View file

@ -1,318 +0,0 @@
# -*- coding: utf-8 -*-
import re
from datetime import timedelta, date, datetime
import operator
import vim
from orgmode._vim import ORGMODE, echom, insert_at_cursor, get_user_input
from orgmode import settings
from orgmode.keybinding import Keybinding, Plug
from orgmode.menu import Submenu, ActionEntry, add_cmd_mapping_menu
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *
from orgmode.py3compat.py_py3_string import *
class Date(object):
u"""
Handles all date and timestamp related tasks.
TODO: extend functionality (calendar, repetitions, ranges). See
http://orgmode.org/guide/Dates-and-Times.html#Dates-and-Times
"""
date_regex = r"\d\d\d\d-\d\d-\d\d"
datetime_regex = r"[A-Z]\w\w \d\d\d\d-\d\d-\d\d \d\d:\d\d>"
month_mapping = {
u'jan': 1, u'feb': 2, u'mar': 3, u'apr': 4, u'may': 5,
u'jun': 6, u'jul': 7, u'aug': 8, u'sep': 9, u'oct': 10, u'nov': 11,
u'dec': 12}
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Dates and Scheduling')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
# set speeddating format that is compatible with orgmode
try:
if int(vim.eval(u_encode(u'exists(":SpeedDatingFormat")'))) == 2:
vim.command(u_encode(u':1SpeedDatingFormat %Y-%m-%d %a'))
vim.command(u_encode(u':1SpeedDatingFormat %Y-%m-%d %a %H:%M'))
else:
echom(u'Speeddating plugin not installed. Please install it.')
except:
echom(u'Speeddating plugin not installed. Please install it.')
@classmethod
def _modify_time(cls, startdate, modifier):
u"""Modify the given startdate according to modifier. Return the new
date or datetime.
See http://orgmode.org/manual/The-date_002ftime-prompt.html
"""
if modifier is None or modifier == '' or modifier == '.':
return startdate
# rm crap from modifier
modifier = modifier.strip()
ops = {'-': operator.sub, '+': operator.add}
# check real date
date_regex = r"(\d\d\d\d)-(\d\d)-(\d\d)"
match = re.search(date_regex, modifier)
if match:
year, month, day = match.groups()
newdate = date(int(year), int(month), int(day))
# check abbreviated date, seperated with '-'
date_regex = u"(\d{1,2})-(\d+)-(\d+)"
match = re.search(date_regex, modifier)
if match:
year, month, day = match.groups()
newdate = date(2000 + int(year), int(month), int(day))
# check abbreviated date, seperated with '/'
# month/day
date_regex = u"(\d{1,2})/(\d{1,2})"
match = re.search(date_regex, modifier)
if match:
month, day = match.groups()
newdate = date(startdate.year, int(month), int(day))
# date should be always in the future
if newdate < startdate:
newdate = date(startdate.year + 1, int(month), int(day))
# check full date, seperated with 'space'
# month day year
# 'sep 12 9' --> 2009 9 12
date_regex = u"(\w\w\w) (\d{1,2}) (\d{1,2})"
match = re.search(date_regex, modifier)
if match:
gr = match.groups()
day = int(gr[1])
month = int(cls.month_mapping[gr[0]])
year = 2000 + int(gr[2])
newdate = date(year, int(month), int(day))
# check days as integers
date_regex = u"^(\d{1,2})$"
match = re.search(date_regex, modifier)
if match:
newday, = match.groups()
newday = int(newday)
if newday > startdate.day:
newdate = date(startdate.year, startdate.month, newday)
else:
# TODO: DIRTY, fix this
# this does NOT cover all edge cases
newdate = startdate + timedelta(days=28)
newdate = date(newdate.year, newdate.month, newday)
# check for full days: Mon, Tue, Wed, Thu, Fri, Sat, Sun
modifier_lc = modifier.lower()
match = re.search(u'mon|tue|wed|thu|fri|sat|sun', modifier_lc)
if match:
weekday_mapping = {
u'mon': 0, u'tue': 1, u'wed': 2, u'thu': 3,
u'fri': 4, u'sat': 5, u'sun': 6}
diff = (weekday_mapping[modifier_lc] - startdate.weekday()) % 7
# use next weeks weekday if current weekday is the same as modifier
if diff == 0:
diff = 7
newdate = startdate + timedelta(days=diff)
# check for days modifier with appended d
match = re.search(u'^(\+|-)(\d*)d', modifier)
if match:
op, days = match.groups()
newdate = ops[op](startdate, timedelta(days=int(days)))
# check for days modifier without appended d
match = re.search(u'^(\+|-)(\d*) |^(\+|-)(\d*)$', modifier)
if match:
groups = match.groups()
try:
op = groups[0]
days = int(groups[1])
except:
op = groups[2]
days = int(groups[3])
newdate = ops[op](startdate, timedelta(days=days))
# check for week modifier
match = re.search(u'^(\+|-)(\d+)w', modifier)
if match:
op, weeks = match.groups()
newdate = ops[op](startdate, timedelta(weeks=int(weeks)))
# check for month modifier
match = re.search(u'^(\+|-)(\d+)m', modifier)
if match:
op, months = match.groups()
newdate = date(startdate.year, ops[op](startdate.month, int(months)),
startdate.day)
# check for year modifier
match = re.search(u'^(\+|-)(\d*)y', modifier)
if match:
op, years = match.groups()
newdate = date(ops[op](startdate.year, int(years)), startdate.month,
startdate.day)
# check for month day
match = re.search(
u'(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (\d{1,2})',
modifier.lower())
if match:
month = cls.month_mapping[match.groups()[0]]
day = int(match.groups()[1])
newdate = date(startdate.year, int(month), int(day))
# date should be always in the future
if newdate < startdate:
newdate = date(startdate.year + 1, int(month), int(day))
# check abbreviated date, seperated with '/'
# month/day/year
date_regex = u"(\d{1,2})/(\d+)/(\d+)"
match = re.search(date_regex, modifier)
if match:
month, day, year = match.groups()
newdate = date(2000 + int(year), int(month), int(day))
# check for month day year
# sep 12 2011
match = re.search(
u'(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (\d{1,2}) (\d{1,4})',
modifier.lower())
if match:
month = int(cls.month_mapping[match.groups()[0]])
day = int(match.groups()[1])
if len(match.groups()[2]) < 4:
year = 2000 + int(match.groups()[2])
else:
year = int(match.groups()[2])
newdate = date(year, month, day)
# check for time: HH:MM
# '12:45' --> datetime(2006, 06, 13, 12, 45))
match = re.search(u'(\d{1,2}):(\d\d)$', modifier)
if match:
try:
startdate = newdate
except:
pass
return datetime(
startdate.year, startdate.month, startdate.day,
int(match.groups()[0]), int(match.groups()[1]))
try:
return newdate
except:
return startdate
@classmethod
def insert_timestamp(cls, active=True):
u"""
Insert a timestamp at the cursor position.
TODO: show fancy calendar to pick the date from.
TODO: add all modifier of orgmode.
"""
today = date.today()
msg = u''.join([
u'Inserting ',
unicode(u_decode(today.strftime(u'%Y-%m-%d %a'))),
u' | Modify date'])
modifier = get_user_input(msg)
# abort if the user canceled the input promt
if modifier is None:
return
newdate = cls._modify_time(today, modifier)
# format
if isinstance(newdate, datetime):
newdate = newdate.strftime(
u_decode(u_encode(u'%Y-%m-%d %a %H:%M')))
else:
newdate = newdate.strftime(
u_decode(u_encode(u'%Y-%m-%d %a')))
timestamp = u'<%s>' % newdate if active else u'[%s]' % newdate
insert_at_cursor(timestamp)
@classmethod
def insert_timestamp_with_calendar(cls, active=True):
u"""
Insert a timestamp at the cursor position.
Show fancy calendar to pick the date from.
TODO: add all modifier of orgmode.
"""
if int(vim.eval(u_encode(u'exists(":CalendarH")'))) != 2:
vim.command("echo 'Please install plugin Calendar to enable this function'")
return
vim.command("CalendarH")
# backup calendar_action
calendar_action = vim.eval("g:calendar_action")
vim.command("let g:org_calendar_action_backup = '" + calendar_action + "'")
vim.command("let g:calendar_action = 'CalendarAction'")
timestamp_template = u'<%s>' if active else u'[%s]'
# timestamp template
vim.command("let g:org_timestamp_template = '" + timestamp_template + "'")
def register(self):
u"""
Registration of the plugin.
Key bindings and other initialization should be done here.
"""
add_cmd_mapping_menu(
self,
name=u'OrgDateInsertTimestampActiveCmdLine',
key_mapping=u'<localleader>sa',
function=u'%s ORGMODE.plugins[u"Date"].insert_timestamp()' % VIM_PY_CALL,
menu_desrc=u'Timest&amp'
)
add_cmd_mapping_menu(
self,
name=u'OrgDateInsertTimestampInactiveCmdLine',
key_mapping='<localleader>si',
function=u'%s ORGMODE.plugins[u"Date"].insert_timestamp(False)' % VIM_PY_CALL,
menu_desrc=u'Timestamp (&inactive)'
)
add_cmd_mapping_menu(
self,
name=u'OrgDateInsertTimestampActiveWithCalendar',
key_mapping=u'<localleader>pa',
function=u'%s ORGMODE.plugins[u"Date"].insert_timestamp_with_calendar()' % VIM_PY_CALL,
menu_desrc=u'Timestamp with Calendar'
)
add_cmd_mapping_menu(
self,
name=u'OrgDateInsertTimestampInactiveWithCalendar',
key_mapping=u'<localleader>pi',
function=u'%s ORGMODE.plugins[u"Date"].insert_timestamp_with_calendar(False)' % VIM_PY_CALL,
menu_desrc=u'Timestamp with Calendar(inactive)'
)
submenu = self.menu + Submenu(u'Change &Date')
submenu + ActionEntry(u'Day &Earlier', u'<C-x>', u'<C-x>')
submenu + ActionEntry(u'Day &Later', u'<C-a>', u'<C-a>')
# vim: set noexpandtab:

View file

@ -1,330 +0,0 @@
# -*- coding: utf-8 -*-
import vim
from orgmode._vim import echo, echom, echoe, ORGMODE, apply_count, repeat, insert_at_cursor, indent_orgmode
from orgmode import settings
from orgmode.menu import Submenu, Separator, ActionEntry, add_cmd_mapping_menu
from orgmode.keybinding import Keybinding, Plug, Command
from orgmode.liborgmode.checkboxes import Checkbox
from orgmode.liborgmode.dom_obj import OrderListType
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.py_py3_string import *
from orgmode.py3compat.unicode_compatibility import *
class EditCheckbox(object):
u"""
Checkbox plugin.
"""
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Edit Checkbox')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
@classmethod
def new_checkbox(cls, below=None, plain=None):
'''
if below is:
True -> create new list below current line
False/None -> create new list above current line
if plain is:
True -> create a plainlist item
False/None -> create an empty checkbox
'''
d = ORGMODE.get_document()
h = d.current_heading()
if h is None:
return
# init checkboxes for current heading
h.init_checkboxes()
c = h.current_checkbox()
nc = Checkbox()
nc._heading = h
# default checkbox level
level = h.level + 1
start = vim.current.window.cursor[0] - 1
# if no checkbox is found, insert at current line with indent level=1
if c is None:
h.checkboxes.append(nc)
else:
l = c.get_parent_list()
idx = c.get_index_in_parent_list()
if l is not None and idx is not None:
l.insert(idx + (1 if below else 0), nc)
# workaround for broken associations, Issue #165
nc._parent = c.parent
if below:
if c.next_sibling:
c.next_sibling._previous_sibling = nc
nc._next_sibling = c.next_sibling
c._next_sibling = nc
nc._previous_sibling = c
else:
if c.previous_sibling:
c.previous_sibling._next_sibling = nc
nc._next_sibling = c
nc._previous_sibling = c.previous_sibling
c._previous_sibling = nc
t = c.type
# increase key for ordered lists
if t[-1] in OrderListType:
try:
num = int(t[:-1]) + (1 if below else -1)
if num < 0:
# don't decrease to numbers below zero
echom(u"Can't decrement further than '0'")
return
t = '%d%s' % (num, t[-1])
except ValueError:
try:
char = ord(t[:-1]) + (1 if below else -1)
if below:
if char == 91:
# stop incrementing at Z (90)
echom(u"Can't increment further than 'Z'")
return
elif char == 123:
# increment from z (122) to A
char = 65
else:
if char == 96:
# stop decrementing at a (97)
echom(u"Can't decrement further than 'a'")
return
elif char == 64:
# decrement from A (65) to z
char = 122
t = u'%s%s' % (chr(char), t[-1])
except ValueError:
pass
nc.type = t
level = c.level
if below:
start = c.end_of_last_child
else:
start = c.start
if plain: # only create plainlist item when requested
nc.status = None
nc.level = level
if below:
start += 1
# vim's buffer behave just opposite to Python's list when inserting a
# new item. The new entry is appended in vim put prepended in Python!
vim.current.buffer.append("") # workaround for neovim
vim.current.buffer[start:start] = [unicode(nc)]
del vim.current.buffer[-1] # restore from workaround for neovim
# update checkboxes status
cls.update_checkboxes_status()
# do not start insert upon adding new checkbox, Issue #211
if int(settings.get(u'org_prefer_insert_mode', u'1')):
vim.command(u_encode(u'exe "normal %dgg"|startinsert!' % (start + 1, )))
else:
vim.command(u_encode(u'exe "normal %dgg$"' % (start + 1, )))
@classmethod
def toggle(cls, checkbox=None):
u"""
Toggle the checkbox given in the parameter.
If the checkbox is not given, it will toggle the current checkbox.
"""
d = ORGMODE.get_document()
current_heading = d.current_heading()
# init checkboxes for current heading
if current_heading is None:
return
current_heading = current_heading.init_checkboxes()
if checkbox is None:
# get current_checkbox
c = current_heading.current_checkbox()
# no checkbox found
if c is None:
cls.update_checkboxes_status()
return
else:
c = checkbox
if c.status == Checkbox.STATUS_OFF or c.status is None:
# set checkbox status on if all children are on
if c.all_children_status()[0] == 0 or c.are_children_all(Checkbox.STATUS_ON):
c.toggle()
d.write_checkbox(c)
elif c.status is None:
c.status = Checkbox.STATUS_OFF
d.write_checkbox(c)
elif c.status == Checkbox.STATUS_ON:
if c.all_children_status()[0] == 0 or c.is_child_one(Checkbox.STATUS_OFF):
c.toggle()
d.write_checkbox(c)
elif c.status == Checkbox.STATUS_INT:
# can't toggle intermediate state directly according to emacs orgmode
pass
# update checkboxes status
cls.update_checkboxes_status()
@classmethod
def _update_subtasks(cls):
d = ORGMODE.get_document()
h = d.current_heading()
# init checkboxes for current heading
h.init_checkboxes()
# update heading subtask info
c = h.first_checkbox
if c is None:
return
total, on = c.all_siblings_status()
h.update_subtasks(total, on)
# update all checkboxes under current heading
cls._update_checkboxes_subtasks(c)
@classmethod
def _update_checkboxes_subtasks(cls, checkbox):
# update checkboxes
for c in checkbox.all_siblings():
if c.children:
total, on = c.first_child.all_siblings_status()
c.update_subtasks(total, on)
cls._update_checkboxes_subtasks(c.first_child)
@classmethod
def update_checkboxes_status(cls):
d = ORGMODE.get_document()
h = d.current_heading()
if h is None:
return
# init checkboxes for current heading
h.init_checkboxes()
cls._update_checkboxes_status(h.first_checkbox)
cls._update_subtasks()
@classmethod
def _update_checkboxes_status(cls, checkbox=None):
u""" helper function for update checkboxes status
:checkbox: The first checkbox of this indent level
:return: The status of the parent checkbox
"""
if checkbox is None:
return
status_off, status_on, status_int, total = 0, 0, 0, 0
# update all top level checkboxes' status
for c in checkbox.all_siblings():
current_status = c.status
# if this checkbox is not leaf, its status should determine by all its children
if c.all_children_status()[0] > 0:
current_status = cls._update_checkboxes_status(c.first_child)
# don't update status if the checkbox has no status
if c.status is None:
current_status = None
# the checkbox needs to have status
else:
total += 1
# count number of status in this checkbox level
if current_status == Checkbox.STATUS_OFF:
status_off += 1
elif current_status == Checkbox.STATUS_ON:
status_on += 1
elif current_status == Checkbox.STATUS_INT:
status_int += 1
# write status if any update
if current_status is not None and c.status != current_status:
c.status = current_status
d = ORGMODE.get_document()
d.write_checkbox(c)
parent_status = Checkbox.STATUS_INT
# all silbing checkboxes are off status
if total == 0:
pass
elif status_off == total:
parent_status = Checkbox.STATUS_OFF
# all silbing checkboxes are on status
elif status_on == total:
parent_status = Checkbox.STATUS_ON
# one silbing checkbox is on or int status
elif status_on != 0 or status_int != 0:
parent_status = Checkbox.STATUS_INT
# other cases
else:
parent_status = None
return parent_status
def register(self):
u"""
Registration of the plugin.
Key bindings and other initialization should be done here.
"""
# default setting if it is not already set.
# checkbox related operation
add_cmd_mapping_menu(
self,
name=u'OrgCheckBoxNewAbove',
function=u'%s ORGMODE.plugins[u"EditCheckbox"].new_checkbox()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>cN',
menu_desrc=u'New CheckBox Above'
)
add_cmd_mapping_menu(
self,
name=u'OrgCheckBoxNewBelow',
function=u'%s ORGMODE.plugins[u"EditCheckbox"].new_checkbox(below=True)<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>cn',
menu_desrc=u'New CheckBox Below'
)
add_cmd_mapping_menu(
self,
name=u'OrgCheckBoxToggle',
function=u':silent! %s ORGMODE.plugins[u"EditCheckbox"].toggle()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>cc',
menu_desrc=u'Toggle Checkbox'
)
add_cmd_mapping_menu(
self,
name=u'OrgCheckBoxUpdate',
function=u':silent! %s ORGMODE.plugins[u"EditCheckbox"].update_checkboxes_status()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>c#',
menu_desrc=u'Update Subtasks'
)
# plainlist related operation
add_cmd_mapping_menu(
self,
name=u'OrgPlainListItemNewAbove',
function=u'%s ORGMODE.plugins[u"EditCheckbox"].new_checkbox(plain=True)<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>cL',
menu_desrc=u'New PlainList Item Above'
)
add_cmd_mapping_menu(
self,
name=u'OrgPlainListItemNewBelow',
function=u'%s ORGMODE.plugins[u"EditCheckbox"].new_checkbox(below=True, plain=True)<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>cl',
menu_desrc=u'New PlainList Item Below'
)
# vim: set noexpandtab:

View file

@ -1,430 +0,0 @@
# -*- coding: utf-8 -*-
import vim
from orgmode._vim import ORGMODE, apply_count, repeat, realign_tags
from orgmode import settings
from orgmode.exceptions import HeadingDomError
from orgmode.keybinding import Keybinding, Plug, MODE_INSERT, MODE_NORMAL
from orgmode.menu import Submenu, Separator, ActionEntry
from orgmode.liborgmode.base import Direction
from orgmode.liborgmode.headings import Heading
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.py_py3_string import *
class EditStructure(object):
u""" EditStructure plugin """
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'&Edit Structure')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
@classmethod
def new_heading(cls, below=None, insert_mode=False, end_of_last_child=False):
u"""
:below: True, insert heading below current heading, False,
insert heading above current heading, None, special
behavior for insert mode, use the current text as
heading
:insert_mode: True, if action is performed in insert mode
:end_of_last_child: True, insert heading at the end of last child,
otherwise the newly created heading will "take
over" the current heading's children
"""
d = ORGMODE.get_document()
current_heading = d.current_heading()
cursor = vim.current.window.cursor[:]
if not current_heading:
# the user is in meta data region
pos = cursor[0] - 1
heading = Heading(title=d.meta_information[pos], body=d.meta_information[pos + 1:])
d.headings.insert(0, heading)
del d.meta_information[pos:]
d.write()
vim.command(u_encode(u'exe "normal %dgg"|startinsert!' % (heading.start_vim, )))
return heading
# check for plain list(checkbox)
current_heading.init_checkboxes()
c = current_heading.current_checkbox()
if c is not None:
ORGMODE.plugins[u"EditCheckbox"].new_checkbox(below, not c.status)
return
heading = Heading(level=current_heading.level)
# it's weird but this is the behavior of original orgmode
if below is None:
below = cursor[1] != 0 or end_of_last_child
# insert newly created heading
l = current_heading.get_parent_list()
idx = current_heading.get_index_in_parent_list()
if l is not None and idx is not None:
l.insert(idx + (1 if below else 0), heading)
else:
raise HeadingDomError(u'Current heading is not properly linked in DOM')
if below and not end_of_last_child:
# append heading at the end of current heading and also take
# over the children of current heading
for child in current_heading.children:
heading.children.append(child, taint=False)
current_heading.children.remove_slice(
0, len(current_heading.children),
taint=False)
# if cursor is currently on a heading, insert parts of it into the
# newly created heading
if insert_mode and cursor[1] != 0 and cursor[0] == current_heading.start_vim:
offset = cursor[1] - current_heading.level - 1 - (
len(current_heading.todo) + 1 if current_heading.todo else 0)
if offset < 0:
offset = 0
if int(settings.get(u'org_improve_split_heading', u'1')) and \
offset > 0 and len(current_heading.title) == offset + 1 \
and current_heading.title[offset - 1] not in (u' ', u'\t'):
offset += 1
heading.title = current_heading.title[offset:]
current_heading.title = current_heading.title[:offset]
heading.body = current_heading.body[:]
current_heading.body = []
d.write()
# do not start insert upon adding new headings, unless already in insert mode. Issue #211
if int(settings.get(u'org_prefer_insert_mode', u'1')) or insert_mode:
vim.command(u_encode(u'exe "normal %dgg"|startinsert!' % (heading.start_vim, )))
else:
vim.command(u_encode(u'exe "normal %dgg$"' % (heading.start_vim, )))
# return newly created heading
return heading
@classmethod
def _append_heading(cls, heading, parent):
if heading.level <= parent.level:
raise ValueError('Heading level not is lower than parent level: %d ! > %d' % (heading.level, parent.level))
if parent.children and parent.children[-1].level < heading.level:
cls._append_heading(heading, parent.children[-1])
else:
parent.children.append(heading, taint=False)
@classmethod
def _change_heading_level(cls, level, including_children=True, on_heading=False, insert_mode=False):
u"""
Change level of heading realtively with or without including children.
:level: the number of levels to promote/demote heading
:including_children: True if should should be included in promoting/demoting
:on_heading: True if promoting/demoting should only happen when the cursor is on the heading
:insert_mode: True if vim is in insert mode
"""
# TODO : current promote and demote works for only headings. Since
# checkboxes also have tree structure. We should think of
# expanding the functionality of promoting and demoting to
# checkboxes as well
d = ORGMODE.get_document()
current_heading = d.current_heading()
if not current_heading or on_heading and current_heading.start_vim != vim.current.window.cursor[0]:
# TODO figure out the actually pressed keybinding and feed these
# keys instead of making keys up like this
if level > 0:
if insert_mode:
vim.eval(u_encode(u'feedkeys("\<C-t>", "n")'))
elif including_children:
vim.eval(u_encode(u'feedkeys(">]]", "n")'))
elif on_heading:
vim.eval(u_encode(u'feedkeys(">>", "n")'))
else:
vim.eval(u_encode(u'feedkeys(">}", "n")'))
else:
if insert_mode:
vim.eval(u_encode(u'feedkeys("\<C-d>", "n")'))
elif including_children:
vim.eval(u_encode(u'feedkeys("<]]", "n")'))
elif on_heading:
vim.eval(u_encode(u'feedkeys("<<", "n")'))
else:
vim.eval(u_encode(u'feedkeys("<}", "n")'))
# return True because otherwise apply_count will not work
return True
# don't allow demotion below level 1
if current_heading.level == 1 and level < 1:
return False
# reduce level of demotion to a minimum heading level of 1
if (current_heading.level + level) < 1:
level = 1
def indent(heading, ic):
if not heading:
return
heading.level += level
if ic:
for child in heading.children:
indent(child, ic)
# save cursor position
c = vim.current.window.cursor[:]
# indent the promoted/demoted heading
indent_end_vim = current_heading.end_of_last_child_vim if including_children else current_heading.end_vim
indent(current_heading, including_children)
# when changing the level of a heading, its position in the DOM
# needs to be updated. It's likely that the heading gets a new
# parent and new children when demoted or promoted
# find new parent
p = current_heading.parent
pl = current_heading.get_parent_list()
ps = current_heading.previous_sibling
nhl = current_heading.level
if level > 0:
# demotion
# subheading or top level heading
if ps and nhl > ps.level:
pl.remove(current_heading, taint=False)
# find heading that is the new parent heading
oh = ps
h = ps
while nhl > h.level:
oh = h
if h.children:
h = h.children[-1]
else:
break
np = h if nhl > h.level else oh
# append current heading to new heading
np.children.append(current_heading, taint=False)
# if children are not included, distribute them among the
# parent heading and it's siblings
if not including_children:
for h in current_heading.children[:]:
if h and h.level <= nhl:
cls._append_heading(h, np)
current_heading.children.remove(h, taint=False)
else:
# promotion
if p and nhl <= p.level:
idx = current_heading.get_index_in_parent_list() + 1
# find the new parent heading
oh = p
h = p
while nhl <= h.level:
# append new children to current heading
for child in h.children[idx:]:
cls._append_heading(child, current_heading)
h.children.remove_slice(idx, len(h.children), taint=False)
idx = h.get_index_in_parent_list() + 1
if h.parent:
h = h.parent
else:
break
ns = oh.next_sibling
while ns and ns.level > current_heading.level:
nns = ns.next_sibling
cls._append_heading(ns, current_heading)
ns = nns
# append current heading to new parent heading / document
pl.remove(current_heading, taint=False)
if nhl > h.level:
h.children.insert(idx, current_heading, taint=False)
else:
d.headings.insert(idx, current_heading, taint=False)
d.write()
# restore cursor position
vim.current.window.cursor = (c[0], c[1] + level)
return True
@classmethod
@realign_tags
@repeat
@apply_count
def demote_heading(cls, including_children=True, on_heading=False, insert_mode=False):
if cls._change_heading_level(1, including_children=including_children, on_heading=on_heading, insert_mode=insert_mode):
if including_children:
return u'OrgDemoteSubtree'
return u'OrgDemoteHeading'
@classmethod
@realign_tags
@repeat
@apply_count
def promote_heading(cls, including_children=True, on_heading=False, insert_mode=False):
if cls._change_heading_level(-1, including_children=including_children, on_heading=on_heading, insert_mode=insert_mode):
if including_children:
return u'OrgPromoteSubtreeNormal'
return u'OrgPromoteHeadingNormal'
@classmethod
def _move_heading(cls, direction=Direction.FORWARD, including_children=True):
u""" Move heading up or down
:returns: heading or None
"""
d = ORGMODE.get_document()
current_heading = d.current_heading()
if not current_heading or \
(direction == Direction.FORWARD and not current_heading.next_sibling) or \
(direction == Direction.BACKWARD and not current_heading.previous_sibling):
return None
cursor_offset = vim.current.window.cursor[0] - (current_heading._orig_start + 1)
l = current_heading.get_parent_list()
if l is None:
raise HeadingDomError(u'Current heading is not properly linked in DOM')
if not including_children:
if current_heading.previous_sibling:
npl = current_heading.previous_sibling.children
for child in current_heading.children:
npl.append(child, taint=False)
elif current_heading.parent:
# if the current heading doesn't have a previous sibling it
# must be the first heading
np = current_heading.parent
for child in current_heading.children:
cls._append_heading(child, np)
else:
# if the current heading doesn't have a parent, its children
# must be added as top level headings to the document
npl = l
for child in current_heading.children[::-1]:
npl.insert(0, child, taint=False)
current_heading.children.remove_slice(0, len(current_heading.children), taint=False)
idx = current_heading.get_index_in_parent_list()
if idx is None:
raise HeadingDomError(u'Current heading is not properly linked in DOM')
offset = 1 if direction == Direction.FORWARD else -1
del l[idx]
l.insert(idx + offset, current_heading)
d.write()
vim.current.window.cursor = (
current_heading.start_vim + cursor_offset,
vim.current.window.cursor[1])
return True
@classmethod
@repeat
@apply_count
def move_heading_upward(cls, including_children=True):
if cls._move_heading(direction=Direction.BACKWARD, including_children=including_children):
if including_children:
return u'OrgMoveSubtreeUpward'
return u'OrgMoveHeadingUpward'
@classmethod
@repeat
@apply_count
def move_heading_downward(cls, including_children=True):
if cls._move_heading(direction=Direction.FORWARD, including_children=including_children):
if including_children:
return u'OrgMoveSubtreeDownward'
return u'OrgMoveHeadingDownward'
def register(self):
u"""
Registration of plugin. Key bindings and other initialization should be done.
"""
# EditStructure related default settings
settings.set(u'org_improve_split_heading', u'1')
# EditStructure related keybindings
self.keybindings.append(Keybinding(u'<C-S-CR>',
Plug(u'OrgNewHeadingAboveNormal', u':silent! %s ORGMODE.plugins[u"EditStructure"].new_heading(below=False)<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'New Heading &above', self.keybindings[-1])
self.keybindings.append(Keybinding(u'<localleader>hN', u'<Plug>OrgNewHeadingAboveNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<localleader><CR>', u'<Plug>OrgNewHeadingAboveNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<S-CR>',
Plug(u'OrgNewHeadingBelowNormal', u':silent! %s ORGMODE.plugins[u"EditStructure"].new_heading(below=True)<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'New Heading &below', self.keybindings[-1])
self.keybindings.append(Keybinding(u'<localleader>hh', u'<Plug>OrgNewHeadingBelowNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<leader><CR>', u'<Plug>OrgNewHeadingBelowNormal', mode=MODE_NORMAL))
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)))
self.menu + ActionEntry(u'New Heading below, after &children', self.keybindings[-1])
self.keybindings.append(Keybinding(u'<localleader>hn', u'<Plug>OrgNewHeadingBelowAfterChildrenNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<CR>', u'<Plug>OrgNewHeadingBelowAfterChildrenNormal', mode=MODE_NORMAL))
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)))
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)))
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)))
self.menu + Separator()
self.keybindings.append(Keybinding(u'm{', Plug(u'OrgMoveHeadingUpward',
u'%s ORGMODE.plugins[u"EditStructure"].move_heading_upward(including_children=False)<CR>' % VIM_PY_CALL)))
self.keybindings.append(Keybinding(u'm[[',
Plug(u'OrgMoveSubtreeUpward', u'%s ORGMODE.plugins[u"EditStructure"].move_heading_upward()<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'Move Subtree &Up', self.keybindings[-1])
self.keybindings.append(Keybinding(u'm}',
Plug(u'OrgMoveHeadingDownward', u'%s ORGMODE.plugins[u"EditStructure"].move_heading_downward(including_children=False)<CR>' % VIM_PY_CALL)))
self.keybindings.append(Keybinding(u'm]]',
Plug(u'OrgMoveSubtreeDownward', u'%s ORGMODE.plugins[u"EditStructure"].move_heading_downward()<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'Move Subtree &Down', self.keybindings[-1])
self.menu + Separator()
self.menu + ActionEntry(u'&Copy Heading', u'yah', u'yah')
self.menu + ActionEntry(u'C&ut Heading', u'dah', u'dah')
self.menu + Separator()
self.menu + ActionEntry(u'&Copy Subtree', u'yar', u'yar')
self.menu + ActionEntry(u'C&ut Subtree', u'dar', u'dar')
self.menu + ActionEntry(u'&Paste Subtree', u'p', u'p')
self.menu + Separator()
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)))
self.menu + ActionEntry(u'&Promote Heading', self.keybindings[-1])
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)))
self.keybindings.append(Keybinding(u'<{', u'<Plug>OrgPromoteHeadingNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<ih', u'<Plug>OrgPromoteHeadingNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<ar', Plug(u'OrgPromoteSubtreeNormal', u':silent! %s ORGMODE.plugins[u"EditStructure"].promote_heading()<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'&Promote Subtree', self.keybindings[-1])
self.keybindings.append(Keybinding(u'<[[', u'<Plug>OrgPromoteSubtreeNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'<ir', u'<Plug>OrgPromoteSubtreeNormal', mode=MODE_NORMAL))
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)))
self.menu + ActionEntry(u'&Demote Heading', self.keybindings[-1])
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)))
self.keybindings.append(Keybinding(u'>}', u'<Plug>OrgDemoteHeadingNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'>ih', u'<Plug>OrgDemoteHeadingNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'>ar', Plug(u'OrgDemoteSubtreeNormal', u':silent! %s ORGMODE.plugins[u"EditStructure"].demote_heading()<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'&Demote Subtree', self.keybindings[-1])
self.keybindings.append(Keybinding(u'>]]', u'<Plug>OrgDemoteSubtreeNormal', mode=MODE_NORMAL))
self.keybindings.append(Keybinding(u'>ir', u'<Plug>OrgDemoteSubtreeNormal', mode=MODE_NORMAL))
# other keybindings
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)))
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)))
# vim: set noexpandtab:

View file

@ -1,183 +0,0 @@
# -*- coding: utf-8 -*-
import os
import subprocess
import vim
from orgmode._vim import ORGMODE, echoe, echom
from orgmode.menu import Submenu, ActionEntry, add_cmd_mapping_menu
from orgmode.keybinding import Keybinding, Plug, Command
from orgmode import settings
from orgmode.py3compat.py_py3_string import *
class Export(object):
u"""
Export a orgmode file using emacs orgmode.
This is a *very simple* wrapper of the emacs/orgmode export. emacs and
orgmode need to be installed. We simply call emacs with some options to
export the .org.
TODO: Offer export options in vim. Don't use the menu.
TODO: Maybe use a native implementation.
"""
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Export')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
@classmethod
def _get_init_script(cls):
init_script = settings.get(u'org_export_init_script', u'')
if init_script:
init_script = os.path.expandvars(os.path.expanduser(init_script))
if os.path.exists(init_script):
return init_script
else:
echoe(u'Unable to find init script %s' % init_script)
@classmethod
def _export(cls, format_):
"""Export current file to format.
Args:
format_: pdf or html
Returns:
return code
"""
emacsbin = os.path.expandvars(os.path.expanduser(
settings.get(u'org_export_emacs', u'/usr/bin/emacs')))
if not os.path.exists(emacsbin):
echoe(u'Unable to find emacs binary %s' % emacsbin)
# build the export command
cmd = [
emacsbin,
u'-nw',
u'--batch',
u'--visit=%s' % vim.eval(u'expand("%:p")'),
u'--funcall=%s' % format_
]
# source init script as well
init_script = cls._get_init_script()
if init_script:
cmd.extend(['--script', init_script])
# export
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
if p.returncode != 0 or settings.get(u'org_export_verbose') == 1:
echom('\n'.join(p.communicate()))
return p.returncode
@classmethod
def topdf(cls):
u"""Export the current buffer as pdf using emacs orgmode."""
ret = cls._export(u'org-latex-export-to-pdf')
if ret != 0:
echoe(u'PDF export failed.')
else:
echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'pdf'))
@classmethod
def tobeamer(cls):
u"""Export the current buffer as beamer pdf using emacs orgmode."""
ret = cls._export(u'org-beamer-export-to-pdf')
if ret != 0:
echoe(u'PDF export failed.')
else:
echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'pdf'))
@classmethod
def tohtml(cls):
u"""Export the current buffer as html using emacs orgmode."""
ret = cls._export(u'org-html-export-to-html')
if ret != 0:
echoe(u'HTML export failed.')
else:
echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'html'))
@classmethod
def tolatex(cls):
u"""Export the current buffer as latex using emacs orgmode."""
ret = cls._export(u'org-latex-export-to-latex')
if ret != 0:
echoe(u'latex export failed.')
else:
echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'tex'))
@classmethod
def tomarkdown(cls):
u"""Export the current buffer as markdown using emacs orgmode."""
ret = cls._export(u'org-md-export-to-markdown')
if ret != 0:
echoe('Markdown export failed. Make sure org-md-export-to-markdown is loaded in emacs, see the manual for details.')
else:
echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'md'))
def register(self):
u"""Registration and keybindings."""
# path to emacs executable
settings.set(u'org_export_emacs', u'/usr/bin/emacs')
# verbose output for export
settings.set(u'org_export_verbose', 0)
# allow the user to define an initialization script
settings.set(u'org_export_init_script', u'')
# to PDF
add_cmd_mapping_menu(
self,
name=u'OrgExportToPDF',
function=u':%s ORGMODE.plugins[u"Export"].topdf()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>ep',
menu_desrc=u'To PDF (via Emacs)'
)
# to Beamer PDF
add_cmd_mapping_menu(
self,
name=u'OrgExportToBeamerPDF',
function=u':%s ORGMODE.plugins[u"Export"].tobeamer()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>eb',
menu_desrc=u'To Beamer PDF (via Emacs)'
)
# to latex
add_cmd_mapping_menu(
self,
name=u'OrgExportToLaTeX',
function=u':%s ORGMODE.plugins[u"Export"].tolatex()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>el',
menu_desrc=u'To LaTeX (via Emacs)'
)
# to HTML
add_cmd_mapping_menu(
self,
name=u'OrgExportToHTML',
function=u':%s ORGMODE.plugins[u"Export"].tohtml()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>eh',
menu_desrc=u'To HTML (via Emacs)'
)
# to Markdown
add_cmd_mapping_menu(
self,
name=u'OrgExportToMarkdown',
function=u':%s ORGMODE.plugins[u"Export"].tomarkdown()<CR>' % VIM_PY_CALL,
key_mapping=u'<localleader>em',
menu_desrc=u'To Markdown (via Emacs)'
)
# vim: set noexpandtab:

View file

@ -1,221 +0,0 @@
# -*- coding: utf-8 -*-
import re
import vim
from orgmode._vim import echom, ORGMODE, realign_tags
from orgmode.menu import Submenu, Separator, ActionEntry
from orgmode.keybinding import Keybinding, Plug, Command
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.py_py3_string import *
class Hyperlinks(object):
u""" Hyperlinks plugin """
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Hyperlinks')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
uri_match = re.compile(
r'^\[{2}(?P<uri>[^][]*)(\]\[(?P<description>[^][]*))?\]{2}')
@classmethod
def _get_link(cls, cursor=None):
u"""
Get the link the cursor is on and return it's URI and description
:cursor: None or (Line, Column)
:returns: None if no link was found, otherwise {uri:URI,
description:DESCRIPTION, line:LINE, start:START, end:END}
or uri and description could be None if not set
"""
cursor = cursor if cursor else vim.current.window.cursor
line = u_decode(vim.current.buffer[cursor[0] - 1])
# if the cursor is on the last bracket, it's not recognized as a hyperlink
start = line.rfind(u'[[', 0, cursor[1])
if start == -1:
start = line.rfind(u'[[', 0, cursor[1] + 2)
end = line.find(u']]', cursor[1])
if end == -1:
end = line.find(u']]', cursor[1] - 1)
# extract link
if start != -1 and end != -1:
end += 2
match = Hyperlinks.uri_match.match(line[start:end])
res = {
u'line': line,
u'start': start,
u'end': end,
u'uri': None,
u'description': None}
if match:
res.update(match.groupdict())
# reverse character escaping(partly done due to matching)
res[u'uri'] = res[u'uri'].replace(u'\\\\', u'\\')
return res
@classmethod
def follow(cls, action=u'openLink', visual=u''):
u""" Follow hyperlink. If called on a regular string UTL determines the
outcome. Normally a file with that name will be opened.
:action: "copy" if the link should be copied to clipboard, otherwise
the link will be opened
:visual: "visual" if Universal Text Linking should be triggered in
visual mode
:returns: URI or None
"""
if not int(vim.eval(u'exists(":Utl")')):
echom(u'Universal Text Linking plugin not installed, unable to proceed.')
return
action = u'copyLink' \
if (action and action.startswith(u'copy')) \
else u'openLink'
visual = u'visual' if visual and visual.startswith(u'visual') else u''
link = Hyperlinks._get_link()
if link and link[u'uri'] is not None:
# call UTL with the URI
vim.command(u_encode(u'Utl %s %s %s' % (action, visual, link[u'uri'])))
return link[u'uri']
else:
# call UTL and let it decide what to do
vim.command(u_encode(u'Utl %s %s' % (action, visual)))
@classmethod
@realign_tags
def insert(cls, uri=None, description=None):
u""" Inserts a hyperlink. If no arguments are provided, an interactive
query will be started.
:uri: The URI that will be opened
:description: An optional description that will be displayed instead of
the URI
:returns: (URI, description)
"""
link = Hyperlinks._get_link()
if link:
if uri is None and link[u'uri'] is not None:
uri = link[u'uri']
if description is None and link[u'description'] is not None:
description = link[u'description']
if uri is None:
uri = vim.eval(u'input("Link: ", "", "file")')
elif link:
uri = vim.eval(u'input("Link: ", "%s", "file")' % link[u'uri'])
if uri is None:
return
else:
uri = u_decode(uri)
# character escaping
uri = uri.replace(u'\\', u'\\\\\\\\')
uri = uri.replace(u' ', u'\ ')
if description is None:
description = u_decode(vim.eval(u'input("Description: ")'))
elif link:
description = vim.eval(
u'input("Description: ", "%s")' %
u_decode(link[u'description']))
if description is None:
return
cursor = vim.current.window.cursor
cl = u_decode(vim.current.buffer[cursor[0] - 1])
head = cl[:cursor[1] + 1] if not link else cl[:link[u'start']]
tail = cl[cursor[1] + 1:] if not link else cl[link[u'end']:]
separator = u''
if description:
separator = u']['
if uri or description:
vim.current.buffer[cursor[0] - 1] = \
u_encode(u''.join((head, u'[[%s%s%s]]' % (uri, separator, description), tail)))
elif link:
vim.current.buffer[cursor[0] - 1] = \
u_encode(u''.join((head, tail)))
def register(self):
u"""
Registration of plugin. Key bindings and other initialization should be done.
"""
cmd = Command(
u'OrgHyperlinkFollow',
u'%s ORGMODE.plugins[u"Hyperlinks"].follow()' % VIM_PY_CALL)
self.commands.append(cmd)
self.keybindings.append(
Keybinding(u'gl', Plug(u'OrgHyperlinkFollow', self.commands[-1])))
self.menu + ActionEntry(u'&Follow Link', self.keybindings[-1])
cmd = Command(
u'OrgHyperlinkCopy',
u'%s ORGMODE.plugins[u"Hyperlinks"].follow(action=u"copy")' % VIM_PY_CALL)
self.commands.append(cmd)
self.keybindings.append(
Keybinding(u'gyl', Plug(u'OrgHyperlinkCopy', self.commands[-1])))
self.menu + ActionEntry(u'&Copy Link', self.keybindings[-1])
cmd = Command(
u'OrgHyperlinkInsert',
u'%s ORGMODE.plugins[u"Hyperlinks"].insert(<f-args>)' % VIM_PY_CALL,
arguments=u'*')
self.commands.append(cmd)
self.keybindings.append(
Keybinding(u'gil', Plug(u'OrgHyperlinkInsert', self.commands[-1])))
self.menu + ActionEntry(u'&Insert Link', self.keybindings[-1])
self.menu + Separator()
# find next link
cmd = Command(
u'OrgHyperlinkNextLink',
u":if search('\[\{2}\zs[^][]*\(\]\[[^][]*\)\?\ze\]\{2}', 's') == 0 | echo 'No further link found.' | endif")
self.commands.append(cmd)
self.keybindings.append(
Keybinding(u'gn', Plug(u'OrgHyperlinkNextLink', self.commands[-1])))
self.menu + ActionEntry(u'&Next Link', self.keybindings[-1])
# find previous link
cmd = Command(
u'OrgHyperlinkPreviousLink',
u":if search('\[\{2}\zs[^][]*\(\]\[[^][]*\)\?\ze\]\{2}', 'bs') == 0 | echo 'No further link found.' | endif")
self.commands.append(cmd)
self.keybindings.append(
Keybinding(u'go', Plug(u'OrgHyperlinkPreviousLink', self.commands[-1])))
self.menu + ActionEntry(u'&Previous Link', self.keybindings[-1])
self.menu + Separator()
# Descriptive Links
cmd = Command(u'OrgHyperlinkDescriptiveLinks', u':setlocal cole=2')
self.commands.append(cmd)
self.menu + ActionEntry(u'&Descriptive Links', self.commands[-1])
# Literal Links
cmd = Command(u'OrgHyperlinkLiteralLinks', u':setlocal cole=0')
self.commands.append(cmd)
self.menu + ActionEntry(u'&Literal Links', self.commands[-1])
# vim: set noexpandtab:

View file

@ -1,42 +0,0 @@
# -*- coding: utf-8 -*-
import vim
from orgmode._vim import echo, echom, echoe, ORGMODE, apply_count, repeat
from orgmode.menu import Submenu, Separator, ActionEntry
from orgmode.keybinding import Keybinding, Plug, Command
from orgmode.py3compat.py_py3_string import *
class LoggingWork(object):
u""" LoggingWork plugin """
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'&Logging work')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
# commands for this plugin
self.commands = []
@classmethod
def action(cls):
u""" Some kind of action
:returns: TODO
"""
pass
def register(self):
u"""
Registration of plugin. Key bindings and other initialization should be done.
"""
# an Action menu entry which binds "keybinding" to action ":action"
self.commands.append(Command(u'OrgLoggingRecordDoneTime', u'%s ORGMODE.plugins[u"LoggingWork"].action()' % VIM_PY_CALL))
self.menu + ActionEntry(u'&Record DONE time', self.commands[-1])

View file

@ -1,173 +0,0 @@
# -*- coding: utf-8 -*-
import vim
from orgmode._vim import ORGMODE, apply_count
from orgmode.menu import Submenu
from orgmode.keybinding import Keybinding, Plug, MODE_VISUAL, MODE_OPERATOR
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.py_py3_string import *
class Misc(object):
u""" Miscellaneous functionality """
def __init__(self):
u""" Initialize plugin """
object.__init__(self)
# menu entries this plugin should create
self.menu = ORGMODE.orgmenu + Submenu(u'Misc')
# key bindings for this plugin
# key bindings are also registered through the menu so only additional
# bindings should be put in this variable
self.keybindings = []
@classmethod
def jump_to_first_character(cls):
heading = ORGMODE.get_document().current_heading()
if not heading or heading.start_vim != vim.current.window.cursor[0]:
vim.eval(u_encode(u'feedkeys("^", "n")'))
return
vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)
@classmethod
def edit_at_first_character(cls):
heading = ORGMODE.get_document().current_heading()
if not heading or heading.start_vim != vim.current.window.cursor[0]:
vim.eval(u_encode(u'feedkeys("I", "n")'))
return
vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)
vim.command(u_encode(u'startinsert'))
# @repeat
@classmethod
@apply_count
def i_heading(cls, mode=u'visual', selection=u'inner', skip_children=False):
u"""
inner heading text object
"""
heading = ORGMODE.get_document().current_heading()
if heading:
if selection != u'inner':
heading = heading if not heading.parent else heading.parent
line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]
if mode != u'visual':
line_start = vim.current.window.cursor[0]
line_end = line_start
start = line_start
end = line_end
move_one_character_back = u'' if mode == u'visual' else u'h'
if heading.start_vim < line_start:
start = heading.start_vim
if heading.end_vim > line_end and not skip_children:
end = heading.end_vim
elif heading.end_of_last_child_vim > line_end and skip_children:
end = heading.end_of_last_child_vim
if mode != u'visual' and not vim.current.buffer[end - 1]:
end -= 1
move_one_character_back = u''
swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''
if selection == u'inner' and vim.current.window.cursor[0] != line_start:
h = ORGMODE.get_document().current_heading()
if h:
heading = h
visualmode = u_decode(vim.eval(u'visualmode()')) if mode == u'visual' else u'v'
if line_start == start and line_start != heading.start_vim:
if col_start in (0, 1):
vim.command(u_encode(u'normal! %dgg0%s%dgg$%s%s' % (start, visualmode, end, move_one_character_back, swap_cursor)))
else:
vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, col_start - 1, visualmode, end, move_one_character_back, swap_cursor)))
else:
vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, heading.level + 1, visualmode, end, move_one_character_back, swap_cursor)))
if selection == u'inner':
if mode == u'visual':
return u'OrgInnerHeadingVisual' if not skip_children else u'OrgInnerTreeVisual'
else:
return u'OrgInnerHeadingOperator' if not skip_children else u'OrgInnerTreeOperator'
else:
if mode == u'visual':
return u'OrgOuterHeadingVisual' if not skip_children else u'OrgOuterTreeVisual'
else:
return u'OrgOuterHeadingOperator' if not skip_children else u'OrgOuterTreeOperator'
elif mode == u'visual':
vim.command(u_encode(u'normal! gv'))
# @repeat
@classmethod
@apply_count
def a_heading(cls, selection=u'inner', skip_children=False):
u"""
a heading text object
"""
heading = ORGMODE.get_document().current_heading()
if heading:
if selection != u'inner':
heading = heading if not heading.parent else heading.parent
line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]
start = line_start
end = line_end
if heading.start_vim < line_start:
start = heading.start_vim
if heading.end_vim > line_end and not skip_children:
end = heading.end_vim
elif heading.end_of_last_child_vim > line_end and skip_children:
end = heading.end_of_last_child_vim
swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''
vim.command(u_encode(u'normal! %dgg%s%dgg$%s' % (start, vim.eval(u_encode(u'visualmode()')), end, swap_cursor)))
if selection == u'inner':
return u'OrgAInnerHeadingVisual' if not skip_children else u'OrgAInnerTreeVisual'
else:
return u'OrgAOuterHeadingVisual' if not skip_children else u'OrgAOuterTreeVisual'
else:
vim.command(u_encode(u'normal! gv'))
def register(self):
u"""
Registration of plugin. Key bindings and other initialization should be done.
"""
self.keybindings.append(Keybinding(u'^',
Plug(u'OrgJumpToFirstCharacter', u'%s ORGMODE.plugins[u"Misc"].jump_to_first_character()<CR>' % VIM_PY_CALL)))
self.keybindings.append(Keybinding(u'I',
Plug(u'OrgEditAtFirstCharacter', u'%s ORGMODE.plugins[u"Misc"].edit_at_first_character()<CR>' % VIM_PY_CALL)))
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)))
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)))
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)))
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)))
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)))
self.keybindings.append(Keybinding(u'ah', u':normal Vah<CR>', mode=MODE_OPERATOR))
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)))
self.keybindings.append(Keybinding(u'OH', u':normal VOH<CR>', mode=MODE_OPERATOR))
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)))
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)))
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)))
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)))
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)))
self.keybindings.append(Keybinding(u'ar', u':normal Var<CR>', mode=MODE_OPERATOR))
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)))
self.keybindings.append(Keybinding(u'OR', u':normal VOR<CR>', mode=MODE_OPERATOR))
# vim: set noexpandtab:

View file

@ -1,326 +0,0 @@
# -*- coding: utf-8 -*-
import vim
from orgmode._vim import echo, ORGMODE, apply_count
from orgmode.menu import Submenu, ActionEntry
from orgmode.keybinding import Keybinding, MODE_VISUAL, MODE_OPERATOR, Plug
from orgmode.liborgmode.documents import Direction
from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.py_py3_string import *
class Navigator(object):
u""" Implement navigation in org-mode documents """
def __init__(self):
object.__init__(self)
self.menu = ORGMODE.orgmenu + Submenu(u'&Navigate Headings')
self.keybindings = []
@classmethod
@apply_count
def parent(cls, mode):
u"""
Focus parent heading
:returns: parent heading or None
"""
heading = ORGMODE.get_document().current_heading()
if not heading:
if mode == u'visual':
vim.command(u_encode(u'normal! gv'))
else:
echo(u'No heading found')
return
if not heading.parent:
if mode == u'visual':
vim.command(u_encode(u'normal! gv'))
else:
echo(u'No parent heading found')
return
p = heading.parent
if mode == u'visual':
cls._change_visual_selection(heading, p, direction=Direction.BACKWARD, parent=True)
else:
vim.current.window.cursor = (p.start_vim, p.level + 1)
return p
@classmethod
@apply_count
def parent_next_sibling(cls, mode):
u"""
Focus the parent's next sibling
:returns: parent's next sibling heading or None
"""
heading = ORGMODE.get_document().current_heading()
if not heading:
if mode == u'visual':
vim.command(u_encode(u'normal! gv'))
else:
echo(u'No heading found')
return
if not heading.parent or not heading.parent.next_sibling:
if mode == u'visual':
vim.command(u_encode(u'normal! gv'))
else:
echo(u'No parent heading found')
return
ns = heading.parent.next_sibling
if mode == u'visual':
cls._change_visual_selection(heading, ns, direction=Direction.FORWARD, parent=False)
elif mode == u'operator':
vim.current.window.cursor = (ns.start_vim, 0)
else:
vim.current.window.cursor = (ns.start_vim, ns.level + 1)
return ns
@classmethod
def _change_visual_selection(cls, current_heading, heading, direction=Direction.FORWARD, noheadingfound=False, parent=False):
current = vim.current.window.cursor[0]
line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]
f_start = heading.start_vim
f_end = heading.end_vim
swap_cursor = True
# << |visual start
# selection end >>
if current == line_start:
if (direction == Direction.FORWARD and line_end < f_start) or noheadingfound and not direction == Direction.BACKWARD:
swap_cursor = False
# focus heading HERE
# << |visual start
# selection end >>
# << |visual start
# focus heading HERE
# selection end >>
if f_start < line_start and direction == Direction.BACKWARD:
if current_heading.start_vim < line_start and not parent:
line_start = current_heading.start_vim
else:
line_start = f_start
elif (f_start < line_start or f_start < line_end) and not noheadingfound:
line_start = f_start
# << |visual start
# selection end >>
# focus heading HERE
else:
if direction == Direction.FORWARD:
if line_end < f_start and not line_start == f_start - 1 and current_heading:
# focus end of previous heading instead of beginning of next heading
line_start = line_end
line_end = f_start - 1
else:
# focus end of next heading
line_start = line_end
line_end = f_end
elif direction == Direction.BACKWARD:
if line_end < f_end:
pass
else:
line_start = line_end
line_end = f_end
# << visual start
# selection end| >>
else:
# focus heading HERE
# << visual start
# selection end| >>
if line_start > f_start and line_end > f_end and not parent:
line_end = f_end
swap_cursor = False
elif (line_start > f_start or line_start == f_start) and \
line_end <= f_end and direction == Direction.BACKWARD:
line_end = line_start
line_start = f_start
# << visual start
# selection end and focus heading end HERE| >>
# << visual start
# focus heading HERE
# selection end| >>
# << visual start
# selection end| >>
# focus heading HERE
else:
if direction == Direction.FORWARD:
if line_end < f_start - 1:
# focus end of previous heading instead of beginning of next heading
line_end = f_start - 1
else:
# focus end of next heading
line_end = f_end
else:
line_end = f_end
swap_cursor = False
move_col_start = u'%dl' % (col_start - 1) if (col_start - 1) > 0 and (col_start - 1) < 2000000000 else u''
move_col_end = u'%dl' % (col_end - 1) if (col_end - 1) > 0 and (col_end - 1) < 2000000000 else u''
swap = u'o' if swap_cursor else u''
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)))
@classmethod
def _focus_heading(cls, mode, direction=Direction.FORWARD, skip_children=False):
u"""
Focus next or previous heading in the given direction
:direction: True for next heading, False for previous heading
:returns: next heading or None
"""
d = ORGMODE.get_document()
current_heading = d.current_heading()
heading = current_heading
focus_heading = None
# FIXME this is just a piece of really ugly and unmaintainable code. It
# should be rewritten
if not heading:
if direction == Direction.FORWARD and d.headings \
and vim.current.window.cursor[0] < d.headings[0].start_vim:
# the cursor is in the meta information are, therefore focus
# first heading
focus_heading = d.headings[0]
if not (heading or focus_heading):
if mode == u'visual':
# restore visual selection when no heading was found
vim.command(u_encode(u'normal! gv'))
else:
echo(u'No heading found')
return
elif direction == Direction.BACKWARD:
if vim.current.window.cursor[0] != heading.start_vim:
# the cursor is in the body of the current heading, therefore
# the current heading will be focused
if mode == u'visual':
line_start, col_start = [int(i) for i in
vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]
if line_start >= heading.start_vim and line_end > heading.start_vim:
focus_heading = heading
else:
focus_heading = heading
# so far no heading has been found that the next focus should be on
if not focus_heading:
if not skip_children and direction == Direction.FORWARD and heading.children:
focus_heading = heading.children[0]
elif direction == Direction.FORWARD and heading.next_sibling:
focus_heading = heading.next_sibling
elif direction == Direction.BACKWARD and heading.previous_sibling:
focus_heading = heading.previous_sibling
if not skip_children:
while focus_heading.children:
focus_heading = focus_heading.children[-1]
else:
if direction == Direction.FORWARD:
focus_heading = current_heading.next_heading
else:
focus_heading = current_heading.previous_heading
noheadingfound = False
if not focus_heading:
if mode in (u'visual', u'operator'):
# the cursor seems to be on the last or first heading of this
# document and performes another next/previous operation
focus_heading = heading
noheadingfound = True
else:
if direction == Direction.FORWARD:
echo(u'Already focussing last heading')
else:
echo(u'Already focussing first heading')
return
if mode == u'visual':
cls._change_visual_selection(current_heading, focus_heading, direction=direction, noheadingfound=noheadingfound)
elif mode == u'operator':
if direction == Direction.FORWARD and vim.current.window.cursor[0] >= focus_heading.start_vim:
vim.current.window.cursor = (focus_heading.end_vim, len(u_decode(vim.current.buffer[focus_heading.end])))
else:
vim.current.window.cursor = (focus_heading.start_vim, 0)
else:
vim.current.window.cursor = (focus_heading.start_vim, focus_heading.level + 1)
if noheadingfound:
return
return focus_heading
@classmethod
@apply_count
def previous(cls, mode, skip_children=False):
u"""
Focus previous heading
"""
return cls._focus_heading(mode, direction=Direction.BACKWARD, skip_children=skip_children)
@classmethod
@apply_count
def next(cls, mode, skip_children=False):
u"""
Focus next heading
"""
return cls._focus_heading(mode, direction=Direction.FORWARD, skip_children=skip_children)
def register(self):
# normal mode
self.keybindings.append(Keybinding(u'g{', Plug('OrgJumpToParentNormal',
u'%s ORGMODE.plugins[u"Navigator"].parent(mode=u"normal")<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'&Up', self.keybindings[-1])
self.keybindings.append(Keybinding(u'g}',
Plug('OrgJumpToParentsSiblingNormal', u'%s ORGMODE.plugins[u"Navigator"].parent_next_sibling(mode=u"normal")<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'&Down', self.keybindings[-1])
self.keybindings.append(Keybinding(u'{',
Plug(u'OrgJumpToPreviousNormal', u'%s ORGMODE.plugins[u"Navigator"].previous(mode=u"normal")<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'&Previous', self.keybindings[-1])
self.keybindings.append(Keybinding(u'}', Plug(u'OrgJumpToNextNormal',
u'%s ORGMODE.plugins[u"Navigator"].next(mode=u"normal")<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'&Next', self.keybindings[-1])
# visual mode
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)))
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)))
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)))
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)))
# operator-pending mode
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)))
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)))
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)))
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)))
# section wise movement (skip children)
# normal mode
self.keybindings.append(Keybinding(u'[[',
Plug(u'OrgJumpToPreviousSkipChildrenNormal',
u'%s ORGMODE.plugins[u"Navigator"].previous(mode=u"normal", skip_children=True)<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'Ne&xt Same Level', self.keybindings[-1])
self.keybindings.append(Keybinding(u']]',
Plug(u'OrgJumpToNextSkipChildrenNormal',
u'%s ORGMODE.plugins[u"Navigator"].next(mode=u"normal", skip_children=True)<CR>' % VIM_PY_CALL)))
self.menu + ActionEntry(u'Pre&vious Same Level', self.keybindings[-1])
# visual mode
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)))
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)))
# operator-pending mode
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)))
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)))
# vim: set noexpandtab:

Some files were not shown because too many files have changed in this diff Show more