Initial commit.
This commit is contained in:
30
vim/plugin/AnsiEscPlugin.vim
Normal file
30
vim/plugin/AnsiEscPlugin.vim
Normal file
@@ -0,0 +1,30 @@
|
||||
" AnsiEscPlugin.vim
|
||||
" Author: Charles E. Campbell, Jr.
|
||||
" Date: Apr 07, 2010
|
||||
" Version: 12
|
||||
" ---------------------------------------------------------------------
|
||||
" Load Once: {{{1
|
||||
if &cp || exists("g:loaded_AnsiEscPlugin")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_AnsiEscPlugin = "v12"
|
||||
let s:keepcpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" Public Interface: {{{1
|
||||
com! -bang -nargs=0 AnsiEsc :call AnsiEsc#AnsiEsc(<bang>0)
|
||||
|
||||
" DrChip Menu Support: {{{2
|
||||
if has("gui_running") && has("menu") && &go =~ 'm'
|
||||
if !exists("g:DrChipTopLvlMenu")
|
||||
let g:DrChipTopLvlMenu= "DrChip."
|
||||
endif
|
||||
exe 'menu '.g:DrChipTopLvlMenu.'AnsiEsc.Start<tab>:AnsiEsc :AnsiEsc<cr>'
|
||||
endif
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" Restore: {{{1
|
||||
let &cpo= s:keepcpo
|
||||
unlet s:keepcpo
|
||||
" vim: ts=4 fdm=marker
|
||||
900
vim/plugin/CSApprox.vim
Normal file
900
vim/plugin/CSApprox.vim
Normal file
@@ -0,0 +1,900 @@
|
||||
" CSApprox: Make gvim-only colorschemes Just Work terminal vim
|
||||
" Maintainer: Matthew Wozniski (mjw@drexel.edu)
|
||||
" Date: Wed, 01 Apr 2009 22:10:19 -0400
|
||||
" Version: 3.50
|
||||
" History: :help csapprox-changelog
|
||||
"
|
||||
" Long Description:
|
||||
" It's hard to find colorschemes for terminal Vim. Most colorschemes are
|
||||
" written to only support GVim, and don't work at all in terminal Vim.
|
||||
"
|
||||
" This plugin makes GVim-only colorschemes Just Work in terminal Vim, as long
|
||||
" as the terminal supports 88 or 256 colors - and most do these days. This
|
||||
" usually requires no user interaction (but see below for what to do if things
|
||||
" don't Just Work). After getting this plugin happily installed, any time you
|
||||
" use :colorscheme it will do its magic and make the colorscheme Just Work.
|
||||
"
|
||||
" Whenever you change colorschemes using the :colorscheme command this script
|
||||
" will be executed. It will take the colors that the scheme specified for use
|
||||
" in the GUI and use an approximation algorithm to try to gracefully degrade
|
||||
" them to the closest color available in your terminal. If you are running in
|
||||
" a GUI or if your terminal doesn't support 88 or 256 colors, no changes are
|
||||
" made. Also, no changes will be made if the colorscheme seems to have been
|
||||
" high color already.
|
||||
"
|
||||
" License:
|
||||
" Copyright (c) 2009, Matthew J. Wozniski
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
" * Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" * Redistributions in binary form must reproduce the above copyright
|
||||
" notice, this list of conditions and the following disclaimer in the
|
||||
" documentation and/or other materials provided with the distribution.
|
||||
" * The names of the contributors may not be used to endorse or promote
|
||||
" products derived from this software without specific prior written
|
||||
" permission.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
|
||||
" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
" NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
" OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
" {>1} Basic plugin setup
|
||||
|
||||
" {>2} Check preconditions
|
||||
" Quit if the user doesn't want or need us or is missing the gui feature. We
|
||||
" need +gui to be able to check the gui color settings; vim doesn't bother to
|
||||
" store them if it is not built with +gui.
|
||||
if exists('g:CSApprox_loaded')
|
||||
finish
|
||||
elseif ! has('gui')
|
||||
" Warn unless the user set g:CSApprox_verbose_level to zero.
|
||||
if get(g:, 'CSApprox_verbose_level', 1)
|
||||
echomsg "CSApprox needs gui support - not loading."
|
||||
echomsg " See :help |csapprox-+gui| for possible workarounds."
|
||||
endif
|
||||
|
||||
finish
|
||||
endif
|
||||
|
||||
" {1} Mark us as loaded, and disable all compatibility options for now.
|
||||
let g:CSApprox_loaded = 1
|
||||
|
||||
let s:savecpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" {>1} Collect info for the set highlights
|
||||
|
||||
" {>2} Determine if synIDattr is usable
|
||||
" synIDattr() couldn't support 'guisp' until 7.2.052. This function returns
|
||||
" true if :redir is needed to find the 'guisp' attribute, false if synIDattr()
|
||||
" is functional. This test can be overridden by setting the global variable
|
||||
" g:CSApprox_redirfallback to 1 (to force use of :redir) or to 0 (to force use
|
||||
" of synIDattr()).
|
||||
function! s:NeedRedirFallback()
|
||||
if !exists("g:CSApprox_redirfallback")
|
||||
let g:CSApprox_redirfallback = (v:version == 702 && !has('patch52'))
|
||||
\ || v:version < 702
|
||||
endif
|
||||
return g:CSApprox_redirfallback
|
||||
endfunction
|
||||
|
||||
" {>2} Collect and store the highlights
|
||||
" Get a dictionary containing information for every highlight group not merely
|
||||
" linked to another group. Return value is a dictionary, with highlight group
|
||||
" numbers for keys and values that are dictionaries with four keys each,
|
||||
" 'name', 'term', 'cterm', and 'gui'. 'name' holds the group name, and each
|
||||
" of the others holds highlight information for that particular mode.
|
||||
function! s:Highlights(modes)
|
||||
let rv = {}
|
||||
|
||||
let i = 0
|
||||
while 1
|
||||
let i += 1
|
||||
|
||||
" Only interested in groups that exist and aren't linked
|
||||
if synIDtrans(i) == 0
|
||||
break
|
||||
endif
|
||||
|
||||
" Handle vim bug allowing groups with name == "" to be created
|
||||
if synIDtrans(i) != i || len(synIDattr(i, "name")) == 0
|
||||
continue
|
||||
endif
|
||||
|
||||
let rv[i] = {}
|
||||
let rv[i].name = synIDattr(i, "name")
|
||||
|
||||
for where in a:modes
|
||||
let rv[i][where] = {}
|
||||
for attr in [ "bold", "italic", "reverse", "underline", "undercurl" ]
|
||||
let rv[i][where][attr] = synIDattr(i, attr, where)
|
||||
endfor
|
||||
|
||||
for attr in [ "fg", "bg" ]
|
||||
let rv[i][where][attr] = synIDattr(i, attr.'#', where)
|
||||
endfor
|
||||
|
||||
if where == "gui"
|
||||
let rv[i][where]["sp"] = s:SynGuiSp(i, rv[i].name)
|
||||
else
|
||||
let rv[i][where]["sp"] = -1
|
||||
endif
|
||||
|
||||
for attr in [ "fg", "bg", "sp" ]
|
||||
if rv[i][where][attr] == -1
|
||||
let rv[i][where][attr] = ''
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endwhile
|
||||
|
||||
return rv
|
||||
endfunction
|
||||
|
||||
" {>2} Retrieve guisp
|
||||
|
||||
" Get guisp using whichever method is specified by _redir_fallback
|
||||
function! s:SynGuiSp(idx, name)
|
||||
if !s:NeedRedirFallback()
|
||||
return s:SynGuiSpAttr(a:idx)
|
||||
else
|
||||
return s:SynGuiSpRedir(a:name)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" {>3} Implementation for retrieving guisp with redir hack
|
||||
function! s:SynGuiSpRedir(name)
|
||||
redir => temp
|
||||
exe 'sil hi ' . a:name
|
||||
redir END
|
||||
let temp = matchstr(temp, 'guisp=\zs.*')
|
||||
if len(temp) == 0 || temp[0] =~ '\s'
|
||||
let temp = ""
|
||||
else
|
||||
" Make sure we can handle guisp='dark red'
|
||||
let temp = substitute(temp, '[\x00].*', '', '')
|
||||
let temp = substitute(temp, '\s*\(c\=term\|gui\).*', '', '')
|
||||
let temp = substitute(temp, '\s*$', '', '')
|
||||
endif
|
||||
return temp
|
||||
endfunction
|
||||
|
||||
" {>3} Implementation for retrieving guisp with synIDattr()
|
||||
function! s:SynGuiSpAttr(idx)
|
||||
return synIDattr(a:idx, 'sp#', 'gui')
|
||||
endfunction
|
||||
|
||||
" {>1} Handle color names
|
||||
|
||||
" Place to store rgb.txt name to color mappings - lazy loaded if needed
|
||||
let s:rgb = {}
|
||||
|
||||
" {>2} Builtin gui color names
|
||||
" gui_x11.c and gui_gtk_x11.c have some default colors names that are searched
|
||||
" if the x server doesn't know about a color. If 'showrgb' is available,
|
||||
" we'll default to using these color names and values, and overwrite them with
|
||||
" other values if 'showrgb' tells us about those colors.
|
||||
let s:rgb_defaults = { "lightred" : "#FFBBBB",
|
||||
\ "lightgreen" : "#88FF88",
|
||||
\ "lightmagenta" : "#FFBBFF",
|
||||
\ "darkcyan" : "#008888",
|
||||
\ "darkblue" : "#0000BB",
|
||||
\ "darkred" : "#BB0000",
|
||||
\ "darkmagenta" : "#BB00BB",
|
||||
\ "darkgrey" : "#BBBBBB",
|
||||
\ "darkyellow" : "#BBBB00",
|
||||
\ "gray10" : "#1A1A1A",
|
||||
\ "grey10" : "#1A1A1A",
|
||||
\ "gray20" : "#333333",
|
||||
\ "grey20" : "#333333",
|
||||
\ "gray30" : "#4D4D4D",
|
||||
\ "grey30" : "#4D4D4D",
|
||||
\ "gray40" : "#666666",
|
||||
\ "grey40" : "#666666",
|
||||
\ "gray50" : "#7F7F7F",
|
||||
\ "grey50" : "#7F7F7F",
|
||||
\ "gray60" : "#999999",
|
||||
\ "grey60" : "#999999",
|
||||
\ "gray70" : "#B3B3B3",
|
||||
\ "grey70" : "#B3B3B3",
|
||||
\ "gray80" : "#CCCCCC",
|
||||
\ "grey80" : "#CCCCCC",
|
||||
\ "gray90" : "#E5E5E5",
|
||||
\ "grey90" : "#E5E5E5" }
|
||||
|
||||
" {>2} Colors that vim will use by name in one of the default schemes, either
|
||||
" for bg=light or for bg=dark. This lets us avoid loading the entire rgb.txt
|
||||
" database when the scheme itself doesn't ask for colors by name.
|
||||
let s:rgb_presets = { "black" : "#000000",
|
||||
\ "blue" : "#0000ff",
|
||||
\ "brown" : "#a52a2a",
|
||||
\ "cyan" : "#00ffff",
|
||||
\ "darkblue" : "#00008b",
|
||||
\ "darkcyan" : "#008b8b",
|
||||
\ "darkgrey" : "#a9a9a9",
|
||||
\ "darkmagenta" : "#8b008b",
|
||||
\ "green" : "#00ff00",
|
||||
\ "grey" : "#bebebe",
|
||||
\ "grey40" : "#666666",
|
||||
\ "grey90" : "#e5e5e5",
|
||||
\ "lightblue" : "#add8e6",
|
||||
\ "lightcyan" : "#e0ffff",
|
||||
\ "lightgrey" : "#d3d3d3",
|
||||
\ "lightmagenta" : "#ffbbff",
|
||||
\ "magenta" : "#ff00ff",
|
||||
\ "red" : "#ff0000",
|
||||
\ "seagreen" : "#2e8b57",
|
||||
\ "white" : "#ffffff",
|
||||
\ "yellow" : "#ffff00" }
|
||||
|
||||
" {>2} Find available color names
|
||||
" Find the valid named colors. By default, use our own rgb list, but try to
|
||||
" retrieve the system's list if g:CSApprox_use_showrgb is set to true. Store
|
||||
" the color names and color values to the dictionary s:rgb - the keys are
|
||||
" color names (in lowercase), the values are strings representing color values
|
||||
" (as '#rrggbb').
|
||||
function! s:UpdateRgbHash()
|
||||
try
|
||||
if !exists("g:CSApprox_use_showrgb") || !g:CSApprox_use_showrgb
|
||||
throw "Not using showrgb"
|
||||
endif
|
||||
|
||||
" We want to use the 'showrgb' program, if it's around
|
||||
let lines = split(system('showrgb'), '\n')
|
||||
|
||||
if v:shell_error || !exists('lines') || empty(lines)
|
||||
throw "'showrgb' didn't give us an rgb.txt"
|
||||
endif
|
||||
|
||||
let s:rgb = copy(s:rgb_defaults)
|
||||
|
||||
" fmt is (blanks?)(red)(blanks)(green)(blanks)(blue)(blanks)(name)
|
||||
let parsepat = '^\s*\(\d\+\)\s\+\(\d\+\)\s\+\(\d\+\)\s\+\(.*\)$'
|
||||
|
||||
for line in lines
|
||||
let v = matchlist(line, parsepat)
|
||||
if len(v) < 0
|
||||
throw "CSApprox: Bad RGB line: " . string(line)
|
||||
endif
|
||||
let s:rgb[tolower(v[4])] = printf("#%02x%02x%02x", v[1], v[2], v[3])
|
||||
endfor
|
||||
catch
|
||||
try
|
||||
let s:rgb = csapprox#rgb()
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echomsg "Can't call rgb() from autoload/csapprox.vim"
|
||||
echomsg "Named colors will not be available!"
|
||||
echohl None
|
||||
endtry
|
||||
endtry
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" {>1} Derive and set cterm attributes
|
||||
|
||||
" {>2} Attribute overrides
|
||||
" Allow the user to override a specified attribute with another attribute.
|
||||
" For example, the default is to map 'italic' to 'underline' (since many
|
||||
" terminals cannot display italic text, and gvim itself will replace italics
|
||||
" with underlines where italicizing is impossible), and to replace 'sp' with
|
||||
" 'fg' (since terminals can't use one color for the underline and another for
|
||||
" the foreground, we color the entire word). This default can of course be
|
||||
" overridden by the user, by setting g:CSApprox_attr_map. This map must be
|
||||
" a dictionary of string keys, representing the same attributes that synIDattr
|
||||
" can look up, to string values, representing the attribute mapped to or an
|
||||
" empty string to disable the given attribute entirely.
|
||||
function! s:attr_map(attr)
|
||||
let rv = get(g:CSApprox_attr_map, a:attr, a:attr)
|
||||
|
||||
return rv
|
||||
endfunction
|
||||
|
||||
function! s:NormalizeAttrMap(map)
|
||||
let old = copy(a:map)
|
||||
let new = filter(a:map, '0')
|
||||
|
||||
let valid_attrs = [ 'bg', 'fg', 'sp', 'bold', 'italic',
|
||||
\ 'reverse', 'underline', 'undercurl' ]
|
||||
|
||||
let colorattrs = [ 'fg', 'bg', 'sp' ]
|
||||
|
||||
for olhs in keys(old)
|
||||
if olhs ==? 'inverse'
|
||||
let nlhs = 'reverse'
|
||||
endif
|
||||
|
||||
let orhs = old[olhs]
|
||||
|
||||
if orhs ==? 'inverse'
|
||||
let nrhs = 'reverse'
|
||||
endif
|
||||
|
||||
let nlhs = tolower(olhs)
|
||||
let nrhs = tolower(orhs)
|
||||
|
||||
try
|
||||
if index(valid_attrs, nlhs) == -1
|
||||
echomsg "CSApprox: Bad attr map (removing unrecognized attribute " . olhs . ")"
|
||||
elseif nrhs != '' && index(valid_attrs, nrhs) == -1
|
||||
echomsg "CSApprox: Bad attr map (removing unrecognized attribute " . orhs . ")"
|
||||
elseif nrhs != '' && !!(index(colorattrs, nlhs)+1) != !!(index(colorattrs, nrhs)+1)
|
||||
echomsg "CSApprox: Bad attr map (removing " . olhs . "; type mismatch with " . orhs . ")"
|
||||
elseif nrhs == 'sp'
|
||||
echomsg "CSApprox: Bad attr map (removing " . olhs . "; can't map to 'sp')"
|
||||
else
|
||||
let new[nlhs] = nrhs
|
||||
endif
|
||||
catch
|
||||
echo v:exception
|
||||
endtry
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" {>2} Normalize the GUI settings of a highlight group
|
||||
" If the Normal group is cleared, set it to gvim's default, black on white
|
||||
" Though this would be a really weird thing for a scheme to do... *shrug*
|
||||
function! s:FixupGuiInfo(highlights)
|
||||
if a:highlights[s:hlid_normal].gui.bg == ''
|
||||
let a:highlights[s:hlid_normal].gui.bg = 'white'
|
||||
endif
|
||||
|
||||
if a:highlights[s:hlid_normal].gui.fg == ''
|
||||
let a:highlights[s:hlid_normal].gui.fg = 'black'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" {>2} Map gui settings to cterm settings
|
||||
" Given information about a highlight group, replace the cterm settings with
|
||||
" the mapped gui settings, applying any attribute overrides along the way. In
|
||||
" particular, this gives special treatment to the 'reverse' attribute and the
|
||||
" 'guisp' attribute. In particular, if the 'reverse' attribute is set for
|
||||
" gvim, we unset it for the terminal and instead set ctermfg to match guibg
|
||||
" and vice versa, since terminals can consider a 'reverse' flag to mean using
|
||||
" default-bg-on-default-fg instead of current-bg-on-current-fg. We also
|
||||
" ensure that the 'sp' attribute is never set for cterm, since no terminal can
|
||||
" handle that particular highlight. If the user wants to display the guisp
|
||||
" color, he should map it to either 'fg' or 'bg' using g:CSApprox_attr_map.
|
||||
function! s:FixupCtermInfo(highlights)
|
||||
for hl in values(a:highlights)
|
||||
|
||||
if !has_key(hl, 'cterm')
|
||||
let hl["cterm"] = {}
|
||||
endif
|
||||
|
||||
" Find attributes to be set in the terminal
|
||||
for attr in [ "bold", "italic", "reverse", "underline", "undercurl" ]
|
||||
let hl.cterm[attr] = ''
|
||||
if hl.gui[attr] == 1
|
||||
if s:attr_map(attr) != ''
|
||||
let hl.cterm[ s:attr_map(attr) ] = 1
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
for color in [ "bg", "fg" ]
|
||||
let eff_color = color
|
||||
if hl.cterm['reverse']
|
||||
let eff_color = (color == 'bg' ? 'fg' : 'bg')
|
||||
endif
|
||||
|
||||
let hl.cterm[color] = get(hl.gui, s:attr_map(eff_color), '')
|
||||
endfor
|
||||
|
||||
if hl.gui['sp'] != '' && s:attr_map('sp') != ''
|
||||
let hl.cterm[s:attr_map('sp')] = hl.gui['sp']
|
||||
endif
|
||||
|
||||
if hl.cterm['reverse'] && hl.cterm.bg == ''
|
||||
let hl.cterm.bg = 'fg'
|
||||
endif
|
||||
|
||||
if hl.cterm['reverse'] && hl.cterm.fg == ''
|
||||
let hl.cterm.fg = 'bg'
|
||||
endif
|
||||
|
||||
if hl.cterm['reverse']
|
||||
let hl.cterm.reverse = ''
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" {>2} Kludge around inability to reference autoload functions
|
||||
function! s:DefaultApproximator(...)
|
||||
return call('csapprox#per_component#Approximate', a:000)
|
||||
endfunction
|
||||
|
||||
" {>2} Set cterm colors for a highlight group
|
||||
" Given the information for a single highlight group (ie, the value of
|
||||
" one of the items in s:Highlights() already normalized with s:FixupCtermInfo
|
||||
" and s:FixupGuiInfo), handle matching the gvim colors to the closest cterm
|
||||
" colors by calling the appropriate approximator as specified with the
|
||||
" g:CSApprox_approximator_function variable and set the colors and attributes
|
||||
" appropriately to match the gui.
|
||||
function! s:SetCtermFromGui(hl)
|
||||
let hl = a:hl
|
||||
|
||||
" Set up the default approximator function, if needed
|
||||
if !exists("g:CSApprox_approximator_function")
|
||||
let g:CSApprox_approximator_function = function("s:DefaultApproximator")
|
||||
endif
|
||||
|
||||
" Clear existing highlights
|
||||
exe 'hi ' . hl.name . ' cterm=NONE ctermbg=NONE ctermfg=NONE'
|
||||
|
||||
for which in [ 'bg', 'fg' ]
|
||||
let val = hl.cterm[which]
|
||||
|
||||
" Skip unset colors
|
||||
if val == -1 || val == ""
|
||||
continue
|
||||
endif
|
||||
|
||||
" Try translating anything but 'fg', 'bg', #rrggbb, and rrggbb from an
|
||||
" rgb.txt color to a #rrggbb color
|
||||
if val !~? '^[fb]g$' && val !~ '^#\=\x\{6}$'
|
||||
try
|
||||
" First see if it is in our preset-by-vim rgb list
|
||||
let val = s:rgb_presets[tolower(val)]
|
||||
catch
|
||||
" Then try loading and checking our real rgb list
|
||||
if empty(s:rgb)
|
||||
call s:UpdateRgbHash()
|
||||
endif
|
||||
try
|
||||
let val = s:rgb[tolower(val)]
|
||||
catch
|
||||
" And then barf if we still haven't found it
|
||||
if &verbose
|
||||
echomsg "CSApprox: Colorscheme uses unknown color \"" . val . "\""
|
||||
endif
|
||||
continue
|
||||
endtry
|
||||
endtry
|
||||
endif
|
||||
|
||||
if val =~? '^[fb]g$'
|
||||
exe 'hi ' . hl.name . ' cterm' . which . '=' . val
|
||||
let hl.cterm[which] = val
|
||||
elseif val =~ '^#\=\x\{6}$'
|
||||
let val = substitute(val, '^#', '', '')
|
||||
let r = str2nr(val[0:1], 16)
|
||||
let g = str2nr(val[2:3], 16)
|
||||
let b = str2nr(val[4:5], 16)
|
||||
let hl.cterm[which] = g:CSApprox_approximator_function(r, g, b)
|
||||
exe 'hi ' . hl.name . ' cterm' . which . '=' . hl.cterm[which]
|
||||
else
|
||||
throw "Internal error handling color: " . val
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Finally, set the attributes
|
||||
let attrs = [ 'bold', 'italic', 'underline', 'undercurl' ]
|
||||
call filter(attrs, 'hl.cterm[v:val] == 1')
|
||||
|
||||
if !empty(attrs)
|
||||
exe 'hi ' . hl.name . ' cterm=' . join(attrs, ',')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" {>1} Top-level control
|
||||
|
||||
" Cache the highlight ID of the normal group; it's used often and won't change
|
||||
let s:hlid_normal = hlID('Normal')
|
||||
|
||||
" {>2} Builtin cterm color names above 15
|
||||
" Vim defines some color name to high color mappings internally (see
|
||||
" syntax.c:do_highlight). Since we don't want to overwrite a colorscheme that
|
||||
" was actually written for a high color terminal with our choices, but have no
|
||||
" way to tell if a colorscheme was written for a high color terminal, we fall
|
||||
" back on guessing. If any highlight group has a cterm color set to 16 or
|
||||
" higher, we assume that the user has used a high color colorscheme - unless
|
||||
" that color is one of the below, which vim can set internally when a color is
|
||||
" requested by name.
|
||||
let s:presets_88 = []
|
||||
let s:presets_88 += [32] " Brown
|
||||
let s:presets_88 += [72] " DarkYellow
|
||||
let s:presets_88 += [84] " Gray
|
||||
let s:presets_88 += [84] " Grey
|
||||
let s:presets_88 += [82] " DarkGray
|
||||
let s:presets_88 += [82] " DarkGrey
|
||||
let s:presets_88 += [43] " LightBlue
|
||||
let s:presets_88 += [61] " LightGreen
|
||||
let s:presets_88 += [63] " LightCyan
|
||||
let s:presets_88 += [74] " LightRed
|
||||
let s:presets_88 += [75] " LightMagenta
|
||||
let s:presets_88 += [78] " LightYellow
|
||||
|
||||
let s:presets_256 = []
|
||||
let s:presets_256 += [130] " Brown
|
||||
let s:presets_256 += [130] " DarkYellow
|
||||
let s:presets_256 += [248] " Gray
|
||||
let s:presets_256 += [248] " Grey
|
||||
let s:presets_256 += [242] " DarkGray
|
||||
let s:presets_256 += [242] " DarkGrey
|
||||
let s:presets_256 += [ 81] " LightBlue
|
||||
let s:presets_256 += [121] " LightGreen
|
||||
let s:presets_256 += [159] " LightCyan
|
||||
let s:presets_256 += [224] " LightRed
|
||||
let s:presets_256 += [225] " LightMagenta
|
||||
let s:presets_256 += [229] " LightYellow
|
||||
|
||||
" {>2} Wrapper around :exe to allow :executing multiple commands.
|
||||
" "cmd" is the command to be :executed.
|
||||
" If the variable is a String, it is :executed.
|
||||
" If the variable is a List, each element is :executed.
|
||||
function! s:exe(cmd)
|
||||
if type(a:cmd) == type('')
|
||||
exe a:cmd
|
||||
else
|
||||
for cmd in a:cmd
|
||||
call s:exe(cmd)
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" {>2} Function to handle hooks
|
||||
" Prototype: HandleHooks(type [, scheme])
|
||||
" "type" is the type of hook to be executed, ie. "pre" or "post"
|
||||
" "scheme" is the name of the colorscheme that is currently active, if known
|
||||
"
|
||||
" If the variables g:CSApprox_hook_{type} and g:CSApprox_hook_{scheme}_{type}
|
||||
" exist, this will :execute them in that order. If one does not exist, it
|
||||
" will silently be ignored.
|
||||
"
|
||||
" If the scheme name contains characters that are invalid in a variable name,
|
||||
" they will simply be removed. Ie, g:colors_name = "123 foo_bar-baz456"
|
||||
" becomes "foo_barbaz456"
|
||||
"
|
||||
" NOTE: Exceptions will be printed out, rather than end processing early. The
|
||||
" rationale is that it is worse for the user to fix the hook in an editor with
|
||||
" broken colors. :)
|
||||
function! s:HandleHooks(type, ...)
|
||||
let type = a:type
|
||||
let scheme = (a:0 == 1 ? a:1 : "")
|
||||
let scheme = substitute(scheme, '[^[:alnum:]_]', '', 'g')
|
||||
let scheme = substitute(scheme, '^\d\+', '', '')
|
||||
|
||||
for cmd in [ 'g:CSApprox_hook_' . type,
|
||||
\ 'g:CSApprox_' . scheme . '_hook_' . type,
|
||||
\ 'g:CSApprox_hook_' . scheme . '_' . type ]
|
||||
if exists(cmd)
|
||||
try
|
||||
call s:exe(eval(cmd))
|
||||
catch
|
||||
echomsg "Error processing " . cmd . ":"
|
||||
echomsg v:exception
|
||||
endtry
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" {>2} Main function
|
||||
" Wrapper around the actual implementation to make it easier to ensure that
|
||||
" all temporary settings are restored by the time we return, whether or not
|
||||
" something was thrown. Additionally, sets the 'verbose' option to the max of
|
||||
" g:CSApprox_verbose_level (default 1) and &verbose for the duration of the
|
||||
" main function. This allows us to default to a message whenever any error,
|
||||
" even a recoverable one, occurs, meaning the user quickly finds out when
|
||||
" something's wrong, but makes it very easy for the user to make us silent.
|
||||
function! s:CSApprox(...)
|
||||
try
|
||||
if a:0 == 1 && a:1
|
||||
if !exists('s:inhibit_hicolor_test')
|
||||
let s:inhibit_hicolor_test = 0
|
||||
endif
|
||||
let s:inhibit_hicolor_test += 1
|
||||
endif
|
||||
|
||||
let savelz = &lz
|
||||
|
||||
set lz
|
||||
|
||||
if exists("g:CSApprox_attr_map") && type(g:CSApprox_attr_map) == type({})
|
||||
call s:NormalizeAttrMap(g:CSApprox_attr_map)
|
||||
else
|
||||
let g:CSApprox_attr_map = { 'italic' : 'underline', 'sp' : 'fg' }
|
||||
endif
|
||||
|
||||
" colors_name must be unset and reset, or vim will helpfully reload the
|
||||
" colorscheme when we set the background for the Normal group.
|
||||
" See the help entries ':hi-normal-cterm' and 'g:colors_name'
|
||||
if exists("g:colors_name")
|
||||
let colors_name = g:colors_name
|
||||
unlet g:colors_name
|
||||
endif
|
||||
|
||||
" Similarly, the global variable "syntax_cmd" must be set to something vim
|
||||
" doesn't recognize, lest vim helpfully switch all colors back to the
|
||||
" default whenever the Normal group is changed (in syncolor.vim)...
|
||||
if exists("g:syntax_cmd")
|
||||
let syntax_cmd = g:syntax_cmd
|
||||
endif
|
||||
let g:syntax_cmd = "PLEASE DON'T CHANGE ANY COLORS!!!"
|
||||
|
||||
" Set up our verbosity level, if needed.
|
||||
" Default to 1, so the user can know if something's wrong.
|
||||
if !exists("g:CSApprox_verbose_level")
|
||||
let g:CSApprox_verbose_level = 1
|
||||
endif
|
||||
|
||||
call s:HandleHooks("pre", (exists("colors_name") ? colors_name : ""))
|
||||
|
||||
" Set 'verbose' set to the maximum of &verbose and CSApprox_verbose_level
|
||||
exe max([&vbs, g:CSApprox_verbose_level]) 'verbose call s:CSApproxImpl()'
|
||||
|
||||
call s:HandleHooks("post", (exists("colors_name") ? colors_name : ""))
|
||||
finally
|
||||
if exists("colors_name")
|
||||
let g:colors_name = colors_name
|
||||
endif
|
||||
|
||||
unlet g:syntax_cmd
|
||||
if exists("syntax_cmd")
|
||||
let g:syntax_cmd = syntax_cmd
|
||||
endif
|
||||
|
||||
let &lz = savelz
|
||||
|
||||
if a:0 == 1 && a:1
|
||||
let s:inhibit_hicolor_test -= 1
|
||||
if s:inhibit_hicolor_test == 0
|
||||
unlet s:inhibit_hicolor_test
|
||||
endif
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" {>2} CSApprox implementation
|
||||
" Verifies that the user has not started the gui, and that vim recognizes his
|
||||
" terminal as having enough colors for us to go on, then gathers the existing
|
||||
" highlights and sets the cterm colors to match the gui colors for all those
|
||||
" highlights (unless the colorscheme was already high-color).
|
||||
function! s:CSApproxImpl()
|
||||
" Return if not running in an 88/256 color terminal
|
||||
if &t_Co != 256 && &t_Co != 88
|
||||
if &verbose && !has('gui_running')
|
||||
echomsg "CSApprox skipped; terminal only has" &t_Co "colors, not 88/256"
|
||||
echomsg "Try checking :help csapprox-terminal for workarounds"
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
" Get the current highlight colors
|
||||
let highlights = s:Highlights(["gui"])
|
||||
|
||||
let hinums = keys(highlights)
|
||||
|
||||
" Make sure that the script is not already 256 color by checking to make
|
||||
" sure that no groups are set to a value above 256, unless the color they're
|
||||
" set to can be set internally by vim (gotten by scraping
|
||||
" color_numbers_{88,256} in syntax.c:do_highlight)
|
||||
"
|
||||
" XXX: s:inhibit_hicolor_test allows this test to be skipped for snapshots
|
||||
if !exists("s:inhibit_hicolor_test") || !s:inhibit_hicolor_test
|
||||
for hlid in hinums
|
||||
for type in [ 'bg', 'fg' ]
|
||||
let color = synIDattr(hlid, type, 'cterm')
|
||||
|
||||
if color > 15 && index(s:presets_{&t_Co}, str2nr(color)) < 0
|
||||
" The value is set above 15, and wasn't set by vim.
|
||||
if &verbose >= 2
|
||||
echomsg 'CSApprox: Exiting - high' type 'color found for' highlights[hlid].name
|
||||
endif
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
|
||||
call s:FixupGuiInfo(highlights)
|
||||
call s:FixupCtermInfo(highlights)
|
||||
|
||||
" We need to set the Normal group first so 'bg' and 'fg' work as colors
|
||||
call insert(hinums, remove(hinums, index(hinums, string(s:hlid_normal))))
|
||||
|
||||
" then set each color's cterm attributes to match gui
|
||||
for hlid in hinums
|
||||
call s:SetCtermFromGui(highlights[hlid])
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" {>2} Write out the current colors to an 88/256 color colorscheme file.
|
||||
" "file" - destination filename
|
||||
" "overwrite" - overwrite an existing file
|
||||
function! s:CSApproxSnapshot(file, overwrite)
|
||||
let force = a:overwrite
|
||||
let file = fnamemodify(a:file, ":p")
|
||||
|
||||
if empty(file)
|
||||
throw "Bad file name: \"" . file . "\""
|
||||
elseif (filewritable(fnamemodify(file, ':h')) != 2)
|
||||
throw "Cannot write to directory \"" . fnamemodify(file, ':h') . "\""
|
||||
elseif (glob(file) || filereadable(file)) && !force
|
||||
" TODO - respect 'confirm' here and prompt if it's set.
|
||||
echohl ErrorMsg
|
||||
echomsg "E13: File exists (add ! to override)"
|
||||
echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
" Sigh... This is basically a bug, but one that I have no chance of fixing.
|
||||
" Vim decides that Pmenu should be highlighted in 'LightMagenta' in terminal
|
||||
" vim and as 'Magenta' in gvim... And I can't ask it what color it actually
|
||||
" *wants*. As far as I can see, there's no way for me to learn that
|
||||
" I should output 'Magenta' when 'LightMagenta' is provided by vim for the
|
||||
" terminal.
|
||||
if !has('gui_running')
|
||||
echohl WarningMsg
|
||||
echomsg "Warning: The written colorscheme may have incorrect colors"
|
||||
echomsg " when CSApproxSnapshot is used in terminal vim!"
|
||||
echohl None
|
||||
endif
|
||||
|
||||
let save_t_Co = &t_Co
|
||||
let s:inhibit_hicolor_test = 1
|
||||
if exists("g:CSApprox_konsole")
|
||||
let save_CSApprox_konsole = g:CSApprox_konsole
|
||||
endif
|
||||
if exists("g:CSApprox_eterm")
|
||||
let save_CSApprox_eterm = g:CSApprox_eterm
|
||||
endif
|
||||
|
||||
" Needed just like in CSApprox()
|
||||
if exists("g:colors_name")
|
||||
let colors_name = g:colors_name
|
||||
unlet g:colors_name
|
||||
endif
|
||||
|
||||
" Needed just like in CSApprox()
|
||||
if exists("g:syntax_cmd")
|
||||
let syntax_cmd = g:syntax_cmd
|
||||
endif
|
||||
let g:syntax_cmd = "PLEASE DON'T CHANGE ANY COLORS!!!"
|
||||
|
||||
try
|
||||
let lines = []
|
||||
let lines += [ '" This scheme was created by CSApproxSnapshot' ]
|
||||
let lines += [ '" on ' . strftime("%a, %d %b %Y") ]
|
||||
let lines += [ '' ]
|
||||
let lines += [ 'hi clear' ]
|
||||
let lines += [ 'if exists("syntax_on")' ]
|
||||
let lines += [ ' syntax reset' ]
|
||||
let lines += [ 'endif' ]
|
||||
let lines += [ '' ]
|
||||
let lines += [ 'if v:version < 700' ]
|
||||
let lines += [ ' let g:colors_name = expand("<sfile>:t:r")' ]
|
||||
let lines += [ ' command! -nargs=+ CSAHi exe "hi" substitute(substitute(<q-args>, "undercurl", "underline", "g"), "guisp\\S\\+", "", "g")' ]
|
||||
let lines += [ 'else' ]
|
||||
let lines += [ ' let g:colors_name = expand("<sfile>:t:r")' ]
|
||||
let lines += [ ' command! -nargs=+ CSAHi exe "hi" <q-args>' ]
|
||||
let lines += [ 'endif' ]
|
||||
let lines += [ '' ]
|
||||
|
||||
let lines += [ 'if 0' ]
|
||||
for round in [ 'konsole', 'eterm', 'xterm', 'urxvt' ]
|
||||
sil! unlet g:CSApprox_eterm
|
||||
sil! unlet g:CSApprox_konsole
|
||||
|
||||
if round == 'konsole'
|
||||
let g:CSApprox_konsole = 1
|
||||
elseif round == 'eterm'
|
||||
let g:CSApprox_eterm = 1
|
||||
endif
|
||||
|
||||
if round == 'urxvt'
|
||||
set t_Co=88
|
||||
else
|
||||
set t_Co=256
|
||||
endif
|
||||
|
||||
call s:CSApprox()
|
||||
|
||||
let highlights = s:Highlights(["term", "cterm", "gui"])
|
||||
call s:FixupGuiInfo(highlights)
|
||||
|
||||
if round == 'konsole' || round == 'eterm'
|
||||
let lines += [ 'elseif has("gui_running") || (&t_Co == ' . &t_Co
|
||||
\ . ' && (&term ==# "xterm" || &term =~# "^screen")'
|
||||
\ . ' && exists("g:CSApprox_' . round . '")'
|
||||
\ . ' && g:CSApprox_' . round . ')'
|
||||
\ . ' || &term =~? "^' . round . '"' ]
|
||||
else
|
||||
let lines += [ 'elseif has("gui_running") || &t_Co == ' . &t_Co ]
|
||||
endif
|
||||
|
||||
let hinums = keys(highlights)
|
||||
|
||||
call insert(hinums, remove(hinums, index(hinums, string(s:hlid_normal))))
|
||||
|
||||
for hlnum in hinums
|
||||
let hl = highlights[hlnum]
|
||||
let line = ' CSAHi ' . hl.name
|
||||
for type in [ 'term', 'cterm', 'gui' ]
|
||||
let attrs = [ 'reverse', 'bold', 'italic', 'underline', 'undercurl' ]
|
||||
call filter(attrs, 'hl[type][v:val] == 1')
|
||||
let line .= ' ' . type . '=' . (empty(attrs) ? 'NONE' : join(attrs, ','))
|
||||
if type != 'term'
|
||||
let line .= ' ' . type . 'bg=' . (len(hl[type].bg) ? hl[type].bg : 'bg')
|
||||
let line .= ' ' . type . 'fg=' . (len(hl[type].fg) ? hl[type].fg : 'fg')
|
||||
if type == 'gui' && hl.gui.sp !~ '^\s*$'
|
||||
let line .= ' ' . type . 'sp=' . hl[type].sp
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let lines += [ line ]
|
||||
endfor
|
||||
endfor
|
||||
let lines += [ 'endif' ]
|
||||
let lines += [ '' ]
|
||||
let lines += [ 'if 1' ]
|
||||
let lines += [ ' delcommand CSAHi' ]
|
||||
let lines += [ 'endif' ]
|
||||
call writefile(lines, file)
|
||||
finally
|
||||
let &t_Co = save_t_Co
|
||||
|
||||
if exists("save_CSApprox_konsole")
|
||||
let g:CSApprox_konsole = save_CSApprox_konsole
|
||||
endif
|
||||
if exists("save_CSApprox_eterm")
|
||||
let g:CSApprox_eterm = save_CSApprox_eterm
|
||||
endif
|
||||
|
||||
if exists("colors_name")
|
||||
let g:colors_name = colors_name
|
||||
endif
|
||||
|
||||
unlet g:syntax_cmd
|
||||
if exists("syntax_cmd")
|
||||
let g:syntax_cmd = syntax_cmd
|
||||
endif
|
||||
|
||||
call s:CSApprox()
|
||||
|
||||
unlet s:inhibit_hicolor_test
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" {>2} Snapshot user command
|
||||
command! -bang -nargs=1 -complete=file -bar CSApproxSnapshot
|
||||
\ call s:CSApproxSnapshot(<f-args>, strlen("<bang>"))
|
||||
|
||||
" {>2} Manual updates
|
||||
command -bang -bar CSApprox call s:CSApprox(strlen("<bang>"))
|
||||
|
||||
" {>1} Hooks
|
||||
|
||||
" {>2} Autocmds
|
||||
" Set up an autogroup to hook us on the completion of any :colorscheme command
|
||||
augroup CSApprox
|
||||
au!
|
||||
au ColorScheme * call s:CSApprox()
|
||||
"au User CSApproxPost highlight Normal ctermbg=none | highlight NonText ctermbg=None
|
||||
augroup END
|
||||
|
||||
" {>2} Execute
|
||||
" The last thing to do when sourced is to run and actually fix up the colors.
|
||||
if !has('gui_running')
|
||||
call s:CSApprox()
|
||||
endif
|
||||
|
||||
" {>1} Restore compatibility options
|
||||
let &cpo = s:savecpo
|
||||
unlet s:savecpo
|
||||
|
||||
|
||||
" {0} vim:sw=2:sts=2:et:fdm=expr:fde=substitute(matchstr(getline(v\:lnum),'^\\s*"\\s*{\\zs.\\{-}\\ze}'),'^$','=','')
|
||||
466
vim/plugin/ColorSchemeMenuMaker.vim
Normal file
466
vim/plugin/ColorSchemeMenuMaker.vim
Normal file
@@ -0,0 +1,466 @@
|
||||
" theme.menu.vim: Generates Vim themes menu and organizes themes based
|
||||
" upon background colors
|
||||
" Maintainer: Erik Falor <rAjsBnFCybe@tzNnvy.Zpbz g?? - NOSPAM>
|
||||
" Date: Aug 30, 2007
|
||||
" Version: 0.4
|
||||
"
|
||||
|
||||
" Initialization: {{{
|
||||
if exists("g:loaded_theme_menu") || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_theme_menu= "0.4"
|
||||
let s:keepcpo = &cpo
|
||||
set cpo&vim
|
||||
"}}}
|
||||
|
||||
" Script Variables: {{{
|
||||
let s:menuFile = strpart(&rtp, 0, stridx(&rtp, ',')) . '/plugin/ColorSchemes.vim'
|
||||
let s:menuName = '&ColorSchemes'
|
||||
let s:xdigit = '[0123456789ABCDEFabcdef]'
|
||||
let s:hexvals = { 0:0, 1:1, 2:2, 3:3,
|
||||
\4:4, 5:5, 6:6, 7:7,
|
||||
\8:8, 9:9, 'a':10, 'b':11,
|
||||
\'c':12, 'd':13, 'e':14, 'f':15,
|
||||
\'A':10, 'B':11, 'C':12, 'D':13,
|
||||
\'E':14, 'F':15 }
|
||||
"}}}
|
||||
|
||||
" Library Functions {{{
|
||||
function! <SID>RGBtoHSV(r, g, b) "{{{
|
||||
let h = 0
|
||||
let s = 0
|
||||
let v = 0
|
||||
if (a:b > a:g) && (a:b > a:r)
|
||||
let v = a:b
|
||||
if v != 0
|
||||
let min = 0
|
||||
if(a:r > a:g)
|
||||
let min = a:g
|
||||
else
|
||||
let min = a:r
|
||||
endif
|
||||
|
||||
let delta = v - min
|
||||
|
||||
if delta != 0
|
||||
let s = (delta * 255) / v
|
||||
let h = 240 + (60 * a:r - 60 * a:g) / delta
|
||||
else
|
||||
let s = 0
|
||||
let h = 240 + (60 * a:r - 60 * a:g)
|
||||
endif
|
||||
if h < 0
|
||||
let h = h + 360
|
||||
endif
|
||||
else
|
||||
let s = 0
|
||||
let h = 0
|
||||
endif
|
||||
elseif a:g > a:r
|
||||
let v = a:g
|
||||
if v != 0
|
||||
let min = 0
|
||||
if a:r > a:b
|
||||
let min = a:b
|
||||
else
|
||||
let min = a:r
|
||||
endif
|
||||
let delta = v - min
|
||||
if delta != 0
|
||||
let s = (delta * 255) / v
|
||||
let h = 120 + (60 * a:b - 60 * a:r) / delta
|
||||
else
|
||||
let s = 0
|
||||
let h = 120 + (60 * a:b - 60 * a:r)
|
||||
endif
|
||||
if h < 0
|
||||
let h = h + 360
|
||||
endif
|
||||
else
|
||||
let s = 0
|
||||
let h = 0
|
||||
endif
|
||||
else
|
||||
let v = a:r
|
||||
if v != 0
|
||||
let min = 0
|
||||
if a:g > a:b
|
||||
let min = a:b
|
||||
else
|
||||
let min = a:g
|
||||
endif
|
||||
let delta = v - min
|
||||
if delta != 0
|
||||
let s = (delta * 255) / v
|
||||
let h = (60 * a:g - 60 * a:b) / delta
|
||||
else
|
||||
let s = 0
|
||||
let h = 60 * a:g - 60 * a:b
|
||||
endif
|
||||
if h < 0
|
||||
let h = h + 360
|
||||
endif
|
||||
else
|
||||
let s = 0
|
||||
let h = 0
|
||||
endif
|
||||
endif
|
||||
return [h, s, v]
|
||||
endfunction "RGBtoHSV()
|
||||
"}}}
|
||||
|
||||
function! <SID>IsBlack(r, g, b, h, s, v) "{{{
|
||||
if a:r == a:g && a:g == a:b && a:b == 0
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "IsBlack()}}}
|
||||
|
||||
function! <SID>IsWhite(r, g, b, h, s, v) "{{{
|
||||
if a:r == a:g && a:g == a:b && a:b == 255
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "IsWhite()}}}
|
||||
|
||||
function! <SID>IsDarkGrey(r, g, b, h, s, v) "{{{
|
||||
let diffRGB = max([a:r, a:g, a:b]) - min([a:r, a:g, a:b])
|
||||
let darkGreyFuzz = 20
|
||||
if diffRGB <= darkGreyFuzz
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "IsDarkGrey()}}}
|
||||
|
||||
function! <SID>IsOffWhite(r, g, b, h, s, v) "{{{
|
||||
let offWhiteSat = 32
|
||||
let offWhiteVal = 255 - 32
|
||||
if a:v >= offWhiteVal && a:s <= offWhiteSat
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsGrey(r, g, b, h, s, v) "{{{
|
||||
let diffRGB = max([a:r, a:g, a:b]) - min([a:r, a:g, a:b])
|
||||
let greyFuzz = 28
|
||||
let greyVal = 32
|
||||
|
||||
if diffRGB > greyFuzz
|
||||
return 0
|
||||
elseif (a:s <= greyFuzz )
|
||||
\&& (a:v <= 255 - (greyVal * 1))
|
||||
\&& (a:v >= 0 + (greyVal * 1))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsYellow(r, g, b, h, s, v) "{{{
|
||||
if a:h > 30 && a:h <= 90
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsGreen(r, g, b, h, s, v) "{{{
|
||||
if a:h > 90 && a:h <= 180
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsCyan(r, g, b, h, s, v) "{{{
|
||||
" cyan will be 180 deg +/- 10 deg
|
||||
let variance = 10
|
||||
if a:h > 180 - variance && a:h < 180 + variance
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsBlue(r, g, b, h, s, v) "{{{
|
||||
if a:h > 180 && a:h <= 270
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsMagenta(r, g, b, h, s, v) "{{{
|
||||
if a:h > 270 && a:h <= 330
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction }}}
|
||||
|
||||
function! <SID>IsOrange(r, g, b, h, s, v) "{{{
|
||||
"a magic number found through trial and error
|
||||
let greenFuzz = 172
|
||||
if a:r > a:g && a:b == 0 && a:g < greenFuzz && a:g != 0
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>IsRed(r, g, b, h, s, v) "{{{
|
||||
if a:h > 330 || a:h <= 30
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>RgbTxt2Hexes() "{{{
|
||||
"read rgb.txt, return dictionary mapping color names to hex triplet
|
||||
if exists("g:rgbtxt") && filereadable(g:rgbtxt)
|
||||
let rgbtxt = g:rgbtxt
|
||||
else
|
||||
if has("win32") || has("win64")
|
||||
let rgbtxt = expand("$VIMRUNTIME/rgb.txt")
|
||||
elseif filereadable("/usr/X11R6/lib/X11/rgb.txt")
|
||||
let rgbtxt = "/usr/X11R6/lib/X11/rgb.txt"
|
||||
elseif filereadable("/usr/share/X11/rgb.txt")
|
||||
let rgbtxt = "/usr/share/X11/rgb.txt"
|
||||
endif
|
||||
endif
|
||||
let rgbdict = {}
|
||||
if filereadable(rgbtxt)
|
||||
for line in readfile(rgbtxt)
|
||||
if line !~ '^\(!\|#\)'
|
||||
let l = matchlist(line, '\s*\(\d\+\)\s*\(\d\+\)\s*\(\d\+\)\s*\(.*\)')
|
||||
let rgbdict[tolower(l[4])] = printf('%02X%02X%02X', l[1], l[2], l[3])
|
||||
endif
|
||||
endfor
|
||||
"note: vim treats guibg=NONE as guibg=white
|
||||
let rgbdict['none'] = 'FFFFFF'
|
||||
else
|
||||
echoerr "ColorSchemeMenuMaker.vim could not open rgb.txt file at " . rgbtxt
|
||||
endif
|
||||
return rgbdict
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>RGBHexToHexes(rgb) "{{{
|
||||
let xdigits = '\(' . s:xdigit . '\{2\}\)'
|
||||
let pat = '\(#\)\?' . xdigits . xdigits . xdigits
|
||||
let l = matchlist(a:rgb, pat)
|
||||
if len(l) > 0
|
||||
return [ l[2], l[3], l[4] ]
|
||||
else
|
||||
return []
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>RGBHexToInts(rgbList) "{{{
|
||||
return map(a:rgbList, '<SID>Hex2Int(v:val)')
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>Hex2Int(hex) "{{{
|
||||
let xdigits = split(a:hex, '\zs')
|
||||
return 16 * s:hexvals[xdigits[0]] + s:hexvals[xdigits[1]]
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>RGB2BoyColor(rgb) "{{{
|
||||
let rgbL = <SID>RGBHexToInts(<SID>RGBHexToHexes(a:rgb))
|
||||
let r = rgbL[0] | let g = rgbL[1] | let b = rgbL[2]
|
||||
let hsvL = <SID>RGBtoHSV(r, g, b)
|
||||
let h = hsvL[0] | let s = hsvL[1] | let v = hsvL[2]
|
||||
if <SID>IsBlack(r, g, b, h, s, v) == 1 | return 'black' | endif
|
||||
if <SID>IsWhite(r, g, b, h, s, v) == 1 | return 'white' | endif
|
||||
if <SID>IsGrey(r, g, b, h, s, v) == 1 | return 'grey' | endif
|
||||
if <SID>IsOffWhite(r, g, b, h, s, v) == 1 | return 'offwhite' | endif
|
||||
if <SID>IsDarkGrey(r, g, b, h, s, v) == 1 | return 'darkgrey' | endif
|
||||
if <SID>IsOrange(r, g, b, h, s, v) == 1 | return 'orange' | endif
|
||||
if <SID>IsYellow(r, g, b, h, s, v) == 1 | return 'yellow' | endif
|
||||
if <SID>IsCyan(r, g, b, h, s, v) == 1 | return 'cyan' | endif
|
||||
if <SID>IsGreen(r, g, b, h, s, v) == 1 | return 'green' | endif
|
||||
if <SID>IsBlue(r, g, b, h, s, v) == 1 | return 'blue' | endif
|
||||
if <SID>IsMagenta(r, g, b, h, s, v) == 1 | return 'magenta' | endif
|
||||
if <SID>IsRed(r, g, b, h, s, v) == 1 | return 'red' | endif
|
||||
return 'unknown'
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>GlobThemes() "{{{
|
||||
"return list containing paths to all theme files in &runtimepath
|
||||
return split(globpath(&rtp, 'colors/*.vim'), '\n')
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>ScanThemeBackground() "{{{
|
||||
"Read each of the theme files and find out which color
|
||||
"each theme 'basically' is. Uses the last 'hi Normal'
|
||||
"group found to classify by color. Notes those color
|
||||
"files that do have more than one 'hi Normal' command.
|
||||
let name2hex = <SID>RgbTxt2Hexes()
|
||||
let themeColors = {}
|
||||
let themeNames = {}
|
||||
let i = 0
|
||||
let pat = 'hi.*\s\+Normal\s\+.\{-}guibg=\(#\?\)\(\w\+\)'
|
||||
for theme in <SID>GlobThemes()
|
||||
if filereadable(theme)
|
||||
|
||||
"DEBUG
|
||||
"let i = i + 1
|
||||
"if i > 10
|
||||
"break
|
||||
"endif
|
||||
|
||||
let higroupfound = 0
|
||||
let color = ''
|
||||
for line in readfile(theme)
|
||||
let bg = matchlist(line, pat)
|
||||
if len(bg) > 0
|
||||
if bg[1] == '#'
|
||||
let color = <SID>RGB2BoyColor(bg[2])
|
||||
else
|
||||
if has_key(name2hex, tolower(bg[2]))
|
||||
let color = <SID>RGB2BoyColor(name2hex[tolower(bg[2])])
|
||||
else
|
||||
let color = 'unknown'
|
||||
endif
|
||||
endif
|
||||
let higroupfound += 1
|
||||
endif
|
||||
endfor
|
||||
let themename = fnamemodify(theme, ':t:r')
|
||||
let letter = toupper(strpart(themename, 0, 1))
|
||||
if letter =~ '\d' | let letter = '#' | endif
|
||||
|
||||
if len(color) < 1
|
||||
let color = 'unknown'
|
||||
endif
|
||||
|
||||
"allocate sub-dict if needed
|
||||
if !has_key(themeColors, color)
|
||||
let themeColors[color] = {}
|
||||
endif
|
||||
"allocate sub-dict if needed
|
||||
if !has_key(themeNames, letter)
|
||||
let themeNames[letter] = {}
|
||||
endif
|
||||
if higroupfound > 1
|
||||
"mark themes with many 'hi Normal' commands
|
||||
if len(color) > 0
|
||||
let themeColors[color][themename] = '*' . themename
|
||||
endif
|
||||
let themeNames[letter][themename] = '*' . themename
|
||||
else
|
||||
if len(color) > 0
|
||||
let themeColors[color][themename] = themename
|
||||
endif
|
||||
let themeNames[letter][themename] = themename
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return [themeColors, themeNames]
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>BuildMenu(dicts) "{{{
|
||||
"puts menu commands into a list
|
||||
let menu = []
|
||||
call add(menu, '"ColorScheme menu generated ' . strftime("%c", localtime()))
|
||||
call add(menu, '')
|
||||
call add(menu, '"Themes by color:')
|
||||
call add(menu, '')
|
||||
"count number of themes categorized by color
|
||||
let totThemes = 0
|
||||
for i in keys(a:dicts[0])
|
||||
let totThemes += len(a:dicts[0][i])
|
||||
endfor
|
||||
for color in sort(keys(a:dicts[0]))
|
||||
let numThemes = len(a:dicts[0][color])
|
||||
call add(menu, '')
|
||||
call add(menu, '"submenu '. color)
|
||||
for theme in sort(keys(a:dicts[0][color]))
|
||||
call add(menu, '9000amenu '. s:menuName. '.&Colors\ ('. totThemes . ').'
|
||||
\. color . '\ ('. numThemes . ').'
|
||||
\. a:dicts[0][color][theme]. ' :colo '. theme . '<CR>')
|
||||
endfor
|
||||
endfor
|
||||
call add(menu, '"Themes by name:')
|
||||
call add(menu, '')
|
||||
"count number of themes categorized by name
|
||||
let totThemes = 0
|
||||
for i in keys(a:dicts[1])
|
||||
let totThemes += len(a:dicts[1][i])
|
||||
endfor
|
||||
for letter in sort(keys(a:dicts[1]))
|
||||
let numThemes = len(a:dicts[1][letter])
|
||||
call add(menu, '')
|
||||
call add(menu, '"submenu '. letter)
|
||||
for theme in sort(keys(a:dicts[1][letter]))
|
||||
call add(menu, 'amenu '. s:menuName. '.&Names\ (' . totThemes . ').'
|
||||
\. letter . '\ ('. numThemes .').'
|
||||
\. a:dicts[1][letter][theme] . ' :colo '. theme . '<CR>')
|
||||
endfor
|
||||
endfor
|
||||
|
||||
call add(menu, '')
|
||||
"add a separator and a command to re-init the menu
|
||||
call add(menu, 'amenu ' . s:menuName .'.-Sep- :')
|
||||
call add(menu, 'amenu ' . s:menuName .'.Reload\ Menu :ReloadColors<CR>')
|
||||
call add(menu, 'amenu ' . s:menuName .'.Refresh\ Menu :RefreshColors<CR>')
|
||||
call add(menu, '')
|
||||
call add(menu, 'command! -nargs=0 ReloadColors call <SID>ReloadColors()')
|
||||
call add(menu, 'command! -nargs=0 RefreshColors call <SID>RefreshColors()')
|
||||
call add(menu, '')
|
||||
call add(menu, 'if !exists("g:running_ReloadColors")')
|
||||
call add(menu, ' function! <SID>ReloadColors()')
|
||||
call add(menu, ' let g:running_ReloadColors = 1')
|
||||
call add(menu, ' aunmenu ' . s:menuName)
|
||||
call add(menu, " execute 'source " . s:menuFile . "'")
|
||||
call add(menu, ' unlet g:running_ReloadColors')
|
||||
call add(menu, " echomsg 'Done Reloading " . s:menuFile . "'")
|
||||
call add(menu, ' endfunction')
|
||||
call add(menu, 'endif')
|
||||
|
||||
call add(menu, 'if !exists("g:running_RefreshColors")')
|
||||
call add(menu, ' function! <SID>RefreshColors()')
|
||||
call add(menu, ' let g:running_RefreshColors = 1')
|
||||
call add(menu, ' call WriteColorSchemeMenu()')
|
||||
call add(menu, ' call <SID>ReloadColors()')
|
||||
call add(menu, ' unlet g:running_RefreshColors')
|
||||
call add(menu, " echomsg 'Done Refreshing " . s:menuFile . "'")
|
||||
call add(menu, ' endfunction')
|
||||
call add(menu, 'endif')
|
||||
|
||||
return menu
|
||||
endfunction "}}}
|
||||
|
||||
function! WriteColorSchemeMenu() "{{{
|
||||
"Builds the menu from the two dicts returned by ScanThemeBackground()
|
||||
"Stores menu in first plugin dir specified by &rtp
|
||||
let menu = <SID>BuildMenu(<SID>ScanThemeBackground())
|
||||
call writefile(menu, s:menuFile)
|
||||
endfunction "}}}
|
||||
|
||||
function! <SID>InitMenu() "{{{
|
||||
call WriteColorSchemeMenu()
|
||||
execute "source " . s:menuFile
|
||||
endfunction "}}}
|
||||
|
||||
"}}}
|
||||
|
||||
" Restore &cpo: {{{1
|
||||
let &cpo= s:keepcpo
|
||||
unlet s:keepcpo
|
||||
"}}}1
|
||||
|
||||
"Detect absence of ColorScheme menu, and generate a new one automatically
|
||||
if !filereadable(s:menuFile) "{{{
|
||||
echomsg "Creating ColorScheme menu - Please Wait..."
|
||||
call <SID>InitMenu()
|
||||
echomsg "Done!"
|
||||
endif "}}}
|
||||
|
||||
" vim: tabstop=4 foldmethod=marker
|
||||
486
vim/plugin/ColorSchemes.vim
Normal file
486
vim/plugin/ColorSchemes.vim
Normal file
@@ -0,0 +1,486 @@
|
||||
"ColorScheme menu generated Sat 01 Sep 2007 23:21:10 NZST
|
||||
|
||||
"Themes by color:
|
||||
|
||||
|
||||
"submenu black
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).adrian :colo adrian<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*af :colo af<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).billw :colo billw<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*black_angus :colo black_angus<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).blackbeauty :colo blackbeauty<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).blacksea :colo blacksea<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).blugrine :colo blugrine<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).brookstream :colo brookstream<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).candy :colo candy<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).colorer :colo colorer<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dante :colo dante<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).darkblack :colo darkblack<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).darkocean :colo darkocean<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_blue :colo dw_blue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_cyan :colo dw_cyan<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_green :colo dw_green<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_orange :colo dw_orange<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_purple :colo dw_purple<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_red :colo dw_red<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).dw_yellow :colo dw_yellow<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).elflord :colo elflord<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).fnaqevan :colo fnaqevan<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).golden :colo golden<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).gothic :colo gothic<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdblue :colo hhdblue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdcyan :colo hhdcyan<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdgray :colo hhdgray<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdgreen :colo hhdgreen<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdmagenta :colo hhdmagenta<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdred :colo hhdred<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).hhdyellow :colo hhdyellow<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*inkpot :colo inkpot<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).jhdark :colo jhdark<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).koehler :colo koehler<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).less :colo less<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).manxome :colo manxome<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).matrix :colo matrix<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).metacosm :colo metacosm<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*motus :colo motus<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).murphy :colo murphy<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).neverness :colo neverness<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).nightwish :colo nightwish<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).oceanblack :colo oceanblack<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).pablo :colo pablo<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).potts :colo potts<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*ps_color :colo ps_color<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).putty :colo putty<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).redblack :colo redblack<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).relaxedgreen :colo relaxedgreen<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).revolutions :colo revolutions<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).ron :colo ron<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).sean :colo sean<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).tango :colo tango<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*torte :colo torte<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).vibrantink :colo vibrantink<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).*vividchalk :colo vividchalk<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).black\ (57).wintersday :colo wintersday<CR>
|
||||
|
||||
"submenu blue
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).adam :colo adam<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).adaryn :colo adaryn<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).aqua :colo aqua<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).astronaut :colo astronaut<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).asu1dark :colo asu1dark<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).blue :colo blue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).bluegreen :colo bluegreen<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).borland :colo borland<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).breeze :colo breeze<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).caramel :colo caramel<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).cleanphp :colo cleanphp<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).*cool :colo cool<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).darkblue :colo darkblue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).darkblue2 :colo darkblue2<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).denim :colo denim<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).desertedocean :colo desertedocean<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).dusk :colo dusk<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).edo_sea :colo edo_sea<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).hhazure :colo hhazure<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).ibmedit :colo ibmedit<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).midnight :colo midnight<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).midnight2 :colo midnight2<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).navajo-night :colo navajo-night<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).nightshimmer :colo nightshimmer<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).northsky :colo northsky<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).oceandeep :colo oceandeep<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).sea :colo sea<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).softblue :colo softblue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).transparent :colo transparent<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).blue\ (30).turbo :colo turbo<CR>
|
||||
|
||||
"submenu cyan
|
||||
9000amenu &ColorSchemes.&Colors\ (190).cyan\ (3).darkslategray :colo darkslategray<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).cyan\ (3).gor :colo gor<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).cyan\ (3).marklar :colo marklar<CR>
|
||||
|
||||
"submenu darkgrey
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).candycode :colo candycode<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).darkdot :colo darkdot<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).darktango :colo darktango<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).greyblue :colo greyblue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).hhspring :colo hhspring<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).hhteal :colo hhteal<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).hhviolet :colo hhviolet<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).lettuce :colo lettuce<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).night :colo night<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).darkgrey\ (10).rdark :colo rdark<CR>
|
||||
|
||||
"submenu green
|
||||
9000amenu &ColorSchemes.&Colors\ (190).green\ (2).earth :colo earth<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).green\ (2).*tabula :colo tabula<CR>
|
||||
|
||||
"submenu grey
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).biogoo :colo biogoo<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).blackdust :colo blackdust<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).camo :colo camo<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).*dawn :colo dawn<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).desert :colo desert<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).desertEx :colo desertEx<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).evening :colo evening<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).fog :colo fog<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).freya :colo freya<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).jhlight :colo jhlight<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).neon :colo neon<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).slate :colo slate<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).toothpik :colo toothpik<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).umber-green :colo umber-green<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).whitedust :colo whitedust<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).xemacs :colo xemacs<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).grey\ (17).*zenburn :colo zenburn<CR>
|
||||
|
||||
"submenu magenta
|
||||
9000amenu &ColorSchemes.&Colors\ (190).magenta\ (1).lilac :colo lilac<CR>
|
||||
|
||||
"submenu offwhite
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).automation :colo automation<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).autumn :colo autumn<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).autumn2 :colo autumn2<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).autumnleaf :colo autumnleaf<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).*baycomb :colo baycomb<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).bmichaelsen :colo bmichaelsen<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).fine_blue :colo fine_blue<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).fruit :colo fruit<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).habiLight :colo habiLight<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).ironman :colo ironman<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).mod_tcsoft :colo mod_tcsoft<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).morning :colo morning<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).nedit :colo nedit<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).nedit2 :colo nedit2<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).nuvola :colo nuvola<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).oceanlight :colo oceanlight<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).pyte :colo pyte<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).python :colo python<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).seashell :colo seashell<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).sf :colo sf<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).offwhite\ (21).simpleandfriendly :colo simpleandfriendly<CR>
|
||||
|
||||
"submenu orange
|
||||
9000amenu &ColorSchemes.&Colors\ (190).orange\ (1).*mars :colo mars<CR>
|
||||
|
||||
"submenu red
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).ChocolateLiquor :colo ChocolateLiquor<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).aiseered :colo aiseered<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).chocolateliquor :colo chocolateliquor<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).hhpink :colo hhpink<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).*navajo :colo navajo<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).peachpuff :colo peachpuff<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).tibet :colo tibet<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).tomatosoup :colo tomatosoup<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).red\ (9).xian :colo xian<CR>
|
||||
|
||||
"submenu unknown
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).brown :colo brown<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).bw :colo bw<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).c :colo c<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).calmar256-light :colo calmar256-light<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).chela_light :colo chela_light<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).coffee :colo coffee<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).colorscheme_template :colo colorscheme_template<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).default :colo default<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).desert256 :colo desert256<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).impact :colo impact<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).psql :colo psql<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).reloaded :colo reloaded<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).unknown\ (13).vc :colo vc<CR>
|
||||
|
||||
"submenu white
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).bog :colo bog<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).delek :colo delek<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).eclipse :colo eclipse<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).emacs :colo emacs<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).gobo :colo gobo<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).lingodirector :colo lingodirector<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).martin_krischik :colo martin_krischik<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).*moria :colo moria<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).print_bw :colo print_bw<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).*scite :colo scite<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).shine :colo shine<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).*sienna :colo sienna<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).taqua :colo taqua<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).tcsoft :colo tcsoft<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).tolerable :colo tolerable<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).vcbc :colo vcbc<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).white :colo white<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).white\ (18).zellner :colo zellner<CR>
|
||||
|
||||
"submenu yellow
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).PapayaWhip :colo PapayaWhip<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).buttercream :colo buttercream<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).hhorange :colo hhorange<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).olive :colo olive<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).papayawhip :colo papayawhip<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).professional :colo professional<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).robinhood :colo robinhood<CR>
|
||||
9000amenu &ColorSchemes.&Colors\ (190).yellow\ (8).sand :colo sand<CR>
|
||||
"Themes by name:
|
||||
|
||||
|
||||
"submenu A
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).adam :colo adam<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).adaryn :colo adaryn<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).adrian :colo adrian<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).*af :colo af<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).aiseered :colo aiseered<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).aqua :colo aqua<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).astronaut :colo astronaut<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).asu1dark :colo asu1dark<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).automation :colo automation<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).autumn :colo autumn<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).autumn2 :colo autumn2<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).A\ (12).autumnleaf :colo autumnleaf<CR>
|
||||
|
||||
"submenu B
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).*baycomb :colo baycomb<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).billw :colo billw<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).biogoo :colo biogoo<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).*black_angus :colo black_angus<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).blackbeauty :colo blackbeauty<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).blackdust :colo blackdust<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).blacksea :colo blacksea<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).blue :colo blue<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).bluegreen :colo bluegreen<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).blugrine :colo blugrine<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).bmichaelsen :colo bmichaelsen<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).bog :colo bog<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).borland :colo borland<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).breeze :colo breeze<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).brookstream :colo brookstream<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).brown :colo brown<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).buttercream :colo buttercream<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).B\ (18).bw :colo bw<CR>
|
||||
|
||||
"submenu C
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).ChocolateLiquor :colo ChocolateLiquor<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).c :colo c<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).calmar256-light :colo calmar256-light<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).camo :colo camo<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).candy :colo candy<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).candycode :colo candycode<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).caramel :colo caramel<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).chela_light :colo chela_light<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).chocolateliquor :colo chocolateliquor<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).cleanphp :colo cleanphp<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).coffee :colo coffee<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).colorer :colo colorer<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).colorscheme_template :colo colorscheme_template<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).C\ (14).*cool :colo cool<CR>
|
||||
|
||||
"submenu D
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dante :colo dante<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darkblack :colo darkblack<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darkblue :colo darkblue<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darkblue2 :colo darkblue2<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darkdot :colo darkdot<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darkocean :colo darkocean<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darkslategray :colo darkslategray<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).darktango :colo darktango<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).*dawn :colo dawn<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).default :colo default<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).delek :colo delek<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).denim :colo denim<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).desert :colo desert<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).desert256 :colo desert256<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).desertEx :colo desertEx<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).desertedocean :colo desertedocean<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dusk :colo dusk<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_blue :colo dw_blue<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_cyan :colo dw_cyan<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_green :colo dw_green<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_orange :colo dw_orange<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_purple :colo dw_purple<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_red :colo dw_red<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).D\ (24).dw_yellow :colo dw_yellow<CR>
|
||||
|
||||
"submenu E
|
||||
amenu &ColorSchemes.&Names\ (190).E\ (6).earth :colo earth<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).E\ (6).eclipse :colo eclipse<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).E\ (6).edo_sea :colo edo_sea<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).E\ (6).elflord :colo elflord<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).E\ (6).emacs :colo emacs<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).E\ (6).evening :colo evening<CR>
|
||||
|
||||
"submenu F
|
||||
amenu &ColorSchemes.&Names\ (190).F\ (5).fine_blue :colo fine_blue<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).F\ (5).fnaqevan :colo fnaqevan<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).F\ (5).fog :colo fog<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).F\ (5).freya :colo freya<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).F\ (5).fruit :colo fruit<CR>
|
||||
|
||||
"submenu G
|
||||
amenu &ColorSchemes.&Names\ (190).G\ (5).gobo :colo gobo<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).G\ (5).golden :colo golden<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).G\ (5).gor :colo gor<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).G\ (5).gothic :colo gothic<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).G\ (5).greyblue :colo greyblue<CR>
|
||||
|
||||
"submenu H
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).habiLight :colo habiLight<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhazure :colo hhazure<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdblue :colo hhdblue<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdcyan :colo hhdcyan<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdgray :colo hhdgray<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdgreen :colo hhdgreen<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdmagenta :colo hhdmagenta<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdred :colo hhdred<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhdyellow :colo hhdyellow<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhorange :colo hhorange<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhpink :colo hhpink<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhspring :colo hhspring<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhteal :colo hhteal<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).H\ (14).hhviolet :colo hhviolet<CR>
|
||||
|
||||
"submenu I
|
||||
amenu &ColorSchemes.&Names\ (190).I\ (4).ibmedit :colo ibmedit<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).I\ (4).impact :colo impact<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).I\ (4).*inkpot :colo inkpot<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).I\ (4).ironman :colo ironman<CR>
|
||||
|
||||
"submenu J
|
||||
amenu &ColorSchemes.&Names\ (190).J\ (2).jhdark :colo jhdark<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).J\ (2).jhlight :colo jhlight<CR>
|
||||
|
||||
"submenu K
|
||||
amenu &ColorSchemes.&Names\ (190).K\ (1).koehler :colo koehler<CR>
|
||||
|
||||
"submenu L
|
||||
amenu &ColorSchemes.&Names\ (190).L\ (4).less :colo less<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).L\ (4).lettuce :colo lettuce<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).L\ (4).lilac :colo lilac<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).L\ (4).lingodirector :colo lingodirector<CR>
|
||||
|
||||
"submenu M
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).manxome :colo manxome<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).marklar :colo marklar<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).*mars :colo mars<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).martin_krischik :colo martin_krischik<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).matrix :colo matrix<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).metacosm :colo metacosm<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).midnight :colo midnight<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).midnight2 :colo midnight2<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).mod_tcsoft :colo mod_tcsoft<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).*moria :colo moria<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).morning :colo morning<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).*motus :colo motus<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).M\ (13).murphy :colo murphy<CR>
|
||||
|
||||
"submenu N
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).*navajo :colo navajo<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).navajo-night :colo navajo-night<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).nedit :colo nedit<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).nedit2 :colo nedit2<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).neon :colo neon<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).neverness :colo neverness<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).night :colo night<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).nightshimmer :colo nightshimmer<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).nightwish :colo nightwish<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).northsky :colo northsky<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).N\ (11).nuvola :colo nuvola<CR>
|
||||
|
||||
"submenu O
|
||||
amenu &ColorSchemes.&Names\ (190).O\ (4).oceanblack :colo oceanblack<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).O\ (4).oceandeep :colo oceandeep<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).O\ (4).oceanlight :colo oceanlight<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).O\ (4).olive :colo olive<CR>
|
||||
|
||||
"submenu P
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).PapayaWhip :colo PapayaWhip<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).pablo :colo pablo<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).papayawhip :colo papayawhip<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).peachpuff :colo peachpuff<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).potts :colo potts<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).print_bw :colo print_bw<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).professional :colo professional<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).*ps_color :colo ps_color<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).psql :colo psql<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).putty :colo putty<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).pyte :colo pyte<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).P\ (12).python :colo python<CR>
|
||||
|
||||
"submenu R
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).rdark :colo rdark<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).redblack :colo redblack<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).relaxedgreen :colo relaxedgreen<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).reloaded :colo reloaded<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).revolutions :colo revolutions<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).robinhood :colo robinhood<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).R\ (7).ron :colo ron<CR>
|
||||
|
||||
"submenu S
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).sand :colo sand<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).*scite :colo scite<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).sea :colo sea<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).sean :colo sean<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).seashell :colo seashell<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).sf :colo sf<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).shine :colo shine<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).*sienna :colo sienna<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).simpleandfriendly :colo simpleandfriendly<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).slate :colo slate<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).S\ (11).softblue :colo softblue<CR>
|
||||
|
||||
"submenu T
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).*tabula :colo tabula<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).tango :colo tango<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).taqua :colo taqua<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).tcsoft :colo tcsoft<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).tibet :colo tibet<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).tolerable :colo tolerable<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).tomatosoup :colo tomatosoup<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).toothpik :colo toothpik<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).*torte :colo torte<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).transparent :colo transparent<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).T\ (11).turbo :colo turbo<CR>
|
||||
|
||||
"submenu U
|
||||
amenu &ColorSchemes.&Names\ (190).U\ (1).umber-green :colo umber-green<CR>
|
||||
|
||||
"submenu V
|
||||
amenu &ColorSchemes.&Names\ (190).V\ (4).vc :colo vc<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).V\ (4).vcbc :colo vcbc<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).V\ (4).vibrantink :colo vibrantink<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).V\ (4).*vividchalk :colo vividchalk<CR>
|
||||
|
||||
"submenu W
|
||||
amenu &ColorSchemes.&Names\ (190).W\ (3).white :colo white<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).W\ (3).whitedust :colo whitedust<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).W\ (3).wintersday :colo wintersday<CR>
|
||||
|
||||
"submenu X
|
||||
amenu &ColorSchemes.&Names\ (190).X\ (2).xemacs :colo xemacs<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).X\ (2).xian :colo xian<CR>
|
||||
|
||||
"submenu Z
|
||||
amenu &ColorSchemes.&Names\ (190).Z\ (2).zellner :colo zellner<CR>
|
||||
amenu &ColorSchemes.&Names\ (190).Z\ (2).*zenburn :colo zenburn<CR>
|
||||
|
||||
amenu &ColorSchemes.-Sep- :
|
||||
amenu &ColorSchemes.Reload\ Menu :ReloadColors<CR>
|
||||
amenu &ColorSchemes.Refresh\ Menu :RefreshColors<CR>
|
||||
|
||||
command! -nargs=0 ReloadColors call <SID>ReloadColors()
|
||||
command! -nargs=0 RefreshColors call <SID>RefreshColors()
|
||||
|
||||
if !exists("g:running_ReloadColors")
|
||||
function! <SID>ReloadColors()
|
||||
let g:running_ReloadColors = 1
|
||||
aunmenu &ColorSchemes
|
||||
execute 'source /home/marty/.vim/plugin/ColorSchemes.vim'
|
||||
unlet g:running_ReloadColors
|
||||
echomsg 'Done Reloading /home/marty/.vim/plugin/ColorSchemes.vim'
|
||||
endfunction
|
||||
endif
|
||||
if !exists("g:running_RefreshColors")
|
||||
function! <SID>RefreshColors()
|
||||
let g:running_RefreshColors = 1
|
||||
call WriteColorSchemeMenu()
|
||||
call <SID>ReloadColors()
|
||||
unlet g:running_RefreshColors
|
||||
echomsg 'Done Refreshing /home/marty/.vim/plugin/ColorSchemes.vim'
|
||||
endfunction
|
||||
endif
|
||||
73
vim/plugin/EasyMotion.vim
Executable file
73
vim/plugin/EasyMotion.vim
Executable file
@@ -0,0 +1,73 @@
|
||||
" EasyMotion - Vim motions on speed!
|
||||
"
|
||||
" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
|
||||
" Source repository: https://github.com/Lokaltog/vim-easymotion
|
||||
|
||||
" Script initialization {{{
|
||||
if exists('g:EasyMotion_loaded') || &compatible || version < 702
|
||||
finish
|
||||
endif
|
||||
|
||||
let g:EasyMotion_loaded = 1
|
||||
" }}}
|
||||
" Default configuration {{{
|
||||
" Default options {{{
|
||||
call EasyMotion#InitOptions({
|
||||
\ 'leader_key' : '<Leader><Leader>'
|
||||
\ , 'keys' : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
\ , 'do_shade' : 1
|
||||
\ , 'do_mapping' : 1
|
||||
\ , 'grouping' : 1
|
||||
\
|
||||
\ , 'hl_group_target' : 'EasyMotionTarget'
|
||||
\ , 'hl_group_shade' : 'EasyMotionShade'
|
||||
\ })
|
||||
" }}}
|
||||
" Default highlighting {{{
|
||||
let s:target_hl_defaults = {
|
||||
\ 'gui' : ['NONE', '#ff0000' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '196' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'red' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:shade_hl_defaults = {
|
||||
\ 'gui' : ['NONE', '#777777' , 'NONE']
|
||||
\ , 'cterm256': ['NONE', '242' , 'NONE']
|
||||
\ , 'cterm' : ['NONE', 'grey' , 'NONE']
|
||||
\ }
|
||||
|
||||
call EasyMotion#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
|
||||
call EasyMotion#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
|
||||
|
||||
" Reset highlighting after loading a new color scheme {{{
|
||||
augroup EasyMotionInitHL
|
||||
autocmd!
|
||||
|
||||
autocmd ColorScheme * call EasyMotion#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
|
||||
autocmd ColorScheme * call EasyMotion#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
|
||||
augroup end
|
||||
" }}}
|
||||
" }}}
|
||||
" Default key mapping {{{
|
||||
call EasyMotion#InitMappings({
|
||||
\ 'f' : { 'name': 'F' , 'dir': 0 }
|
||||
\ , 'F' : { 'name': 'F' , 'dir': 1 }
|
||||
\ , 't' : { 'name': 'T' , 'dir': 0 }
|
||||
\ , 'T' : { 'name': 'T' , 'dir': 1 }
|
||||
\ , 'w' : { 'name': 'WB' , 'dir': 0 }
|
||||
\ , 'W' : { 'name': 'WBW', 'dir': 0 }
|
||||
\ , 'b' : { 'name': 'WB' , 'dir': 1 }
|
||||
\ , 'B' : { 'name': 'WBW', 'dir': 1 }
|
||||
\ , 'e' : { 'name': 'E' , 'dir': 0 }
|
||||
\ , 'E' : { 'name': 'EW' , 'dir': 0 }
|
||||
\ , 'ge': { 'name': 'E' , 'dir': 1 }
|
||||
\ , 'gE': { 'name': 'EW' , 'dir': 1 }
|
||||
\ , 'j' : { 'name': 'JK' , 'dir': 0 }
|
||||
\ , 'k' : { 'name': 'JK' , 'dir': 1 }
|
||||
\ , 'n' : { 'name': 'Search' , 'dir': 0 }
|
||||
\ , 'N' : { 'name': 'Search' , 'dir': 1 }
|
||||
\ })
|
||||
" }}}
|
||||
" }}}
|
||||
|
||||
" vim: fdm=marker:noet:ts=4:sw=4:sts=4
|
||||
61
vim/plugin/FindInNERDTree.vim
Normal file
61
vim/plugin/FindInNERDTree.vim
Normal file
@@ -0,0 +1,61 @@
|
||||
" FindInNERDTree
|
||||
"
|
||||
" Description: Moves the cursor to the node in the NERDTree that
|
||||
" represents the current file. Will open directories
|
||||
" to find it.
|
||||
" Last Change: 11/9/09
|
||||
" Version: 1.0
|
||||
" Author: Doug McInnes <doug@dougmcinnes.com>
|
||||
" URL: http://github.com/dmcinnes/find_in_nerd_tree/tree
|
||||
"
|
||||
" A plugin for NERDTree
|
||||
" http://www.vim.org/scripts/script.php?script_id=1658
|
||||
|
||||
function! FindInNERDTree(...)
|
||||
if a:0
|
||||
let l:path = a:1
|
||||
else
|
||||
let l:nerdbuf = 0
|
||||
for item in tabpagebuflist()
|
||||
if bufname(item) =~ "^NERD_tree_"
|
||||
let l:nerdbuf = item
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:nerdbuf == bufnr('%')
|
||||
" already in the tree
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:path = g:NERDTreePath.New(bufname('%'))
|
||||
|
||||
if l:nerdbuf
|
||||
silent! exec bufwinnr(l:nerdbuf) . "wincmd w"
|
||||
else
|
||||
silent! exec "NERDTreeToggle"
|
||||
endif
|
||||
|
||||
call cursor(g:NERDTreeFileNode.GetRootLineNum(), 1)
|
||||
endif
|
||||
let l:root = g:NERDTreeDirNode.GetSelected()
|
||||
|
||||
if l:root.path.compareTo(l:path) == 0
|
||||
return l:root.findNode(l:path)
|
||||
elseif l:path.str() !~ '^' . l:root.path.str()
|
||||
echo "Not in the current NERD tree!"
|
||||
return 0
|
||||
else
|
||||
let l:node = FindInNERDTree(l:path.getParent())
|
||||
if !empty(l:node)
|
||||
call l:node.open()
|
||||
if a:0
|
||||
return l:node.findNode(l:path)
|
||||
else
|
||||
call NERDTreeRender()
|
||||
call g:NERDTreeFileNode.New(l:path).putCursorHere(1, 0)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
return {}
|
||||
endfunction
|
||||
675
vim/plugin/IndentAnything.vim
Normal file
675
vim/plugin/IndentAnything.vim
Normal file
@@ -0,0 +1,675 @@
|
||||
"
|
||||
" Copyright 2006 Tye Zdrojewski
|
||||
"
|
||||
" 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.
|
||||
"
|
||||
"
|
||||
"
|
||||
" Plugin:
|
||||
"
|
||||
" Indent Anything
|
||||
"
|
||||
" Version: 1.2.2
|
||||
"
|
||||
" Description:
|
||||
"
|
||||
" This is an indentation script that calculates the indent level based
|
||||
" on begin/end syntax pairs and line-continuation patterns. It allows one
|
||||
" to create an indent script without writing any code, taking it's
|
||||
" instruction from configurable values.
|
||||
"
|
||||
" Included with this script is Javascript indentation, an example that
|
||||
" explains the configurable values.
|
||||
"
|
||||
"
|
||||
" Installation:
|
||||
"
|
||||
" Place this file in your home directory under ~/.vim/indent/, or replace
|
||||
" the system indent/javascript.vim file to affect all users.
|
||||
"
|
||||
" Maintainer: Tye Z. <zdro@yahoo.com>
|
||||
"
|
||||
" Customization:
|
||||
"
|
||||
" The only thing that can really be customized at this point is whether or
|
||||
" not a line is echoed explaining the indentation result. To turn this on,
|
||||
" set the following variable like so:
|
||||
"
|
||||
" let b:indent_anything_echo = 1
|
||||
"
|
||||
"
|
||||
" History:
|
||||
"
|
||||
" 1.2 - made some functions script-local to prevent naming collisions
|
||||
" - fixed some broken indentation in the middle of a block comment,
|
||||
" which showed up in Javascript indentation.
|
||||
"
|
||||
" 1.2.2 - Fixed a bug causing the line after a single-line block comment to
|
||||
" always have an indent of '0' (i.e. the line after /* comment */).
|
||||
" - Added Apache 2 license
|
||||
"
|
||||
"
|
||||
|
||||
let s:supportedVimVersion = 700
|
||||
|
||||
if version < s:supportedVimVersion
|
||||
echoerr "IndentAnything only supported for Vim " . s:supportedVimVersion . " and up."
|
||||
finish
|
||||
endif
|
||||
|
||||
|
||||
"
|
||||
" Initialize everything needed by this script. Only set those values that are
|
||||
" not set already.
|
||||
"
|
||||
function! IndentAnythingInit()
|
||||
let b:IndentAnythingInitialized = 1
|
||||
" Start with a regular expression that will never match. Matching
|
||||
" will influence behavior, which the defaults should not do.
|
||||
let s:nonMatcher = '[x]\&[^x]'
|
||||
if !exists('b:commentRE')
|
||||
let b:commentRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:lineCommentRE')
|
||||
let b:lineCommentRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:blockCommentRE')
|
||||
let b:blockCommentRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:stringRE')
|
||||
let b:stringRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:singleQuoteStringRE')
|
||||
let b:singleQuoteStringRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:doubleQuoteStringRE')
|
||||
let b:doubleQuoteStringRE = s:nonMatcher
|
||||
endif
|
||||
|
||||
if !exists('b:blockCommentStartRE')
|
||||
let b:blockCommentStartRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:blockCommentMiddleRE')
|
||||
let b:blockCommentMiddleRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:blockCommentEndRE')
|
||||
let b:blockCommentEndRE = s:nonMatcher
|
||||
endif
|
||||
if !exists('b:blockCommentMiddleExtra')
|
||||
let b:blockCommentMiddleExtra = 0
|
||||
endif
|
||||
|
||||
if !exists('b:indentTrios')
|
||||
let b:indentTrios = []
|
||||
endif
|
||||
if !exists('b:lineContList')
|
||||
let b:lineContList = []
|
||||
endif
|
||||
|
||||
if !exists('b:contTraversesLineComments')
|
||||
let b:contTraversesLineComments = 1
|
||||
endif
|
||||
|
||||
if !exists('b:indent_anything_echo')
|
||||
let b:indent_anything_echo = 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! SynHere()
|
||||
return synIDattr(synID(line('.'), col('.'), 1), "name")
|
||||
endfunction
|
||||
"
|
||||
" Returns true if the cursor is currently inside a comment or a string
|
||||
"
|
||||
function! InCommentOrString()
|
||||
let syn = synIDattr(synID(line("."), col("."), 1), "name")
|
||||
if syn =~ b:commentRE || syn =~ b:stringRE
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
"
|
||||
" Returns true if the given line is a comment line (b:lineCommentRE)
|
||||
"
|
||||
function! IsLineComment(linenum)
|
||||
let cursor = getpos('.')
|
||||
exec a:linenum
|
||||
normal ^
|
||||
let l:iscomment = 0
|
||||
let l:syn = synIDattr(synID(line('.'), col('.'), 1), "name")
|
||||
if l:syn =~ b:lineCommentRE " b:commentRE || l:syn =~ b:stringRE
|
||||
let l:iscomment = 1
|
||||
endif
|
||||
call setpos('.', cursor)
|
||||
return l:iscomment
|
||||
endfunction
|
||||
|
||||
"
|
||||
" Returns true if the given line is a comment line (b:lineCommentRE)
|
||||
"
|
||||
function! IsComment(linenum)
|
||||
let cursor = getpos('.')
|
||||
exec a:linenum
|
||||
normal ^
|
||||
let l:iscomment = 0
|
||||
let l:syn = synIDattr(synID(line('.'), col('.'), 1), "name")
|
||||
if l:syn =~ b:commentRE " b:commentRE || l:syn =~ b:stringRE
|
||||
let l:iscomment = 1
|
||||
endif
|
||||
call setpos('.', cursor)
|
||||
return l:iscomment
|
||||
endfunction
|
||||
|
||||
"
|
||||
" Returns true if the given line is a comment line (b:lineCommentRE)
|
||||
"
|
||||
function! IsBlockComment(linenum)
|
||||
let cursor = getpos('.')
|
||||
exec a:linenum
|
||||
normal ^
|
||||
let l:iscomment = 0
|
||||
let l:syn = synIDattr(synID(line('.'), col('.'), 1), "name")
|
||||
if l:syn =~ b:blockCommentRE " b:commentRE || l:syn =~ b:stringRE
|
||||
let l:iscomment = 1
|
||||
endif
|
||||
call setpos('.', cursor)
|
||||
return l:iscomment
|
||||
endfunction
|
||||
|
||||
"
|
||||
" Get the first line at or on the given line that is not blank and is not a
|
||||
" comment line.
|
||||
"
|
||||
function! GetPrevNonBlankNonComment(begin)
|
||||
let cursor = getpos('.')
|
||||
|
||||
let l:prevbegin = a:begin
|
||||
while 1
|
||||
let l:lnum = prevnonblank(l:prevbegin)
|
||||
if l:lnum == 0
|
||||
return 0
|
||||
endif
|
||||
|
||||
"if IsLineComment(l:lnum)
|
||||
if IsComment(l:lnum)
|
||||
let l:prevbegin -= 1
|
||||
continue
|
||||
endif
|
||||
|
||||
break
|
||||
endwhile
|
||||
|
||||
" Restore original cursor location
|
||||
call setpos('.', cursor)
|
||||
return l:lnum
|
||||
endfunction
|
||||
|
||||
"
|
||||
" This does all the work. Does indentation for:
|
||||
"
|
||||
" - All pairs defined in b:indentTrios
|
||||
" - All line continuations in b:lineContList
|
||||
" - Block comments
|
||||
"
|
||||
function! IndentAnything()
|
||||
|
||||
if !exists('b:IndentAnythingInitialized')
|
||||
call IndentAnythingInit()
|
||||
endif
|
||||
|
||||
let adj = 0 " Adjustment
|
||||
|
||||
let g:lastindent = ""
|
||||
let b:hardindent = -1
|
||||
let currlnum = v:lnum
|
||||
let currlnum = line('.')
|
||||
let currline = getline(currlnum)
|
||||
let lastline = ''
|
||||
let prevline = ''
|
||||
|
||||
" Find non-blank lines above the current line.
|
||||
let lastlnum = prevnonblank(currlnum - 1)
|
||||
let prevlnum = prevnonblank(lastlnum - 1)
|
||||
if lastlnum != 0
|
||||
let lastline = getline(lastlnum)
|
||||
endif
|
||||
if prevlnum != 0
|
||||
let prevline = getline(prevlnum)
|
||||
endif
|
||||
if b:contTraversesLineComments
|
||||
let lastcodelnum = GetPrevNonBlankNonComment(currlnum - 1)
|
||||
let prevcodelnum = GetPrevNonBlankNonComment(lastcodelnum - 1)
|
||||
if lastcodelnum !=0
|
||||
let lastcodeline = getline(lastcodelnum)
|
||||
endif
|
||||
endif
|
||||
|
||||
" Start from the first char on the line. Vim doesn't seem to consistently
|
||||
" place the cursor there before calling the indent routines.
|
||||
call cursor(0, 1)
|
||||
call search('\S', 'W')
|
||||
|
||||
let l:cur = getpos('.')
|
||||
|
||||
"
|
||||
" Call indentation adjustment functions.
|
||||
"
|
||||
|
||||
"
|
||||
" Block comments
|
||||
"
|
||||
let l:BlockCommentAdj = 0
|
||||
let l:BlockCommentAdj += s:GetBlockCommentIndent(currlnum, lastlnum)
|
||||
let adj += l:BlockCommentAdj
|
||||
|
||||
"
|
||||
" Pairs
|
||||
"
|
||||
let b:lastclosed = { 'at' : 0 }
|
||||
let b:pairadj = 0
|
||||
if !l:BlockCommentAdj
|
||||
" If we're not in the middle of a block comment (because we haven't
|
||||
" made any adjustments for that), then process block indentation.
|
||||
for trio in b:indentTrios
|
||||
let b:pairadj += s:GetPairIndent(currline, lastline, lastlnum,
|
||||
\ trio[0], trio[1], trio[2])
|
||||
endfor
|
||||
endif
|
||||
let adj += b:pairadj
|
||||
|
||||
"
|
||||
" Line continuations
|
||||
"
|
||||
let contadj = 0
|
||||
let isBlockCommentStart = currline =~ '^\s*' . b:blockCommentStartRE
|
||||
let isBlockCommentMid = (IsBlockComment(currlnum) && !isBlockCommentStart)
|
||||
if !isBlockCommentMid
|
||||
" If the current line is not the middle of a block comment, then
|
||||
" process line continuations.
|
||||
for ContRule in b:lineContList
|
||||
if b:contTraversesLineComments "&& !isBlockCommentStart
|
||||
let contadj = s:GetContIndent(ContRule, currline, lastcodeline, lastcodelnum, prevcodelnum)
|
||||
else
|
||||
let contadj = s:GetContIndent(ContRule, currline, lastline, lastlnum, prevlnum)
|
||||
endif
|
||||
" This is for line continuation patterns, of which there can be only
|
||||
" one per line to indicate continuation
|
||||
if contadj
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
let adj += contadj
|
||||
endif
|
||||
|
||||
|
||||
"
|
||||
" Find the previous indent to which we will add the adjustment
|
||||
"
|
||||
let prevind = indent(lastlnum)
|
||||
|
||||
if l:BlockCommentAdj
|
||||
let g:lastindent .= " indent (prevblockcomment: " . prevind . " at " . lastcodelnum . ") "
|
||||
elseif contadj && b:contTraversesLineComments
|
||||
" If we have adjusted for line continuation, then use the indentation
|
||||
" for the previous code line
|
||||
let prevind = indent(lastcodelnum)
|
||||
let g:lastindent .= " indent (prevcode: " . prevind . " at " . lastcodelnum . ") "
|
||||
|
||||
elseif (isBlockCommentStart || !IsBlockComment(currlnum)) && IsBlockComment(lastlnum)
|
||||
" If this is the first line after a block comment, then add the
|
||||
" adjustment to the line where the block comment started.
|
||||
let prevind = s:GetPostBlockCommentIndent(lastlnum)
|
||||
let g:lastindent .= " indent (prevblock: " . prevind . " at " . lastlnum . ") "
|
||||
|
||||
elseif exists("b:defaultIndentExpr")
|
||||
let g:lastindent .= " using defaultIndentExpr (" . b:defaultIndentExpr . ") "
|
||||
exec "let prevind = " . b:defaultIndentExpr
|
||||
else
|
||||
" Default to adjusting the previous line's indent.
|
||||
let g:lastindent .= " indent (prev: " . prevind . " at " . lastlnum . ") "
|
||||
endif
|
||||
|
||||
" Just in case there is no previous indent.
|
||||
let prevind = (prevind == -1 ? 0 : prevind)
|
||||
|
||||
if b:indent_anything_echo
|
||||
echom g:lastindent
|
||||
endif
|
||||
|
||||
call setpos('.', l:cur)
|
||||
|
||||
return adj + prevind
|
||||
|
||||
endfunction
|
||||
|
||||
"
|
||||
" Get the adjustment for the second line of a block comment. The second line
|
||||
" will be aligned under the start of the block, even if it is not at the
|
||||
" beginning of the line. Extra adjustment (b:blockCommentMiddleExtra) will
|
||||
" be added.
|
||||
"
|
||||
function! s:GetBlockCommentIndent(CurrLNum, LastLNum)
|
||||
let l:cursor = getpos('.')
|
||||
let l:adj = 0
|
||||
if a:LastLNum == searchpair(b:blockCommentStartRE, '', b:blockCommentEndRE, 'bWr')
|
||||
\ && a:LastLNum > 0
|
||||
let l:adj = col('.') + b:blockCommentMiddleExtra
|
||||
normal ^
|
||||
let l:adj -= col('.')
|
||||
endif
|
||||
call setpos('.', l:cursor)
|
||||
return l:adj
|
||||
endfunction
|
||||
|
||||
function! s:GetPostBlockCommentIndent(LastLNum)
|
||||
|
||||
let l:cursor = getpos('.')
|
||||
let l:ind = 0
|
||||
let l:comment_start_lnum = 0;
|
||||
|
||||
" Find beginning of block comment containing the start of line LastLNum
|
||||
exec a:LastLNum
|
||||
normal ^
|
||||
let l:comment_start_lnum = searchpair(
|
||||
\ b:blockCommentStartRE, b:blockCommentMiddleRE, b:blockCommentEndRE, 'bWr')
|
||||
|
||||
" Assume that the LastLNum is a block comment. If the comment both
|
||||
" started and stopped on LastLNum, then searchpair will return 0. In that
|
||||
" case, we just want to return the indent of LastLNum itself.
|
||||
if 0 == l:comment_start_lnum
|
||||
let l:comment_start_lnum = a:LastLNum
|
||||
endif
|
||||
|
||||
let l:ind = indent(l:comment_start_lnum)
|
||||
|
||||
if 1 || l:ind != 0 && b:indent_anything_echo
|
||||
let g:lastindent = g:lastindent .
|
||||
\ "GetPostBlockCommentIndent: " . l:ind
|
||||
endif
|
||||
|
||||
call setpos('.', l:cursor)
|
||||
|
||||
"return l:ind
|
||||
return l:ind > 0 ? l:ind : 0
|
||||
|
||||
endfunction
|
||||
|
||||
"
|
||||
" Get additional indentation based on blocks of code, as defined by the Head
|
||||
" and Tail patterns.
|
||||
"
|
||||
function! s:GetPairIndent(CurrLine, LastLine, LastLNum, Head, Mid, Tail)
|
||||
|
||||
let levels = 0
|
||||
let adj = 0
|
||||
let origcol = col(".")
|
||||
let origline = line(".")
|
||||
|
||||
|
||||
"
|
||||
" How many levels were started on the last line? Search backwards for
|
||||
" pair starters until we're not on the last nonblank. If the last line
|
||||
" doesn't contain the pair-starter, then don't bother with searchpair();
|
||||
" it's a performance bottleneck because (I think) it will always search
|
||||
" all the way back until it finds a match or can't search any more.
|
||||
"
|
||||
"
|
||||
if a:LastLine =~ a:Head
|
||||
while 1
|
||||
"
|
||||
" Include the limit of the search to be the last line. BIG
|
||||
" performance booster! That also means we only have to see *if*
|
||||
" there was a match, and not worry about where it is.
|
||||
"
|
||||
"let pairstart = searchpair(a:Head, a:Mid, a:Tail, 'Wb')
|
||||
"if pairstart == 0 || pairstart != a:LastLNum
|
||||
let pairstart = searchpair(a:Head, a:Mid, a:Tail, 'Wb', '', a:LastLNum)
|
||||
if pairstart == 0 "|| pairstart != a:LastLNum
|
||||
break
|
||||
endif
|
||||
let syn = synIDattr(synID(line("."), col("."), 1), "name")
|
||||
" Also continue on the off chance that we find the match on the
|
||||
" current line. This shouldn't happen, but the pattern might
|
||||
" start with whitespace.
|
||||
if syn =~ b:commentRE || syn =~ b:stringRE || pairstart == origline
|
||||
continue
|
||||
endif
|
||||
let levels += 1
|
||||
endwhile
|
||||
endif
|
||||
|
||||
" If we aren't within a level that was started on the last line, then
|
||||
" check how many levels were closed on the last line.
|
||||
"
|
||||
if levels == 0
|
||||
|
||||
" Move to the beginning of the last line
|
||||
call cursor(a:LastLNum,0)
|
||||
normal ^
|
||||
|
||||
" If the line starts with an open, The close shouldn't be counted as
|
||||
" such, because we're looking for closes that didn't start on this
|
||||
" line.
|
||||
if a:LastLine =~ '^\s*' . a:Head ||
|
||||
\ (a:Mid != '' && a:LastLine =~ '^\s*' . a:Mid)
|
||||
let levels = 1
|
||||
endif
|
||||
|
||||
"
|
||||
" Count the closes on the last line (i.e. LastLNum), stopping once
|
||||
" we've hit comments. If the line doesn't even contain the end of the
|
||||
" pair, don't bother with searchpair() (same aforementioned
|
||||
" rationale).
|
||||
"
|
||||
if a:LastLine =~ a:Tail
|
||||
while 1
|
||||
"
|
||||
" Include the limit of the search to be the last line. BIG
|
||||
" performance booster! That also means we only have to see
|
||||
" *if* there was a match, and not worry about where it is.
|
||||
"
|
||||
"let pairend = searchpair(a:Head, a:Mid, a:Tail, 'W')
|
||||
"if pairend == 0 || a:LastLNum != pairend
|
||||
"let pairend = searchpair(a:Head, a:Mid, a:Tail, 'W', '', a:LastLNum)
|
||||
let pairend = searchpair(a:Head, a:Mid, a:Tail, 'W',
|
||||
\'InCommentOrString()', a:LastLNum)
|
||||
if pairend == 0 "|| a:LastLNum != pairend
|
||||
|
||||
" STARTS with a:Tail, since we already know the line
|
||||
" matches it.
|
||||
if b:lastclosed.at < col('.') && (
|
||||
\ a:LastLine =~ '^\s*' . a:Tail
|
||||
\ || (a:Mid != '' && a:LastLine =~ '^\s*' . a:Mid) )
|
||||
let b:lastclosed = {
|
||||
\ 'at' : col('.'),
|
||||
\ 'head' : a:Head,
|
||||
\ 'mid' : a:Mid,
|
||||
\ 'tail' : a:Tail }
|
||||
endif
|
||||
|
||||
|
||||
break
|
||||
endif
|
||||
" This might not be needed with the expr included in the
|
||||
" search call.
|
||||
"let syn = synIDattr(synID(line("."), col("."), 1), "name")
|
||||
"if syn =~ b:commentRE || syn =~ b:stringRE || syn == ''
|
||||
" break
|
||||
"endif
|
||||
let levels -= 1
|
||||
|
||||
" Track the last close to try to match pairs that start on
|
||||
" line continuations
|
||||
if b:lastclosed.at < col('.')
|
||||
let b:lastclosed = {
|
||||
\ 'at' : col('.'),
|
||||
\ 'head' : a:Head,
|
||||
\ 'mid' : a:Mid,
|
||||
\ 'tail' : a:Tail }
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
endif
|
||||
|
||||
" This is redundant, as per above
|
||||
" If the current line starts with a close, count it. It won't effect the
|
||||
" indentation of the next line because it is the first thing on the line
|
||||
" and won't be counted as a "close on the last line".
|
||||
if a:CurrLine =~ '^\s*' . a:Tail
|
||||
\ || (a:Mid != '' && a:CurrLine =~ '^\s*' . a:Mid)
|
||||
let levels -= 1
|
||||
endif
|
||||
|
||||
" Restore original cursor location
|
||||
call cursor(origline, origcol)
|
||||
|
||||
let adj = &sw*levels
|
||||
if adj != 0 && b:indent_anything_echo
|
||||
let g:lastindent = g:lastindent .
|
||||
\ "GetPairIndent(" . a:Head . "/" . b:lastclosed.at . "):" . adj . " "
|
||||
endif
|
||||
|
||||
return adj
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:GetContIndent(Rule, CurrLine, LastLine, LastLNum, PrevLNum)
|
||||
|
||||
let adj = 0
|
||||
let origcol = col(".")
|
||||
let origline = line(".")
|
||||
let lastcont = 0
|
||||
let prevcont = 0
|
||||
|
||||
let l:lastlnum = a:LastLNum
|
||||
let l:prevlnum = a:PrevLNum
|
||||
|
||||
let l:preblockstart = -1
|
||||
|
||||
" Get the last matching line number. If the match occurs w/in a comment
|
||||
" or string, then it's a non-match.
|
||||
"
|
||||
"let lastmatchlnum = search(a:Rule.pattern, 'Wb', a:PrevLNum)
|
||||
let lastmatchlnum = search(a:Rule.pattern, 'Wb', a:LastLNum)
|
||||
let syn = synIDattr(synID(line("."), col("."), 1), "name")
|
||||
|
||||
"if syn =~ b:commentRE || syn =~ b:stringRE
|
||||
if syn =~ b:commentRE || syn =~ b:stringRE || b:lastclosed.at > 0
|
||||
let lastmatchlnum = 0
|
||||
endif
|
||||
|
||||
" Should be able to just search to the line....
|
||||
" " Figure out the last and previous continuation status
|
||||
" if lastmatchlnum && lastmatchlnum == a:LastLNum
|
||||
" let lastcont = 1
|
||||
" endif
|
||||
if lastmatchlnum == a:LastLNum
|
||||
let lastcont = 1
|
||||
endif
|
||||
|
||||
" start checking at the start of the block that ended on the prev line
|
||||
if b:lastclosed.at > 0
|
||||
call cursor(a:LastLNum, b:lastclosed.at)
|
||||
" TODO: add 'skip' to skip comments
|
||||
let l:preblockstart = searchpair(b:lastclosed.head, b:lastclosed.mid, b:lastclosed.tail, 'bW')
|
||||
let g:lastindent .= ' postpair ("' . b:lastclosed.head . '"): '
|
||||
\ . l:preblockstart . '/' . col('.') . ' '
|
||||
|
||||
if b:contTraversesLineComments
|
||||
let l:prevlnum = GetPrevNonBlankNonComment(line('.') - 1)
|
||||
else
|
||||
let l:prevlnum = prevnonblank(line('.') - 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
" Get the previous matching line number. If the match occurs w/in a
|
||||
" comment or string, then it's a non-match. Use the adjusted, local
|
||||
" prevlnum as the limit of the search, since we don't care about matches
|
||||
" beyond that.
|
||||
let prevmatchlnum = search(a:Rule.pattern, 'Wb', l:prevlnum)
|
||||
|
||||
|
||||
let syn = synIDattr(synID(line("."), col("."), 1), "name")
|
||||
" Handle:
|
||||
" if ()
|
||||
" if () {
|
||||
" this_line; // should not be reduced
|
||||
"if syn =~ b:commentRE || syn =~ b:stringRE
|
||||
if syn =~ b:commentRE || syn =~ b:stringRE
|
||||
let prevmatchlnum = 0
|
||||
endif
|
||||
|
||||
" Should be able to just search to the line....
|
||||
" if ( lastmatchlnum && lastmatchlnum == a:PrevLNum )
|
||||
" \ || ( prevmatchlnum && prevmatchlnum == l:prevlnum )
|
||||
" let prevcont = 1
|
||||
" endif
|
||||
"
|
||||
" If there is a previous line, it is a continued line, and we haven't
|
||||
" already done a positive adjustment for a pair/block, then reduce.
|
||||
" Don't undo a positive adjustment for a pair because the previous line
|
||||
" was a continued line. That will happen after the end of the block.
|
||||
"if prevmatchlnum == l:prevlnum && b:pairadj <= 0
|
||||
if l:prevlnum && prevmatchlnum == l:prevlnum && b:pairadj <= 0
|
||||
let prevcont = 1
|
||||
endif
|
||||
|
||||
"echom "lastcont: " . lastcont .
|
||||
" \ ", prevcont: " . prevcont .
|
||||
" \ ", lastmatchlnum: " . lastmatchlnum .
|
||||
" \ ", prevmatchlnum: " . prevmatchlnum .
|
||||
" \ ", lastlnum: " . a:LastLNum .
|
||||
" \ ", PrevLNum: " . a:PrevLNum
|
||||
let firstcont = (lastcont && !prevcont)
|
||||
let firstcont = ((lastcont && !prevcont) || (lastcont && b:pairadj))
|
||||
|
||||
" If we are adjusting the current line for a pair, then don't count this
|
||||
" line as a post-continuation line. The post continuation line will be
|
||||
" after the close of said pair.
|
||||
let postcont = (!lastcont && prevcont)
|
||||
"let postcont = (!lastcont && prevcont && !b:pairadj )
|
||||
|
||||
let g:lastindent .= 'lastcont (' . lastcont . '), prevcont (' . prevcont . ') '
|
||||
|
||||
|
||||
"if firstcont && a:CurrLine !~ '^\s*{'
|
||||
if firstcont
|
||||
if has_key(a:Rule, 'ignore') && a:CurrLine =~ a:Rule.ignore
|
||||
let g:lastindent .= "(ignoring '" . a:Rule.ignore . "') "
|
||||
else
|
||||
let adj = adj + &sw
|
||||
endif
|
||||
"elseif postcont && a:LastLine !~ '^\s*{' "&& !b:pairadj
|
||||
elseif postcont
|
||||
if has_key(a:Rule, 'ignore') && a:LastLine =~ a:Rule.ignore
|
||||
let g:lastindent .= "(ignoring '" . a:Rule.ignore . "') "
|
||||
else
|
||||
let adj = adj - &sw
|
||||
endif
|
||||
endif
|
||||
|
||||
call cursor(origline, origcol)
|
||||
|
||||
if adj != 0 && b:indent_anything_echo
|
||||
let g:lastindent = g:lastindent .
|
||||
\ "GetContIndent('" . a:Rule.pattern . "'):" . adj . " "
|
||||
endif
|
||||
return adj
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
|
||||
352
vim/plugin/IndexedSearch.vim
Normal file
352
vim/plugin/IndexedSearch.vim
Normal file
@@ -0,0 +1,352 @@
|
||||
let g:indexed_search_colors=0
|
||||
" File: IndexedSearch.vim
|
||||
" Author: Yakov Lerner <iler.ml@gmail.com>
|
||||
" URL: http://www.vim.org/scripts/script.php?script_id=1682
|
||||
" Last change: 2006-11-21
|
||||
"
|
||||
" This script redefines 6 search commands (/,?,n,N,*,#). At each search,
|
||||
" it shows at which match number you are, and the total number
|
||||
" of matches, like this: "At Nth match out of M". This is printed
|
||||
" at the bottom line at every n,N,/,?,*,# search command, automatically.
|
||||
"
|
||||
" To try out the plugin, source it and play with N,n,*,#,/,? commands.
|
||||
" At the bottom line, you'll see wha it shows. There are no new
|
||||
" commands and no new behavior to learn. Just additional info
|
||||
" on the bottom line, whenever you perform search.
|
||||
"
|
||||
" Works on vim6 and vim7. On very large files, won't cause slowdown
|
||||
" because it checks the file size.
|
||||
" Don't use if you're sensitive to one of its components :-)
|
||||
"
|
||||
" I am posting this plugin because I find it useful.
|
||||
" -----------------------------------------------------
|
||||
" Checking Where You Are with respect to Search Matches
|
||||
" .....................................................
|
||||
" You can press \\ or \/ (that's backslach then slash),
|
||||
" or :ShowSearchIndex to show at which match index you are,
|
||||
" without moving cursor.
|
||||
"
|
||||
" If cursor is exactly on the match, the message is:
|
||||
" At Nth match of M
|
||||
" If cursor is between matches, following messages are displayed:
|
||||
" Betwen matches 189-190 of 300
|
||||
" Before first match, of 300
|
||||
" After last match, of 300
|
||||
" ------------------------------------------------------
|
||||
" To disable colors for messages, set 'let g:indexed_search_colors=0'.
|
||||
" ------------------------------------------------------
|
||||
" Performance. Plugin bypasses match counting when it would take
|
||||
" too much time (too many matches, too large file). You can
|
||||
" tune performance limits below, after comment "Performance tuning limits"
|
||||
" ------------------------------------------------------
|
||||
" In case of bugs and wishes, please email: iler.ml at gmail.com
|
||||
" ------------------------------------------------------
|
||||
|
||||
|
||||
" before 061119, it worked only vim7 not on vim6 (we use winrestview())
|
||||
" after 061119, works only on vim6 (we avoid winrestview on vim6)
|
||||
|
||||
|
||||
"if version < 700 | finish | endif " we need vim7 at least. Won't work for vim6
|
||||
|
||||
"if &cp | echo "warning: IndexedSearch.vim need nocp" | finish | endif " we need &nocp mode
|
||||
|
||||
if exists("g:indexed_search_plugin") | finish | endif
|
||||
let g:indexed_search_plugin = 1
|
||||
|
||||
if !exists('g:indexed_search_colors')
|
||||
let g:indexed_search_colors=1 " 1-use colors for messages, 0-no colors
|
||||
endif
|
||||
|
||||
if !exists('g:indexed_search_shortmess')
|
||||
let g:indexed_search_shortmess=0 " 1-longer messages; 0(or undefined)-longer messages.
|
||||
endif
|
||||
|
||||
|
||||
" ------------------ "Performance tuning limits" -------------------
|
||||
if !exists('g:search_index_max')
|
||||
let g:search_index_max=30000 " max filesize(in lines) up to what
|
||||
" ShowCurrentSearchIndex() works
|
||||
endif
|
||||
if !exists("g:search_index_maxhit")
|
||||
let g:search_index_maxhit=1000
|
||||
endif
|
||||
" -------------- End of Performance tuning limits ------------------
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
command! ShowSearchIndex :call s:ShowCurrentSearchIndex(1,'')
|
||||
|
||||
|
||||
" before 061114 we had op invocation inside the function but this
|
||||
" did not properly keep @/ and direction (func.return restores @/ and direction)
|
||||
" after 061114 invoking op inside the function does not work because
|
||||
" @/ and direction is restored at return from function
|
||||
" We must have op invocation at the toplevel of mapping even though this
|
||||
" makes mappings longer.
|
||||
nnoremap <silent>n :let v:errmsg=''<cr>:silent! norm! n<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
|
||||
nnoremap <silent>N :let v:errmsg=''<cr>:silent! norm! N<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
|
||||
nnoremap <silent>* :let v:errmsg=''<cr>:silent! norm! *<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
|
||||
nnoremap <silent># :let v:errmsg=''<cr>:silent! norm! #<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
|
||||
|
||||
|
||||
nnoremap <silent>\/ :call <SID>ShowCurrentSearchIndex(1,'')<cr>
|
||||
nnoremap <silent>\\ :call <SID>ShowCurrentSearchIndex(1,'')<cr>
|
||||
nnoremap <silent>g/ :call <SID>ShowCurrentSearchIndex(1,'')<cr>
|
||||
|
||||
|
||||
" before 061120, I had cmapping for <cr> which was very intrusive. Didn't work
|
||||
" with supertab iInde<c-x><c-p>(resulted in something like recursive <c-r>=
|
||||
" after 061120, I remap [/?] instead of remapping <cr>. Works in vim6, too
|
||||
|
||||
nnoremap / :call <SID>DelaySearchIndex(0,'')<cr>/
|
||||
nnoremap ? :call <SID>DelaySearchIndex(0,'')<cr>?
|
||||
|
||||
|
||||
let s:ScheduledEcho = ''
|
||||
let s:DelaySearchIndex = 0
|
||||
let g:IndSearchUT = &ut
|
||||
|
||||
|
||||
func! s:ScheduleEcho(msg,highlight)
|
||||
|
||||
"if &ut > 50 | let g:IndSearchUT=&ut | let &ut=50 | endif
|
||||
"if &ut > 100 | let g:IndSearchUT=&ut | let &ut=100 | endif
|
||||
if &ut > 200 | let g:IndSearchUT=&ut | let &ut=200 | endif
|
||||
" 061116 &ut is sometimes not restored and drops permanently to 50. But how ?
|
||||
|
||||
let s:ScheduledEcho = a:msg
|
||||
let use_colors = !exists('g:indexed_search_colors') || g:indexed_search_colors
|
||||
let s:ScheduledHighlight = ( use_colors ? a:highlight : "None" )
|
||||
|
||||
aug IndSearchEcho
|
||||
|
||||
au CursorHold *
|
||||
\ exe 'set ut='.g:IndSearchUT |
|
||||
\ if s:DelaySearchIndex | call s:ShowCurrentSearchIndex(0,'') |
|
||||
\ let s:ScheduledEcho = s:Msg | let s:ScheduledHighlight = s:Highlight |
|
||||
\ let s:DelaySearchIndex = 0 | endif |
|
||||
\ if s:ScheduledEcho != ""
|
||||
\ | exe "echohl ".s:ScheduledHighlight | echo s:ScheduledEcho | echohl None
|
||||
\ | let s:ScheduledEcho='' |
|
||||
\ endif |
|
||||
\ aug IndSearchEcho | exe 'au!' | aug END | aug! IndSearchEcho
|
||||
" how about moving contents of this au into function
|
||||
|
||||
aug END
|
||||
endfun " s:ScheduleEcho
|
||||
|
||||
|
||||
func! s:DelaySearchIndex(force,cmd)
|
||||
let s:DelaySearchIndex = 1
|
||||
call s:ScheduleEcho('','')
|
||||
endfunc
|
||||
|
||||
|
||||
func! s:ShowCurrentSearchIndex(force, cmd)
|
||||
" NB: function saves and restores @/ and direction
|
||||
" this used to cause me many troubles
|
||||
|
||||
call s:CountCurrentSearchIndex(a:force, a:cmd) " -> s:Msg, s:Highlight
|
||||
|
||||
if s:Msg != ""
|
||||
call s:ScheduleEcho(s:Msg, s:Highlight )
|
||||
endif
|
||||
endfun
|
||||
|
||||
|
||||
function! s:MilliSince( start )
|
||||
" usage: let s = reltime() | sleep 100m | let milli = MilliSince(s)
|
||||
let x = reltimestr( reltime( a:start ) )
|
||||
" there can be leading spaces in x
|
||||
let sec = substitute(x, '^ *\([0-9]\+\)', '\1', '')
|
||||
let frac = substitute(x, '\.\([0-9]\+\)', '\1', '') . "000"
|
||||
let milli = strpart( frac, 0, 3)
|
||||
return sec * 1000 + milli
|
||||
endfun
|
||||
|
||||
|
||||
func! s:CountCurrentSearchIndex(force, cmd)
|
||||
" sets globals -> s:Msg , s:Highlight
|
||||
let s:Msg = '' | let s:Highlight = ''
|
||||
let builtin_errmsg = ""
|
||||
|
||||
" echo "" | " make sure old msg is erased
|
||||
if a:cmd == '!'
|
||||
" if cmd is '!', we do not execute any command but report
|
||||
" last errmsg
|
||||
if v:errmsg != ""
|
||||
echohl Error
|
||||
echomsg v:errmsg
|
||||
echohl None
|
||||
endif
|
||||
elseif a:cmd != ''
|
||||
let v:errmsg = ""
|
||||
|
||||
silent! exe "norm! ".a:cmd
|
||||
|
||||
if v:errmsg != ""
|
||||
echohl Error
|
||||
echomsg v:errmsg
|
||||
echohl None
|
||||
endif
|
||||
|
||||
if line('$') >= g:search_index_max
|
||||
" for large files, preserve original error messages and add nothing
|
||||
return ""
|
||||
endif
|
||||
else
|
||||
endif
|
||||
|
||||
if !a:force && line('$') >= g:search_index_max
|
||||
let too_slow=1
|
||||
" when too_slow, we'll want to switch the work over to CursorHold
|
||||
return ""
|
||||
endif
|
||||
if @/ == '' | return "" | endif
|
||||
if version >= 700
|
||||
let save = winsaveview()
|
||||
endif
|
||||
let line = line('.')
|
||||
let vcol = virtcol('.')
|
||||
norm gg0
|
||||
let num = 0 " total # of matches in the buffer
|
||||
let exact = -1
|
||||
let after = 0
|
||||
let too_slow = 0 " if too_slow, we'll want to switch the work over to CursorHold
|
||||
let s_opt = 'Wc'
|
||||
while search(@/, s_opt) && ( num <= g:search_index_maxhit || a:force)
|
||||
let num = num + 1
|
||||
if line('.') == line && virtcol('.') == vcol
|
||||
let exact = num
|
||||
elseif line('.') < line || (line('.') == line && virtcol('.') < vcol)
|
||||
let after = num
|
||||
endif
|
||||
let s_opt = 'W'
|
||||
endwh
|
||||
if version >= 700
|
||||
call winrestview(save)
|
||||
else
|
||||
exe line
|
||||
exe "norm! ".vcol."|"
|
||||
endif
|
||||
if !a:force && num > g:search_index_maxhit
|
||||
if exact >= 0
|
||||
let too_slow=1 " if too_slow, we'll want to switch the work over to CursorHold
|
||||
let num=">".(num-1)
|
||||
else
|
||||
let s:Msg = ">".(num-1)." matches"
|
||||
if v:errmsg != ""
|
||||
let s:Msg = "" " avoid overwriting builtin errmsg with our ">1000 matches"
|
||||
endif
|
||||
return ""
|
||||
endif
|
||||
endif
|
||||
|
||||
let s:Highlight = "Directory"
|
||||
if num == "0"
|
||||
let s:Highlight = "Error"
|
||||
let prefix = "No matches "
|
||||
elseif exact == 1 && num==1
|
||||
" s:Highlight remains default
|
||||
"let prefix = "At single match"
|
||||
let prefix = "Single match"
|
||||
elseif exact == 1
|
||||
let s:Highlight = "Search"
|
||||
"let prefix = "At 1st match, # 1 of " . num
|
||||
"let prefix = "First match, # 1 of " . num
|
||||
let prefix = "First of " . num . " matches "
|
||||
elseif exact == num
|
||||
let s:Highlight = "LineNr"
|
||||
"let prefix = "Last match, # ".num." of " . num
|
||||
"let prefix = "At last match, # ".num." of " . num
|
||||
let prefix = "Last of " . num . " matches "
|
||||
elseif exact >= 0
|
||||
"let prefix = "At # ".exact." match of " . num
|
||||
"let prefix = "Match # ".exact." of " . num
|
||||
"let prefix = "# ".exact." match of " . num
|
||||
if exists('g:indexed_search_shortmess') && g:indexed_search_shortmess
|
||||
let prefix = exact." of " . num . " matches "
|
||||
else
|
||||
let prefix = "Match ".exact." of " . num
|
||||
endif
|
||||
elseif after == 0
|
||||
let s:Highlight = "MoreMsg"
|
||||
let prefix = "Before first match, of ".num." matches "
|
||||
if num == 1
|
||||
let prefix = "Before single match"
|
||||
endif
|
||||
elseif after == num
|
||||
let s:Highlight = "WarningMsg"
|
||||
let prefix = "After last match of ".num." matches "
|
||||
if num == 1
|
||||
let prefix = "After single match"
|
||||
endif
|
||||
else
|
||||
let prefix = "Between matches ".after."-".(after+1)." of ".num
|
||||
endif
|
||||
let s:Msg = prefix . " /".@/ . "/"
|
||||
return ""
|
||||
endfunc
|
||||
|
||||
|
||||
" Messages Summary
|
||||
"
|
||||
" Short Message Long Message
|
||||
" -------------------------------------------
|
||||
" %d of %d matches Match %d of %d
|
||||
" Last of %d matches <-same
|
||||
" First of %d matches <-same
|
||||
" No matchess <-same
|
||||
" -------------------------------------------
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
|
||||
" Last changes
|
||||
" 2006-10-20 added limitation by # of matches
|
||||
" 061021 lerner fixed problem with cmap <enter> that screwed maps
|
||||
" 061021 colors added
|
||||
" 061022 fixed g/ when too many matches
|
||||
" 061106 got message to work with check for largefile right
|
||||
" 061110 addition of DelayedEcho(ScheduledEcho) fixes and simplifies things
|
||||
" 061110 mapping for nN*# greately simplifified by switching to ScheduledEcho
|
||||
" 061110 fixed problem with i<c-o>/pat<cr> and c/PATTERN<CR> Markus Braun
|
||||
" 061110 fixed bug in / and ?, Counting moved to Delayd
|
||||
" 061110 fixed bug extra line+enter prompt in [/?] by addinf redraw
|
||||
" 061110 fixed overwriting builtin errmsg with ">1000 matches"
|
||||
" 061111 fixed bug with gg & 'set nosol' (gg->gg0)
|
||||
" 061113 fixed mysterious eschewing of @/ wfte *,#
|
||||
" 061113 fixed counting of match at the very beginning of file
|
||||
" 061113 added msgs "Before single match", "After single match"
|
||||
" 061113 fixed bug with &ut not always restored. This could happen if
|
||||
" ScheduleEcho() was called twice in a row.
|
||||
" 061114 fixed problem with **#n. Direction of the last n is incorrect (must be backward
|
||||
" but was incorrectly forward)
|
||||
" 061114 fixed disappearrance of "Hit BOTTOM" native msg when file<max and numhits>max
|
||||
" 061116 changed hlgroup os "At last match" from DiffChange to LineNr. Looks more natural.
|
||||
" 061120 shortened text messages.
|
||||
" 061120 made to work on vim6
|
||||
" 061120 bugfix for vim6 (virtcol() not col())
|
||||
" 061120 another bug with virtcol() vs col()
|
||||
" 061120 fixed [/?] on vim6 (vim6 doesn't have getcmdtype())
|
||||
" 061121 fixed mapping in <cr> with supertab.vim. Switched to [/?] mapping, removed <cr> mapping.
|
||||
" also shortened code considerably, made vim6 and vim7 work same way, removed need
|
||||
" for getcmdtype().
|
||||
" 061121 fixed handling of g:indexed_search_colors (Markus Braun)
|
||||
|
||||
|
||||
" Wishlist
|
||||
" - using high-precision timer of vim7, count number of millisec
|
||||
" to run the counters, and base auto-disabling on time it takes.
|
||||
" very complex regexes can be terribly slow even of files like 'man bash'
|
||||
" which is mere 5k lines long. Also when there are >10k matches in the file
|
||||
" set limit to 200 millisec
|
||||
" - implement CursorHold bg counting to which too_slow will resort
|
||||
" - even on large files, we can show "At last match", "After last match"
|
||||
" - define global vars for all highlights, with defaults
|
||||
" hh
|
||||
" hh
|
||||
" hh
|
||||
" hh
|
||||
3132
vim/plugin/NERD_commenter.vim
Normal file
3132
vim/plugin/NERD_commenter.vim
Normal file
File diff suppressed because it is too large
Load Diff
4123
vim/plugin/NERD_tree.vim
Executable file
4123
vim/plugin/NERD_tree.vim
Executable file
File diff suppressed because it is too large
Load Diff
205
vim/plugin/autotag.vim
Normal file
205
vim/plugin/autotag.vim
Normal file
@@ -0,0 +1,205 @@
|
||||
" Increment the number below for a dynamic #include guard
|
||||
let s:autotag_vim_version=1
|
||||
|
||||
if exists("g:autotag_vim_version_sourced")
|
||||
if s:autotag_vim_version == g:autotag_vim_version_sourced
|
||||
finish
|
||||
endif
|
||||
endif
|
||||
|
||||
let g:autotag_vim_version_sourced=s:autotag_vim_version
|
||||
|
||||
" This file supplies automatic tag regeneration when saving files
|
||||
" There's a problem with ctags when run with -a (append)
|
||||
" ctags doesn't remove entries for the supplied source file that no longer exist
|
||||
" so this script (implemented in python) finds a tags file for the file vim has
|
||||
" just saved, removes all entries for that source file and *then* runs ctags -a
|
||||
|
||||
if has("python")
|
||||
|
||||
python << EEOOFF
|
||||
import os
|
||||
import string
|
||||
import os.path
|
||||
import fileinput
|
||||
import sys
|
||||
import vim
|
||||
import time
|
||||
|
||||
# Just in case the ViM build you're using doesn't have subprocess
|
||||
if sys.version < '2.4':
|
||||
def do_cmd(cmd, cwd):
|
||||
old_cwd=os.getcwd()
|
||||
os.chdir(cwd)
|
||||
(ch_in, ch_out) = os.popen2(cmd)
|
||||
for line in ch_out:
|
||||
pass
|
||||
os.chdir(old_cwd)
|
||||
|
||||
import traceback
|
||||
def format_exc():
|
||||
return ''.join(traceback.format_exception(*list(sys.exc_info())))
|
||||
|
||||
else:
|
||||
import subprocess
|
||||
def do_cmd(cmd, cwd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=None, stderr=None, cwd=cwd)
|
||||
|
||||
from traceback import format_exc
|
||||
|
||||
def echo(str):
|
||||
str=str.replace('\\', '\\\\')
|
||||
str=str.replace('"', "'")
|
||||
vim.command("redraw | echo \"%s\"" % str)
|
||||
|
||||
def diag(verbosity, threshold, msg, args = None):
|
||||
if msg and args:
|
||||
msg = msg % args
|
||||
if verbosity >= threshold:
|
||||
echo(msg)
|
||||
|
||||
def goodTag(line, excluded):
|
||||
if line[0] == '!':
|
||||
return True
|
||||
else:
|
||||
f = string.split(line, '\t')
|
||||
if len(f) > 3 and not f[1] in excluded:
|
||||
return True
|
||||
return False
|
||||
|
||||
class AutoTag:
|
||||
__maxTagsFileSize = 1024 * 1024 * 7
|
||||
__threshold = 1
|
||||
|
||||
def __init__(self):
|
||||
self.tags = {}
|
||||
self.excludesuffix = [ "." + s for s in vim.eval("g:autotagExcludeSuffixes").split(".") ]
|
||||
verbosity = long(vim.eval("g:autotagVerbosityLevel"))
|
||||
self.verbosity = verbosity if verbosity > 0 else 0
|
||||
self.sep_used_by_ctags = '/'
|
||||
self.ctags_cmd = vim.eval("g:autotagCtagsCmd")
|
||||
self.tags_file = str(vim.eval("g:autotagTagsFile"))
|
||||
self.count = 0
|
||||
|
||||
def findTagFile(self, source):
|
||||
self.__diag('source = "%s"' % (source, ))
|
||||
( drive, file ) = os.path.splitdrive(source)
|
||||
while file:
|
||||
file = os.path.dirname(file)
|
||||
#self.__diag('drive = "%s", file = "%s"' % (drive, file))
|
||||
tagsFile = os.path.join(drive, file, self.tags_file)
|
||||
#self.__diag('tagsFile "%s"' % tagsFile)
|
||||
if os.path.isfile(tagsFile):
|
||||
st = os.stat(tagsFile)
|
||||
if st:
|
||||
size = getattr(st, 'st_size', None)
|
||||
if size is None:
|
||||
self.__diag("Could not stat tags file %s" % tagsFile)
|
||||
return None
|
||||
if AutoTag.__maxTagsFileSize and size > AutoTag.__maxTagsFileSize:
|
||||
self.__diag("Ignoring too big tags file %s" % tagsFile)
|
||||
return None
|
||||
return tagsFile
|
||||
elif not file or file == os.sep or file == "//" or file == "\\\\":
|
||||
#self.__diag('bail (file = "%s")' % (file, ))
|
||||
return None
|
||||
return None
|
||||
|
||||
def addSource(self, source):
|
||||
if not source:
|
||||
self.__diag('No source')
|
||||
return
|
||||
if os.path.basename(source) == self.tags_file:
|
||||
self.__diag("Ignoring tags file %s" % (self.tags_file,))
|
||||
return
|
||||
(base, suff) = os.path.splitext(source)
|
||||
if suff in self.excludesuffix:
|
||||
self.__diag("Ignoring excluded suffix %s for file %s" % (source, suff))
|
||||
return
|
||||
tagsFile = self.findTagFile(source)
|
||||
if tagsFile:
|
||||
relativeSource = source[len(os.path.dirname(tagsFile)):]
|
||||
if relativeSource[0] == os.sep:
|
||||
relativeSource = relativeSource[1:]
|
||||
if os.sep != self.sep_used_by_ctags:
|
||||
relativeSource = string.replace(relativeSource, os.sep, self.sep_used_by_ctags)
|
||||
if self.tags.has_key(tagsFile):
|
||||
self.tags[tagsFile].append(relativeSource)
|
||||
else:
|
||||
self.tags[tagsFile] = [ relativeSource ]
|
||||
|
||||
def stripTags(self, tagsFile, sources):
|
||||
self.__diag("Stripping tags for %s from tags file %s", (",".join(sources), tagsFile))
|
||||
backup = ".SAFE"
|
||||
input = fileinput.FileInput(files=tagsFile, inplace=True, backup=backup)
|
||||
try:
|
||||
for l in input:
|
||||
l = l.strip()
|
||||
if goodTag(l, sources):
|
||||
print l
|
||||
finally:
|
||||
input.close()
|
||||
try:
|
||||
os.unlink(tagsFile + backup)
|
||||
except StandardError:
|
||||
pass
|
||||
|
||||
def updateTagsFile(self, tagsFile, sources):
|
||||
tagsDir = os.path.dirname(tagsFile)
|
||||
self.stripTags(tagsFile, sources)
|
||||
if self.tags_file:
|
||||
cmd = "%s -f %s -a " % (self.ctags_cmd, self.tags_file)
|
||||
else:
|
||||
cmd = "%s -a " % (self.ctags_cmd,)
|
||||
for source in sources:
|
||||
if os.path.isfile(os.path.join(tagsDir, source)):
|
||||
cmd += " '%s'" % source
|
||||
self.__diag("%s: %s", (tagsDir, cmd))
|
||||
do_cmd(cmd, tagsDir)
|
||||
|
||||
def rebuildTagFiles(self):
|
||||
for (tagsFile, sources) in self.tags.items():
|
||||
self.updateTagsFile(tagsFile, sources)
|
||||
|
||||
def __diag(self, msg, args = None):
|
||||
diag(self.verbosity, AutoTag.__threshold, msg, args)
|
||||
EEOOFF
|
||||
|
||||
function! AutoTag()
|
||||
python << EEOOFF
|
||||
try:
|
||||
if long(vim.eval("g:autotagDisabled")) == 0:
|
||||
at = AutoTag()
|
||||
at.addSource(vim.eval("expand(\"%:p\")"))
|
||||
at.rebuildTagFiles()
|
||||
except:
|
||||
diag(1, -1, format_exc())
|
||||
EEOOFF
|
||||
if exists(":TlistUpdate")
|
||||
TlistUpdate
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if !exists("g:autotagDisabled")
|
||||
let g:autotagDisabled=0
|
||||
endif
|
||||
if !exists("g:autotagVerbosityLevel")
|
||||
let g:autotagVerbosityLevel=0
|
||||
endif
|
||||
if !exists("g:autotagExcludeSuffixes")
|
||||
let g:autotagExcludeSuffixes="tml.xml.text.txt"
|
||||
endif
|
||||
if !exists("g:autotagCtagsCmd")
|
||||
let g:autotagCtagsCmd="ctags"
|
||||
endif
|
||||
if !exists("g:autotagTagsFile")
|
||||
let g:autotagTagsFile="tags"
|
||||
endif
|
||||
augroup autotag
|
||||
au!
|
||||
autocmd BufWritePost,FileWritePost * call AutoTag ()
|
||||
augroup END
|
||||
|
||||
endif " has("python")
|
||||
|
||||
" vim:shiftwidth=3:ts=3
|
||||
1140
vim/plugin/bufexplorer.vim
Normal file
1140
vim/plugin/bufexplorer.vim
Normal file
File diff suppressed because it is too large
Load Diff
449
vim/plugin/camelcasemotion.vim
Normal file
449
vim/plugin/camelcasemotion.vim
Normal file
@@ -0,0 +1,449 @@
|
||||
" camelcasemotion.vim: Mappings for motion through CamelCaseWords and
|
||||
" underscore_notation.
|
||||
"
|
||||
" DESCRIPTION: {{{1
|
||||
" VIM provides many built-in motions, e.g. to move to the next word, or
|
||||
" end of the current word. Most programming languages use either CamelCase
|
||||
" ("anIdentifier") or underscore_notation ("an_identifier") naming
|
||||
" conventions for identifiers. The best way to navigate inside those
|
||||
" identifiers using VIM built-in motions is the '[count]f{char}' motion, i.e.
|
||||
" 'f<uppercase char>' or 'f_', respectively. But we can make this easier:
|
||||
"
|
||||
" This script defines motions ',w', ',b' and ',e' (similar to 'w', 'b', 'e'),
|
||||
" which do not move word-wise (forward/backward), but Camel-wise; i.e. to word
|
||||
" boundaries and uppercase letters. The motions also work on underscore
|
||||
" notation, where words are delimited by underscore ('_') characters.
|
||||
" From here on, both CamelCase and underscore_notation entities are referred
|
||||
" to as "words" (in double quotes). Just like with the regular motions, a
|
||||
" [count] can be prepended to move over multiple "words" at once.
|
||||
" Outside of "words" (e.g. in non-keyword characters like // or ;), the new
|
||||
" motions move just like the regular motions.
|
||||
"
|
||||
" VIM provides a built-in text object called 'inner word' ('iw'), which works
|
||||
" in operator-pending and visual mode. Analog to that, this script defines
|
||||
" inner "word" motions 'i,w', 'i,b' and 'i,e', which select the "word" (or
|
||||
" multiple "words" if a [count] is given) where the cursor is located.
|
||||
"
|
||||
" USAGE:
|
||||
" Use the new motions ',w', ',b' and ',e' in normal mode, operator-pending
|
||||
" mode (cp. :help operator), and visual mode. For example, type 'bc,w' to
|
||||
" change 'Camel' in 'CamelCase' to something else.
|
||||
"
|
||||
" EXAMPLE: motions
|
||||
" Given the following CamelCase identifiers in a source code fragment:
|
||||
" set Script31337PathAndNameWithoutExtension11=%~dpn0
|
||||
" set Script31337PathANDNameWITHOUTExtension11=%~dpn0
|
||||
" and the corresponding identifiers in underscore_notation:
|
||||
" set script_31337_path_and_name_without_extension_11=%~dpn0
|
||||
" set SCRIPT_31337_PATH_AND_NAME_WITHOUT_EXTENSION_11=%~dpn0
|
||||
"
|
||||
" ,w moves to ([x] is cursor position): [s]et, [s]cript, [3]1337, [p]ath,
|
||||
" [a]nd, [n]ame, [w]ithout, [e]xtension, [1]1, [d]pn0, dpn[0], [s]et
|
||||
" ,b moves to: [d]pn0, [1]1, [e]xtension, [w]ithout, ...
|
||||
" ,e moves to: se[t], scrip[t], 3133[7], pat[h], an[d], nam[e], withou[t],
|
||||
" extensio[n], 1[1], dpn[0]
|
||||
"
|
||||
" EXAMPLE: inner motions
|
||||
" Given the following identifier, with the cursor positioned at [x]:
|
||||
" script_31337_path_and_na[m]e_without_extension_11
|
||||
"
|
||||
" v3i,w selects script_31337_path_and_[name_without_extension_]11
|
||||
" v3i,b selects script_31337_[path_and_name]_without_extension_11
|
||||
" v3i,e selects script_31337_path_and_[name_without_extension]_11
|
||||
" Instead of visual mode, you can also use c3i,w to change, d3i,w to delete,
|
||||
" gU3i,w to upper-case, and so on.
|
||||
"
|
||||
" INSTALLATION: {{{1
|
||||
" Put the script into your user or system VIM plugin directory (e.g.
|
||||
" ~/.vim/plugin).
|
||||
"
|
||||
" DEPENDENCIES:
|
||||
" - Requires VIM 7.0 or higher.
|
||||
"
|
||||
" CONFIGURATION:
|
||||
" If you want to use different mappings, map your keys to the
|
||||
" <Plug>CamelCaseMotion_? mapping targets _before_ sourcing this script
|
||||
" (e.g. in your .vimrc).
|
||||
"
|
||||
" Example: Replace the default 'w', 'b' and 'e' mappings instead of defining
|
||||
" additional mappings ',w', ',b' and ',e':
|
||||
" map <silent> w <Plug>CamelCaseMotion_w
|
||||
" map <silent> b <Plug>CamelCaseMotion_b
|
||||
" map <silent> e <Plug>CamelCaseMotion_e
|
||||
"
|
||||
" Example: Replace default 'iw' text-object and define 'ib' and 'ie' motions:
|
||||
" omap <silent> iw <Plug>CamelCaseMotion_iw
|
||||
" vmap <silent> iw <Plug>CamelCaseMotion_iw
|
||||
" omap <silent> ib <Plug>CamelCaseMotion_ib
|
||||
" vmap <silent> ib <Plug>CamelCaseMotion_ib
|
||||
" omap <silent> ie <Plug>CamelCaseMotion_ie
|
||||
" vmap <silent> ie <Plug>CamelCaseMotion_ie
|
||||
"
|
||||
" LIMITATIONS:
|
||||
"
|
||||
" ASSUMPTIONS:
|
||||
"
|
||||
" KNOWN PROBLEMS:
|
||||
" - A degenerate CamelCaseWord containing '\U\u\d' (e.g. "MaP1Roblem")
|
||||
" confuses the operator-pending and visual mode ,e mapping if 'selection' is
|
||||
" not set to "exclusive". It'll skip "P" and select "P1" in one step. As a
|
||||
" workaround, use ',w' instead of ',e'; those two mappings have the same
|
||||
" effect inside CamelCaseWords, anyway.
|
||||
" - The operator-pending and visual mode ,e mapping doesn't work properly when
|
||||
" it reaches the end of the buffer; the final character of the moved-over
|
||||
" "word" remains. As a workaround, use the default 'e' motion instead of
|
||||
" ',e'.
|
||||
" - When the VIM setting 'selection' is not set to "exclusive", a
|
||||
" forward-backward combination in visual mode (e.g. 'v,w,b') selects one
|
||||
" additional character to the left, instead of only the character where the
|
||||
" motion started. Likewise, extension of the visual selection from the front
|
||||
" end is off by one additional character.
|
||||
"
|
||||
" TODO:
|
||||
"
|
||||
" Copyright: (C) 2007-2008 by Ingo Karkat
|
||||
" The VIM LICENSE applies to this script; see ':help copyright'.
|
||||
"
|
||||
" Source: Based on vimtip #1016 by Anthony Van Ham.
|
||||
" Maintainer: Ingo Karkat <ingo@karkat.de>
|
||||
" REVISION DATE REMARKS {{{1
|
||||
" 1.40.017 19-May-2008 BF: Now using :normal! to be independent from
|
||||
" any user mappings. Thanks to Neil Walker for the
|
||||
" patch.
|
||||
" 1.40.016 28-Apr-2008 BF: Wrong forward motion stop at the second
|
||||
" digit if a word starts with multiple numbers
|
||||
" (e.g. 1234.56789). Thanks to Wasim Ahmed for
|
||||
" reporting this.
|
||||
" 1.40.015 24-Apr-2008 ENH: Added inner "word" text objects 'i,w' etc.
|
||||
" that work analoguous to the built-in 'iw' text
|
||||
" object. Thanks to David Kotchan for this
|
||||
" suggestion.
|
||||
" 1.30.014 20-Apr-2008 The motions now also stop at non-keyword
|
||||
" boundaries, just like the regular motions. This
|
||||
" has no effect inside a CamelCaseWord or inside
|
||||
" underscore_notation, but it makes the motions
|
||||
" behave like the regular motions (which is
|
||||
" important if you replace the default motions).
|
||||
" Thanks to Mun Johl for reporting this.
|
||||
" Now using non-capturing parentheses \%() in the
|
||||
" patterns.
|
||||
" 1.30.013 09-Apr-2008 Refactored away s:VisualCamelCaseMotion().
|
||||
" Allowing users to use mappings different than
|
||||
" ,w ,b ,e by defining <Plug>CamelCaseMotion_?
|
||||
" target mappings. This can even be used to
|
||||
" replace the default 'w', 'b' and 'e' mappings,
|
||||
" as suggested by Mun Johl.
|
||||
" Mappings are now created in a generic function.
|
||||
" Now requires VIM 7.0 or higher.
|
||||
" 1.20.012 02-Jun-2007 BF: Corrected motions through mixed
|
||||
" CamelCase_and_UnderScore words by re-ordering
|
||||
" and narrowing the search patterns.
|
||||
" 1.20.011 02-Jun-2007 Thanks again to Joseph Barker for discussing the
|
||||
" complicated visual mode mapping on the vim-dev
|
||||
" mailing list and coming up with a great
|
||||
" simplification:
|
||||
" Removed s:CheckForChangesToTheSelectionSetting().
|
||||
" Introduced s:VisualCamelCaseMotion(), which
|
||||
" handles the differences depending on the
|
||||
" 'selection' setting.
|
||||
" Visual mode mappings now directly map to the
|
||||
" s:VisualCamelCaseMotion() function; no mark is
|
||||
" clobbered, the complex mapping with the inline
|
||||
" expression has been retired.
|
||||
" 1.20.010 29-May-2007 BF: The operator-pending and visual mode ,e
|
||||
" mapping doesn't work properly when it reaches
|
||||
" the end of line; the final character of the
|
||||
" moved-over "word" remains. Fixed this problem
|
||||
" unless the "word" is at the very end of the
|
||||
" buffer.
|
||||
" ENH: The visual mode motions now also (mostly)
|
||||
" work with the (default) setting
|
||||
" 'set selection=inclusive', instead of selecting
|
||||
" one character too much.
|
||||
" ENH: All mappings will check for changes to the
|
||||
" 'selection' setting and remap the visual mode
|
||||
" mappings via function
|
||||
" s:SetupVisualModeMappings(). We cannot rely on
|
||||
" the setting while sourcing camelcasemotion.vim
|
||||
" because the mswin.vim script may be sourced
|
||||
" afterwards, and its 'behave mswin' changes
|
||||
" 'selection'.
|
||||
" Refactored the arguments of function
|
||||
" s:CamelCaseMotion(...).
|
||||
" 1.10.009 28-May-2007 BF: Degenerate CamelCaseWords that consist of
|
||||
" only a single uppercase letter (e.g. "P" in
|
||||
" "MapPRoblem") are skipped by all motions. Thanks
|
||||
" to Joseph Barker for reporting this.
|
||||
" BF: In CamelCaseWords that consist of uppercase
|
||||
" letters followed by decimals (e.g.
|
||||
" "MyUPPER123Problem", the uppercase "word" is
|
||||
" skipped by all motions.
|
||||
" 1.10.008 28-May-2007 Incorporated major improvements and
|
||||
" simplifications done by Joseph Barker:
|
||||
" Operator-pending and visual mode motions now
|
||||
" accept [count] of more than 9.
|
||||
" Visual selections can now be extended from
|
||||
" either end.
|
||||
" Instead of misusing the :[range], the special
|
||||
" variable v:count1 is used. Custom commands are
|
||||
" not needed anymore.
|
||||
" Operator-pending and visual mode mappings are
|
||||
" now generic: There's only a single mapping for
|
||||
" ,w that can be repeated, rather than having a
|
||||
" separate mapping for 1,w 2,w 3,w ...
|
||||
" 1.00.007 22-May-2007 Added documentation for publication.
|
||||
" 006 20-May-2007 BF: visual mode [1,2,3],e on pure CamelCase
|
||||
" mistakenly marks [2,4,6] words. If the cursor is
|
||||
" on a uppercase letter, the search pattern
|
||||
" '\u\l\+' doesn't match at the cursor position,
|
||||
" so another match won. Changed search pattern
|
||||
" from '\l\+',
|
||||
" 005 16-May-2007 Added support for underscore notation.
|
||||
" Added support for "forward to end of word"
|
||||
" (',e') motion.
|
||||
" 004 16-May-2007 Improved search pattern so that
|
||||
" UppercaseWORDSInBetween and digits are handled,
|
||||
" too.
|
||||
" 003 15-May-2007 Changed mappings from <Leader>w to ,w;
|
||||
" other \w mappings interfere here, because it's
|
||||
" irritating when the cursor jump doesn't happen
|
||||
" immediately, because VIM waits whether the
|
||||
" mapping is complete. ,w is faster to type that
|
||||
" \w (and, because of the left-right touch,
|
||||
" preferred over gw).
|
||||
" Added visual mode mappings.
|
||||
" 0.02 15-Feb-2006 BF: missing <SID> for omaps.
|
||||
" 0.01 11-Oct-2005 file creation
|
||||
|
||||
" Avoid installing twice or when in compatible mode
|
||||
if exists("loaded_camelcasemotion") || (v:version < 700)
|
||||
finish
|
||||
endif
|
||||
let loaded_camelcasemotion = 1
|
||||
" }}}1
|
||||
|
||||
"- functions ------------------------------------------------------------------"
|
||||
function! s:CamelCaseMove( direction, count, mode ) " {{{1
|
||||
" Note: There is no inversion of the regular expression character class
|
||||
" 'keyword character' (\k). We need an inversion "non-keyword" defined as
|
||||
" "any non-whitespace character that is not a keyword character (e.g.
|
||||
" [!@#$%^&*()]. This can be specified via a non-whitespace character in
|
||||
" whose place no keyword character matches (\k\@!\S).
|
||||
|
||||
"echo "count is " . a:count
|
||||
let l:i = 0
|
||||
while l:i < a:count
|
||||
if a:direction == 'e'
|
||||
" "Forward to end" motion.
|
||||
"call search( '\>\|\(\a\|\d\)\+\ze_', 'We' )
|
||||
" end of ...
|
||||
" number | ACRONYM followed by CamelCase or number | CamelCase | underscore_notation | non-keyword | word
|
||||
call search( '\d\+\|\u\+\ze\%(\u\l\|\d\)\|\u\l\+\|\%(\a\|\d\)\+\ze_\|\%(\k\@!\S\)\+\|\%(_\@!\k\)\+\>', 'We' )
|
||||
" Note: word must be defined as '\k\>'; '\>' on its own somehow
|
||||
" dominates over the previous branch. Plus, \k must exclude the
|
||||
" underscore, or a trailing one will be incorrectly moved over:
|
||||
" '\%(_\@!\k\)'.
|
||||
if a:mode == 'o'
|
||||
" Note: Special additional treatment for operator-pending mode
|
||||
" "forward to end" motion.
|
||||
" The difference between normal mode, operator-pending and visual
|
||||
" mode is that in the latter two, the motion must go _past_ the
|
||||
" final "word" character, so that all characters of the "word" are
|
||||
" selected. This is done by appending a 'l' motion after the
|
||||
" search for the next "word".
|
||||
"
|
||||
" In operator-pending mode, the 'l' motion only works properly
|
||||
" at the end of the line (i.e. when the moved-over "word" is at
|
||||
" the end of the line) when the 'l' motion is allowed to move
|
||||
" over to the next line. Thus, the 'l' motion is added
|
||||
" temporarily to the global 'whichwrap' setting.
|
||||
" Without this, the motion would leave out the last character in
|
||||
" the line. I've also experimented with temporarily setting
|
||||
" "set virtualedit=onemore" , but that didn't work.
|
||||
let l:save_ww = &whichwrap
|
||||
set whichwrap+=l
|
||||
normal! l
|
||||
let &whichwrap = l:save_ww
|
||||
endif
|
||||
else
|
||||
" Forward (a:direction == '') and backward (a:direction == 'b')
|
||||
" motion.
|
||||
|
||||
let l:direction = (a:direction == 'w' ? '' : a:direction)
|
||||
|
||||
" CamelCase: Jump to beginning of either (start of word, Word, WORD,
|
||||
" 123).
|
||||
" Underscore_notation: Jump to the beginning of an underscore-separated
|
||||
" word or number.
|
||||
"call search( '\<\|\u', 'W' . l:direction )
|
||||
"call search( '\<\|\u\(\l\+\|\u\+\ze\u\)\|\d\+', 'W' . l:direction )
|
||||
"call search( '\<\|\u\(\l\+\|\u\+\ze\u\)\|\d\+\|_\zs\(\a\|\d\)\+', 'W' . l:direction )
|
||||
" beginning of ...
|
||||
" word | empty line | non-keyword after whitespaces | non-whitespace after word | number | ACRONYM followed by CamelCase or number | CamelCase | underscore followed by ACRONYM, Camel, lowercase or number
|
||||
call search( '\<\D\|^$\|\%(^\|\s\)\+\zs\k\@!\S\|\>\S\|\d\+\|\u\+\ze\%(\u\l\|\d\)\|\u\l\+\|_\zs\%(\u\+\|\u\l\+\|\l\+\|\d\+\)', 'W' . l:direction )
|
||||
" Note: word must be defined as '\<\D' to avoid that a word like
|
||||
" 1234Test is moved over as [1][2]34[T]est instead of [1]234[T]est
|
||||
" because \< matches with zero width, and \d\+ will then start
|
||||
" matching '234'. To fix that, we make \d\+ be solely responsible
|
||||
" for numbers by taken this away from \< via \<\D. (An alternative
|
||||
" would be to replace \d\+ with \D\%#\zs\d\+, but that one is more
|
||||
" complex.) All other branches are not affected, because they match
|
||||
" multiple characters and not the same character multiple times.
|
||||
endif
|
||||
let l:i = l:i + 1
|
||||
endwhile
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
function! s:CamelCaseMotion( direction, count, mode ) " {{{1
|
||||
"*******************************************************************************
|
||||
"* PURPOSE:
|
||||
" Perform the motion over CamelCaseWords or underscore_notation.
|
||||
"* ASSUMPTIONS / PRECONDITIONS:
|
||||
" none
|
||||
"* EFFECTS / POSTCONDITIONS:
|
||||
" Move cursor / change selection.
|
||||
"* INPUTS:
|
||||
" a:direction one of 'w', 'b', 'e'
|
||||
" a:count number of "words" to move over
|
||||
" a:mode one of 'n', 'o', 'v', 'iv' (latter one is a special visual mode
|
||||
" when inside the inner "word" text objects.
|
||||
"* RETURN VALUES:
|
||||
" none
|
||||
"*******************************************************************************
|
||||
" Visual mode needs special preparations and postprocessing;
|
||||
" normal and operator-pending mode breeze through to s:CamelCaseMove().
|
||||
|
||||
if a:mode == 'v'
|
||||
" Visual mode was left when calling this function. Reselecting the current
|
||||
" selection returns to visual mode and allows to call search() and issue
|
||||
" normal mode motions while staying in visual mode.
|
||||
normal! gv
|
||||
endif
|
||||
if a:mode == 'v' || a:mode == 'iv'
|
||||
|
||||
" Note_1a:
|
||||
if &selection != 'exclusive' && a:direction == 'w'
|
||||
normal! l
|
||||
endif
|
||||
endif
|
||||
|
||||
call s:CamelCaseMove( a:direction, a:count, a:mode )
|
||||
|
||||
if a:mode == 'v' || a:mode == 'iv'
|
||||
" Note: 'selection' setting.
|
||||
if &selection == 'exclusive' && a:direction == 'e'
|
||||
" When set to 'exclusive', the "forward to end" motion (',e') does not
|
||||
" include the last character of the moved-over "word". To include that, an
|
||||
" additional 'l' motion is appended to the motion; similar to the
|
||||
" special treatment in operator-pending mode.
|
||||
normal! l
|
||||
elseif &selection != 'exclusive' && a:direction != 'e'
|
||||
" Note_1b:
|
||||
" The forward and backward motions move to the beginning of the next "word".
|
||||
" When 'selection' is set to 'inclusive' or 'old', this is one character too far.
|
||||
" The appended 'h' motion undoes this. Because of this backward step,
|
||||
" though, the forward motion finds the current "word" again, and would
|
||||
" be stuck on the current "word". An 'l' motion before the CamelCase
|
||||
" motion (see Note_1a) fixes that.
|
||||
normal! h
|
||||
end
|
||||
endif
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
function! s:CamelCaseInnerMotion( direction, count ) " {{{1
|
||||
" If the cursor is positioned on the first character of a CamelWord, the
|
||||
" backward motion would move to the previous word, which would result in a
|
||||
" wrong selection. To fix this, first move the cursor to the right, so that
|
||||
" the backward motion definitely will cover the current "word" under the
|
||||
" cursor.
|
||||
normal! l
|
||||
|
||||
" Move "word" backwards, enter visual mode, then move "word" forward. This
|
||||
" selects the inner "word" in visual mode; the operator-pending mode takes
|
||||
" this selection as the area covered by the motion.
|
||||
if a:direction == 'b'
|
||||
" Do not do the selection backwards, because the backwards "word" motion
|
||||
" in visual mode + selection=inclusive has an off-by-one error.
|
||||
call s:CamelCaseMotion( 'b', a:count, 'n' )
|
||||
normal! v
|
||||
" We decree that 'b' is the opposite of 'e', not 'w'. This makes more
|
||||
" sense at the end of a line and for underscore_notation.
|
||||
call s:CamelCaseMotion( 'e', a:count, 'iv' )
|
||||
else
|
||||
call s:CamelCaseMotion( 'b', 1, 'n' )
|
||||
normal! v
|
||||
call s:CamelCaseMotion( a:direction, a:count, 'iv' )
|
||||
endif
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
"- mappings -------------------------------------------------------------------
|
||||
" The count is passed into the function through the special variable 'v:count1',
|
||||
" which is easier than misusing the :[range] that :call supports.
|
||||
" <C-U> is used to delete the unused range.
|
||||
" Another option would be to use a custom 'command! -count=1', but that doesn't
|
||||
" work with the normal mode mapping: When a count is typed before the mapping,
|
||||
" the ':' will convert a count of 3 into ':.,+2MyCommand', but ':3MyCommand'
|
||||
" would be required to use -count and <count>.
|
||||
"
|
||||
" We do not provide the fourth "backward to end" motion (,E), because it is
|
||||
" seldomly used.
|
||||
|
||||
function! s:CreateMotionMappings() "{{{1
|
||||
" Create mappings according to this template:
|
||||
" (* stands for the mode [nov], ? for the underlying motion [wbe].)
|
||||
"
|
||||
" *noremap <script> <Plug>CamelCaseMotion_? :<C-U>call <SID>CamelCaseMotion('?',v:count1,'*')<CR>
|
||||
" if ! hasmapto('<Plug>CamelCaseMotion_?', '*')
|
||||
" *map <silent> ,? <Plug>CamelCaseMotion_?
|
||||
" endif
|
||||
|
||||
for l:mode in ['n', 'o', 'v']
|
||||
for l:motion in ['w', 'b', 'e']
|
||||
let l:targetMapping = '<Plug>CamelCaseMotion_' . l:motion
|
||||
execute l:mode . 'noremap <script> ' . l:targetMapping . ' :<C-U>call <SID>CamelCaseMotion(''' . l:motion . ''',v:count1,''' . l:mode . ''')<CR>'
|
||||
if ! hasmapto(l:targetMapping, l:mode)
|
||||
execute l:mode . 'map <silent> ,' . l:motion . ' ' . l:targetMapping
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
" To create a text motion, a mapping for operator-pending mode needs to be
|
||||
" defined. This mapping should move the cursor according to the implemented
|
||||
" motion, or mark the covered text via a visual selection. As inner text motions
|
||||
" need to mark both to the left and right of the cursor position, the visual
|
||||
" selection needs to be used.
|
||||
"
|
||||
" VIM's built-in inner text objects also work in visual mode; they have
|
||||
" different behavior depending on whether visual mode has just been entered or
|
||||
" whether text has already been selected.
|
||||
" We deviate from that and always override the existing selection.
|
||||
function! s:CreateInnerMotionMappings() "{{{1
|
||||
" Create mappings according to this template:
|
||||
" (* stands for the mode [ov], ? for the underlying motion [wbe].)
|
||||
"
|
||||
" *noremap <script> <Plug>CamelCaseMotion_i? :<C-U>call <SID>CamelCaseInnerMotion('?',v:count1)<CR>
|
||||
" if ! hasmapto('<Plug>CamelCaseInnerMotion_i?', '*')
|
||||
" *map <silent> i,? <Plug>CamelCaseInnerMotion_i?
|
||||
" endif
|
||||
|
||||
for l:mode in ['o', 'v']
|
||||
for l:motion in ['w', 'b', 'e']
|
||||
let l:targetMapping = '<Plug>CamelCaseMotion_i' . l:motion
|
||||
execute l:mode . 'noremap <script> ' . l:targetMapping . ' :<C-U>call <SID>CamelCaseInnerMotion(''' . l:motion . ''',v:count1)<CR>'
|
||||
if ! hasmapto(l:targetMapping, l:mode)
|
||||
execute l:mode . 'map <silent> i,' . l:motion . ' ' . l:targetMapping
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
call s:CreateMotionMappings()
|
||||
call s:CreateInnerMotionMappings()
|
||||
|
||||
" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=marker :
|
||||
536
vim/plugin/cecutil.vim
Normal file
536
vim/plugin/cecutil.vim
Normal file
@@ -0,0 +1,536 @@
|
||||
" cecutil.vim : save/restore window position
|
||||
" save/restore mark position
|
||||
" save/restore selected user maps
|
||||
" Author: Charles E. Campbell, Jr.
|
||||
" Version: 18h ASTRO-ONLY
|
||||
" Date: Apr 05, 2010
|
||||
"
|
||||
" Saving Restoring Destroying Marks: {{{1
|
||||
" call SaveMark(markname) let savemark= SaveMark(markname)
|
||||
" call RestoreMark(markname) call RestoreMark(savemark)
|
||||
" call DestroyMark(markname)
|
||||
" commands: SM RM DM
|
||||
"
|
||||
" Saving Restoring Destroying Window Position: {{{1
|
||||
" call SaveWinPosn() let winposn= SaveWinPosn()
|
||||
" call RestoreWinPosn() call RestoreWinPosn(winposn)
|
||||
" \swp : save current window/buffer's position
|
||||
" \rwp : restore current window/buffer's previous position
|
||||
" commands: SWP RWP
|
||||
"
|
||||
" Saving And Restoring User Maps: {{{1
|
||||
" call SaveUserMaps(mapmode,maplead,mapchx,suffix)
|
||||
" call RestoreUserMaps(suffix)
|
||||
"
|
||||
" GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim
|
||||
"
|
||||
" You believe that God is one. You do well. The demons also {{{1
|
||||
" believe, and shudder. But do you want to know, vain man, that
|
||||
" faith apart from works is dead? (James 2:19,20 WEB)
|
||||
"redraw!|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" Load Once: {{{1
|
||||
if &cp || exists("g:loaded_cecutil")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_cecutil = "v18h"
|
||||
let s:keepcpo = &cpo
|
||||
set cpo&vim
|
||||
"DechoRemOn
|
||||
|
||||
" =======================
|
||||
" Public Interface: {{{1
|
||||
" =======================
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" Map Interface: {{{2
|
||||
if !hasmapto('<Plug>SaveWinPosn')
|
||||
map <unique> <Leader>swp <Plug>SaveWinPosn
|
||||
endif
|
||||
if !hasmapto('<Plug>RestoreWinPosn')
|
||||
map <unique> <Leader>rwp <Plug>RestoreWinPosn
|
||||
endif
|
||||
nmap <silent> <Plug>SaveWinPosn :call SaveWinPosn()<CR>
|
||||
nmap <silent> <Plug>RestoreWinPosn :call RestoreWinPosn()<CR>
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" Command Interface: {{{2
|
||||
com! -bar -nargs=0 SWP call SaveWinPosn()
|
||||
com! -bar -nargs=? RWP call RestoreWinPosn(<args>)
|
||||
com! -bar -nargs=1 SM call SaveMark(<q-args>)
|
||||
com! -bar -nargs=1 RM call RestoreMark(<q-args>)
|
||||
com! -bar -nargs=1 DM call DestroyMark(<q-args>)
|
||||
|
||||
com! -bar -nargs=1 WLR call s:WinLineRestore(<q-args>)
|
||||
|
||||
if v:version < 630
|
||||
let s:modifier= "sil! "
|
||||
else
|
||||
let s:modifier= "sil! keepj "
|
||||
endif
|
||||
|
||||
" ===============
|
||||
" Functions: {{{1
|
||||
" ===============
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" SaveWinPosn: {{{2
|
||||
" let winposn= SaveWinPosn() will save window position in winposn variable
|
||||
" call SaveWinPosn() will save window position in b:cecutil_winposn{b:cecutil_iwinposn}
|
||||
" let winposn= SaveWinPosn(0) will *only* save window position in winposn variable (no stacking done)
|
||||
fun! SaveWinPosn(...)
|
||||
" echomsg "Decho: SaveWinPosn() a:0=".a:0
|
||||
if line("$") == 1 && getline(1) == ""
|
||||
" echomsg "Decho: SaveWinPosn : empty buffer"
|
||||
return ""
|
||||
endif
|
||||
let so_keep = &l:so
|
||||
let siso_keep = &siso
|
||||
let ss_keep = &l:ss
|
||||
setlocal so=0 siso=0 ss=0
|
||||
|
||||
let swline = line(".") " save-window line in file
|
||||
let swcol = col(".") " save-window column in file
|
||||
if swcol >= col("$")
|
||||
let swcol= swcol + virtcol(".") - virtcol("$") " adjust for virtual edit (cursor past end-of-line)
|
||||
endif
|
||||
let swwline = winline() - 1 " save-window window line
|
||||
let swwcol = virtcol(".") - wincol() " save-window window column
|
||||
let savedposn = ""
|
||||
" echomsg "Decho: sw[".swline.",".swcol."] sww[".swwline.",".swwcol."]"
|
||||
let savedposn = "call GoWinbufnr(".winbufnr(0).")"
|
||||
let savedposn = savedposn."|".s:modifier.swline
|
||||
let savedposn = savedposn."|".s:modifier."norm! 0z\<cr>"
|
||||
if swwline > 0
|
||||
let savedposn= savedposn.":".s:modifier."call s:WinLineRestore(".(swwline+1).")\<cr>"
|
||||
endif
|
||||
if swwcol > 0
|
||||
let savedposn= savedposn.":".s:modifier."norm! 0".swwcol."zl\<cr>"
|
||||
endif
|
||||
let savedposn = savedposn.":".s:modifier."call cursor(".swline.",".swcol.")\<cr>"
|
||||
|
||||
" save window position in
|
||||
" b:cecutil_winposn_{iwinposn} (stack)
|
||||
" only when SaveWinPosn() is used
|
||||
if a:0 == 0
|
||||
if !exists("b:cecutil_iwinposn")
|
||||
let b:cecutil_iwinposn= 1
|
||||
else
|
||||
let b:cecutil_iwinposn= b:cecutil_iwinposn + 1
|
||||
endif
|
||||
" echomsg "Decho: saving posn to SWP stack"
|
||||
let b:cecutil_winposn{b:cecutil_iwinposn}= savedposn
|
||||
endif
|
||||
|
||||
let &l:so = so_keep
|
||||
let &siso = siso_keep
|
||||
let &l:ss = ss_keep
|
||||
|
||||
" if exists("b:cecutil_iwinposn") " Decho
|
||||
" echomsg "Decho: b:cecutil_winpos{".b:cecutil_iwinposn."}[".b:cecutil_winposn{b:cecutil_iwinposn}."]"
|
||||
" else " Decho
|
||||
" echomsg "Decho: b:cecutil_iwinposn doesn't exist"
|
||||
" endif " Decho
|
||||
" echomsg "Decho: SaveWinPosn [".savedposn."]"
|
||||
return savedposn
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" RestoreWinPosn: {{{2
|
||||
" call RestoreWinPosn()
|
||||
" call RestoreWinPosn(winposn)
|
||||
fun! RestoreWinPosn(...)
|
||||
" echomsg "Decho: RestoreWinPosn() a:0=".a:0
|
||||
" echomsg "Decho: getline(1)<".getline(1).">"
|
||||
" echomsg "Decho: line(.)=".line(".")
|
||||
if line("$") == 1 && getline(1) == ""
|
||||
" echomsg "Decho: RestoreWinPosn : empty buffer"
|
||||
return ""
|
||||
endif
|
||||
let so_keep = &l:so
|
||||
let siso_keep = &l:siso
|
||||
let ss_keep = &l:ss
|
||||
setlocal so=0 siso=0 ss=0
|
||||
|
||||
if a:0 == 0 || a:1 == ""
|
||||
" use saved window position in b:cecutil_winposn{b:cecutil_iwinposn} if it exists
|
||||
if exists("b:cecutil_iwinposn") && exists("b:cecutil_winposn{b:cecutil_iwinposn}")
|
||||
" echomsg "Decho: using stack b:cecutil_winposn{".b:cecutil_iwinposn."}<".b:cecutil_winposn{b:cecutil_iwinposn}.">"
|
||||
try
|
||||
exe s:modifier.b:cecutil_winposn{b:cecutil_iwinposn}
|
||||
catch /^Vim\%((\a\+)\)\=:E749/
|
||||
" ignore empty buffer error messages
|
||||
endtry
|
||||
" normally drop top-of-stack by one
|
||||
" but while new top-of-stack doesn't exist
|
||||
" drop top-of-stack index by one again
|
||||
if b:cecutil_iwinposn >= 1
|
||||
unlet b:cecutil_winposn{b:cecutil_iwinposn}
|
||||
let b:cecutil_iwinposn= b:cecutil_iwinposn - 1
|
||||
while b:cecutil_iwinposn >= 1 && !exists("b:cecutil_winposn{b:cecutil_iwinposn}")
|
||||
let b:cecutil_iwinposn= b:cecutil_iwinposn - 1
|
||||
endwhile
|
||||
if b:cecutil_iwinposn < 1
|
||||
unlet b:cecutil_iwinposn
|
||||
endif
|
||||
endif
|
||||
else
|
||||
echohl WarningMsg
|
||||
echomsg "***warning*** need to SaveWinPosn first!"
|
||||
echohl None
|
||||
endif
|
||||
|
||||
else " handle input argument
|
||||
" echomsg "Decho: using input a:1<".a:1.">"
|
||||
" use window position passed to this function
|
||||
exe a:1
|
||||
" remove a:1 pattern from b:cecutil_winposn{b:cecutil_iwinposn} stack
|
||||
if exists("b:cecutil_iwinposn")
|
||||
let jwinposn= b:cecutil_iwinposn
|
||||
while jwinposn >= 1 " search for a:1 in iwinposn..1
|
||||
if exists("b:cecutil_winposn{jwinposn}") " if it exists
|
||||
if a:1 == b:cecutil_winposn{jwinposn} " and the pattern matches
|
||||
unlet b:cecutil_winposn{jwinposn} " unlet it
|
||||
if jwinposn == b:cecutil_iwinposn " if at top-of-stack
|
||||
let b:cecutil_iwinposn= b:cecutil_iwinposn - 1 " drop stacktop by one
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let jwinposn= jwinposn - 1
|
||||
endwhile
|
||||
endif
|
||||
endif
|
||||
|
||||
" Seems to be something odd: vertical motions after RWP
|
||||
" cause jump to first column. The following fixes that.
|
||||
" Note: was using wincol()>1, but with signs, a cursor
|
||||
" at column 1 yields wincol()==3. Beeping ensued.
|
||||
let vekeep= &ve
|
||||
set ve=all
|
||||
if virtcol('.') > 1
|
||||
exe s:modifier."norm! hl"
|
||||
elseif virtcol(".") < virtcol("$")
|
||||
exe s:modifier."norm! lh"
|
||||
endif
|
||||
let &ve= vekeep
|
||||
|
||||
let &l:so = so_keep
|
||||
let &l:siso = siso_keep
|
||||
let &l:ss = ss_keep
|
||||
|
||||
" echomsg "Decho: RestoreWinPosn"
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" s:WinLineRestore: {{{2
|
||||
fun! s:WinLineRestore(swwline)
|
||||
" echomsg "Decho: s:WinLineRestore(swwline=".a:swwline.")"
|
||||
while winline() < a:swwline
|
||||
let curwinline= winline()
|
||||
exe s:modifier."norm! \<c-y>"
|
||||
if curwinline == winline()
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
" echomsg "Decho: s:WinLineRestore"
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" GoWinbufnr: go to window holding given buffer (by number) {{{2
|
||||
" Prefers current window; if its buffer number doesn't match,
|
||||
" then will try from topleft to bottom right
|
||||
fun! GoWinbufnr(bufnum)
|
||||
" call Dfunc("GoWinbufnr(".a:bufnum.")")
|
||||
if winbufnr(0) == a:bufnum
|
||||
" call Dret("GoWinbufnr : winbufnr(0)==a:bufnum")
|
||||
return
|
||||
endif
|
||||
winc t
|
||||
let first=1
|
||||
while winbufnr(0) != a:bufnum && (first || winnr() != 1)
|
||||
winc w
|
||||
let first= 0
|
||||
endwhile
|
||||
" call Dret("GoWinbufnr")
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" SaveMark: sets up a string saving a mark position. {{{2
|
||||
" For example, SaveMark("a")
|
||||
" Also sets up a global variable, g:savemark_{markname}
|
||||
fun! SaveMark(markname)
|
||||
" call Dfunc("SaveMark(markname<".a:markname.">)")
|
||||
let markname= a:markname
|
||||
if strpart(markname,0,1) !~ '\a'
|
||||
let markname= strpart(markname,1,1)
|
||||
endif
|
||||
" call Decho("markname=".markname)
|
||||
|
||||
let lzkeep = &lz
|
||||
set lz
|
||||
|
||||
if 1 <= line("'".markname) && line("'".markname) <= line("$")
|
||||
let winposn = SaveWinPosn(0)
|
||||
exe s:modifier."norm! `".markname
|
||||
let savemark = SaveWinPosn(0)
|
||||
let g:savemark_{markname} = savemark
|
||||
let savemark = markname.savemark
|
||||
call RestoreWinPosn(winposn)
|
||||
else
|
||||
let g:savemark_{markname} = ""
|
||||
let savemark = ""
|
||||
endif
|
||||
|
||||
let &lz= lzkeep
|
||||
|
||||
" call Dret("SaveMark : savemark<".savemark.">")
|
||||
return savemark
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" RestoreMark: {{{2
|
||||
" call RestoreMark("a") -or- call RestoreMark(savemark)
|
||||
fun! RestoreMark(markname)
|
||||
" call Dfunc("RestoreMark(markname<".a:markname.">)")
|
||||
|
||||
if strlen(a:markname) <= 0
|
||||
" call Dret("RestoreMark : no such mark")
|
||||
return
|
||||
endif
|
||||
let markname= strpart(a:markname,0,1)
|
||||
if markname !~ '\a'
|
||||
" handles 'a -> a styles
|
||||
let markname= strpart(a:markname,1,1)
|
||||
endif
|
||||
" call Decho("markname=".markname." strlen(a:markname)=".strlen(a:markname))
|
||||
|
||||
let lzkeep = &lz
|
||||
set lz
|
||||
let winposn = SaveWinPosn(0)
|
||||
|
||||
if strlen(a:markname) <= 2
|
||||
if exists("g:savemark_{markname}") && strlen(g:savemark_{markname}) != 0
|
||||
" use global variable g:savemark_{markname}
|
||||
" call Decho("use savemark list")
|
||||
call RestoreWinPosn(g:savemark_{markname})
|
||||
exe "norm! m".markname
|
||||
endif
|
||||
else
|
||||
" markname is a savemark command (string)
|
||||
" call Decho("use savemark command")
|
||||
let markcmd= strpart(a:markname,1)
|
||||
call RestoreWinPosn(markcmd)
|
||||
exe "norm! m".markname
|
||||
endif
|
||||
|
||||
call RestoreWinPosn(winposn)
|
||||
let &lz = lzkeep
|
||||
|
||||
" call Dret("RestoreMark")
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" DestroyMark: {{{2
|
||||
" call DestroyMark("a") -- destroys mark
|
||||
fun! DestroyMark(markname)
|
||||
" call Dfunc("DestroyMark(markname<".a:markname.">)")
|
||||
|
||||
" save options and set to standard values
|
||||
let reportkeep= &report
|
||||
let lzkeep = &lz
|
||||
set lz report=10000
|
||||
|
||||
let markname= strpart(a:markname,0,1)
|
||||
if markname !~ '\a'
|
||||
" handles 'a -> a styles
|
||||
let markname= strpart(a:markname,1,1)
|
||||
endif
|
||||
" call Decho("markname=".markname)
|
||||
|
||||
let curmod = &mod
|
||||
let winposn = SaveWinPosn(0)
|
||||
1
|
||||
let lineone = getline(".")
|
||||
exe "k".markname
|
||||
d
|
||||
put! =lineone
|
||||
let &mod = curmod
|
||||
call RestoreWinPosn(winposn)
|
||||
|
||||
" restore options to user settings
|
||||
let &report = reportkeep
|
||||
let &lz = lzkeep
|
||||
|
||||
" call Dret("DestroyMark")
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" QArgSplitter: to avoid \ processing by <f-args>, <q-args> is needed. {{{2
|
||||
" However, <q-args> doesn't split at all, so this one returns a list
|
||||
" with splits at all whitespace (only!), plus a leading length-of-list.
|
||||
" The resulting list: qarglist[0] corresponds to a:0
|
||||
" qarglist[i] corresponds to a:{i}
|
||||
fun! QArgSplitter(qarg)
|
||||
" call Dfunc("QArgSplitter(qarg<".a:qarg.">)")
|
||||
let qarglist = split(a:qarg)
|
||||
let qarglistlen = len(qarglist)
|
||||
let qarglist = insert(qarglist,qarglistlen)
|
||||
" call Dret("QArgSplitter ".string(qarglist))
|
||||
return qarglist
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" ListWinPosn: {{{2
|
||||
"fun! ListWinPosn() " Decho
|
||||
" if !exists("b:cecutil_iwinposn") || b:cecutil_iwinposn == 0 " Decho
|
||||
" call Decho("nothing on SWP stack") " Decho
|
||||
" else " Decho
|
||||
" let jwinposn= b:cecutil_iwinposn " Decho
|
||||
" while jwinposn >= 1 " Decho
|
||||
" if exists("b:cecutil_winposn{jwinposn}") " Decho
|
||||
" call Decho("winposn{".jwinposn."}<".b:cecutil_winposn{jwinposn}.">") " Decho
|
||||
" else " Decho
|
||||
" call Decho("winposn{".jwinposn."} -- doesn't exist") " Decho
|
||||
" endif " Decho
|
||||
" let jwinposn= jwinposn - 1 " Decho
|
||||
" endwhile " Decho
|
||||
" endif " Decho
|
||||
"endfun " Decho
|
||||
"com! -nargs=0 LWP call ListWinPosn() " Decho
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" SaveUserMaps: this function sets up a script-variable (s:restoremap) {{{2
|
||||
" which can be used to restore user maps later with
|
||||
" call RestoreUserMaps()
|
||||
"
|
||||
" mapmode - see :help maparg for details (n v o i c l "")
|
||||
" ex. "n" = Normal
|
||||
" The letters "b" and "u" are optional prefixes;
|
||||
" The "u" means that the map will also be unmapped
|
||||
" The "b" means that the map has a <buffer> qualifier
|
||||
" ex. "un" = Normal + unmapping
|
||||
" ex. "bn" = Normal + <buffer>
|
||||
" ex. "bun" = Normal + <buffer> + unmapping
|
||||
" ex. "ubn" = Normal + <buffer> + unmapping
|
||||
" maplead - see mapchx
|
||||
" mapchx - "<something>" handled as a single map item.
|
||||
" ex. "<left>"
|
||||
" - "string" a string of single letters which are actually
|
||||
" multiple two-letter maps (using the maplead:
|
||||
" maplead . each_character_in_string)
|
||||
" ex. maplead="\" and mapchx="abc" saves user mappings for
|
||||
" \a, \b, and \c
|
||||
" Of course, if maplead is "", then for mapchx="abc",
|
||||
" mappings for a, b, and c are saved.
|
||||
" - :something handled as a single map item, w/o the ":"
|
||||
" ex. mapchx= ":abc" will save a mapping for "abc"
|
||||
" suffix - a string unique to your plugin
|
||||
" ex. suffix= "DrawIt"
|
||||
fun! SaveUserMaps(mapmode,maplead,mapchx,suffix)
|
||||
" call Dfunc("SaveUserMaps(mapmode<".a:mapmode."> maplead<".a:maplead."> mapchx<".a:mapchx."> suffix<".a:suffix.">)")
|
||||
|
||||
if !exists("s:restoremap_{a:suffix}")
|
||||
" initialize restoremap_suffix to null string
|
||||
let s:restoremap_{a:suffix}= ""
|
||||
endif
|
||||
|
||||
" set up dounmap: if 1, then save and unmap (a:mapmode leads with a "u")
|
||||
" if 0, save only
|
||||
let mapmode = a:mapmode
|
||||
let dounmap = 0
|
||||
let dobuffer = ""
|
||||
while mapmode =~ '^[bu]'
|
||||
if mapmode =~ '^u'
|
||||
let dounmap = 1
|
||||
let mapmode = strpart(a:mapmode,1)
|
||||
elseif mapmode =~ '^b'
|
||||
let dobuffer = "<buffer> "
|
||||
let mapmode = strpart(a:mapmode,1)
|
||||
endif
|
||||
endwhile
|
||||
" call Decho("dounmap=".dounmap." dobuffer<".dobuffer.">")
|
||||
|
||||
" save single map :...something...
|
||||
if strpart(a:mapchx,0,1) == ':'
|
||||
" call Decho("save single map :...something...")
|
||||
let amap= strpart(a:mapchx,1)
|
||||
if amap == "|" || amap == "\<c-v>"
|
||||
let amap= "\<c-v>".amap
|
||||
endif
|
||||
let amap = a:maplead.amap
|
||||
let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|:silent! ".mapmode."unmap ".dobuffer.amap
|
||||
if maparg(amap,mapmode) != ""
|
||||
let maprhs = substitute(maparg(amap,mapmode),'|','<bar>','ge')
|
||||
let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|:".mapmode."map ".dobuffer.amap." ".maprhs
|
||||
endif
|
||||
if dounmap
|
||||
exe "silent! ".mapmode."unmap ".dobuffer.amap
|
||||
endif
|
||||
|
||||
" save single map <something>
|
||||
elseif strpart(a:mapchx,0,1) == '<'
|
||||
" call Decho("save single map <something>")
|
||||
let amap = a:mapchx
|
||||
if amap == "|" || amap == "\<c-v>"
|
||||
let amap= "\<c-v>".amap
|
||||
" call Decho("amap[[".amap."]]")
|
||||
endif
|
||||
let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|silent! ".mapmode."unmap ".dobuffer.amap
|
||||
if maparg(a:mapchx,mapmode) != ""
|
||||
let maprhs = substitute(maparg(amap,mapmode),'|','<bar>','ge')
|
||||
let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|".mapmode."map ".dobuffer.amap." ".maprhs
|
||||
endif
|
||||
if dounmap
|
||||
exe "silent! ".mapmode."unmap ".dobuffer.amap
|
||||
endif
|
||||
|
||||
" save multiple maps
|
||||
else
|
||||
" call Decho("save multiple maps")
|
||||
let i= 1
|
||||
while i <= strlen(a:mapchx)
|
||||
let amap= a:maplead.strpart(a:mapchx,i-1,1)
|
||||
if amap == "|" || amap == "\<c-v>"
|
||||
let amap= "\<c-v>".amap
|
||||
endif
|
||||
let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|silent! ".mapmode."unmap ".dobuffer.amap
|
||||
if maparg(amap,mapmode) != ""
|
||||
let maprhs = substitute(maparg(amap,mapmode),'|','<bar>','ge')
|
||||
let s:restoremap_{a:suffix} = s:restoremap_{a:suffix}."|".mapmode."map ".dobuffer.amap." ".maprhs
|
||||
endif
|
||||
if dounmap
|
||||
exe "silent! ".mapmode."unmap ".dobuffer.amap
|
||||
endif
|
||||
let i= i + 1
|
||||
endwhile
|
||||
endif
|
||||
" call Dret("SaveUserMaps : restoremap_".a:suffix.": ".s:restoremap_{a:suffix})
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" RestoreUserMaps: {{{2
|
||||
" Used to restore user maps saved by SaveUserMaps()
|
||||
fun! RestoreUserMaps(suffix)
|
||||
" call Dfunc("RestoreUserMaps(suffix<".a:suffix.">)")
|
||||
if exists("s:restoremap_{a:suffix}")
|
||||
let s:restoremap_{a:suffix}= substitute(s:restoremap_{a:suffix},'|\s*$','','e')
|
||||
if s:restoremap_{a:suffix} != ""
|
||||
" call Decho("exe ".s:restoremap_{a:suffix})
|
||||
exe "silent! ".s:restoremap_{a:suffix}
|
||||
endif
|
||||
unlet s:restoremap_{a:suffix}
|
||||
endif
|
||||
" call Dret("RestoreUserMaps")
|
||||
endfun
|
||||
|
||||
" ==============
|
||||
" Restore: {{{1
|
||||
" ==============
|
||||
let &cpo= s:keepcpo
|
||||
unlet s:keepcpo
|
||||
|
||||
" ================
|
||||
" Modelines: {{{1
|
||||
" ================
|
||||
" vim: ts=4 fdm=marker
|
||||
166
vim/plugin/color_sample_pack.vim
Normal file
166
vim/plugin/color_sample_pack.vim
Normal file
@@ -0,0 +1,166 @@
|
||||
" Vim default schemes
|
||||
amenu T&hemes.D&efault.Blue :colo blue<CR>
|
||||
amenu T&hemes.D&efault.DarkBlue :colo darkblue<CR>
|
||||
amenu T&hemes.D&efault.Default :colo default<CR>
|
||||
amenu T&hemes.D&efault.Delek :colo delek<CR>
|
||||
amenu T&hemes.D&efault.Desert :colo desert<CR>
|
||||
amenu T&hemes.D&efault.ElfLord :colo elflord<CR>
|
||||
amenu T&hemes.D&efault.Evening :colo evening<CR>
|
||||
amenu T&hemes.D&efault.Koehler :colo koehler<CR>
|
||||
amenu T&hemes.D&efault.Morning :colo morning<CR>
|
||||
amenu T&hemes.D&efault.Murphy :colo murphy<CR>
|
||||
amenu T&hemes.D&efault.Pablo :colo pablo<CR>
|
||||
amenu T&hemes.D&efault.PeachPuff :colo peachpuff<CR>
|
||||
amenu T&hemes.D&efault.Ron :colo ron<CR>
|
||||
amenu T&hemes.D&efault.Shine :colo shine<CR>
|
||||
amenu T&hemes.D&efault.Torte :colo torte<CR>
|
||||
|
||||
" Recommended Themes
|
||||
amenu T&hemes.&Recommendations.InkPot :colo inkpot<CR>
|
||||
amenu T&hemes.&Recommendations.MetaCosm :colo metacosm<CR>
|
||||
amenu T&hemes.&Recommendations.MidNight2 :colo midnight2<CR>
|
||||
amenu T&hemes.&Recommendations.PS_Warm :let psc_style='warm'<CR>:colo ps_color<CR>
|
||||
|
||||
amenu T&hemes.-s1- :
|
||||
|
||||
"submenu black
|
||||
amenu T&hemes.black.brookstream :colo brookstream<CR>
|
||||
amenu T&hemes.black.candy :colo candy<CR>
|
||||
amenu T&hemes.black.colorer :colo colorer<CR>
|
||||
amenu T&hemes.black.dante :colo dante<CR>
|
||||
amenu T&hemes.black.darkocean :colo darkocean<CR>
|
||||
amenu T&hemes.black.dw_blue :colo dw_blue<CR>
|
||||
amenu T&hemes.black.dw_cyan :colo dw_cyan<CR>
|
||||
amenu T&hemes.black.dw_green :colo dw_green<CR>
|
||||
amenu T&hemes.black.dw_orange :colo dw_orange<CR>
|
||||
amenu T&hemes.black.dw_purple :colo dw_purple<CR>
|
||||
amenu T&hemes.black.dw_red :colo dw_red<CR>
|
||||
amenu T&hemes.black.dw_yellow :colo dw_yellow<CR>
|
||||
amenu T&hemes.black.elflord :colo elflord<CR>
|
||||
amenu T&hemes.black.fnaqevan :colo fnaqevan<CR>
|
||||
amenu T&hemes.black.golden :colo golden<CR>
|
||||
amenu T&hemes.black.*inkpot :colo inkpot<CR>
|
||||
amenu T&hemes.black.koehler :colo koehler<CR>
|
||||
amenu T&hemes.black.less :colo less<CR>
|
||||
amenu T&hemes.black.manxome :colo manxome<CR>
|
||||
amenu T&hemes.black.matrix :colo matrix<CR>
|
||||
amenu T&hemes.black.metacosm :colo metacosm<CR>
|
||||
amenu T&hemes.black.*motus :colo motus<CR>
|
||||
amenu T&hemes.black.murphy :colo murphy<CR>
|
||||
amenu T&hemes.black.neverness :colo neverness<CR>
|
||||
amenu T&hemes.black.nightwish :colo nightwish<CR>
|
||||
amenu T&hemes.black.oceanblack :colo oceanblack<CR>
|
||||
amenu T&hemes.black.pablo :colo pablo<CR>
|
||||
amenu T&hemes.black.*ps_color :colo ps_color<CR>
|
||||
amenu T&hemes.black.relaxedgreen :colo relaxedgreen<CR>
|
||||
amenu T&hemes.black.ron :colo ron<CR>
|
||||
amenu T&hemes.black.tango :colo tango<CR>
|
||||
amenu T&hemes.black.*torte :colo torte<CR>
|
||||
amenu T&hemes.black.vibrantink :colo vibrantink<CR>
|
||||
amenu T&hemes.black.*vividchalk :colo vividchalk<CR>
|
||||
|
||||
"submenu blue
|
||||
amenu T&hemes.blue.astronaut :colo astronaut<CR>
|
||||
amenu T&hemes.blue.asu1dark :colo asu1dark<CR>
|
||||
amenu T&hemes.blue.blue :colo blue<CR>
|
||||
amenu T&hemes.blue.bluegreen :colo bluegreen<CR>
|
||||
amenu T&hemes.blue.borland :colo borland<CR>
|
||||
amenu T&hemes.blue.breeze :colo breeze<CR>
|
||||
amenu T&hemes.blue.darkblue :colo darkblue<CR>
|
||||
amenu T&hemes.blue.darkblue2 :colo darkblue2<CR>
|
||||
amenu T&hemes.blue.denim :colo denim<CR>
|
||||
amenu T&hemes.blue.desertedocean :colo desertedocean<CR>
|
||||
amenu T&hemes.blue.dusk :colo dusk<CR>
|
||||
amenu T&hemes.blue.hhazure :colo hhazure<CR>
|
||||
amenu T&hemes.blue.midnight :colo midnight<CR>
|
||||
amenu T&hemes.blue.midnight2 :colo midnight2<CR>
|
||||
amenu T&hemes.blue.navajo-night :colo navajo-night<CR>
|
||||
amenu T&hemes.blue.oceandeep :colo oceandeep<CR>
|
||||
amenu T&hemes.blue.sea :colo sea<CR>
|
||||
amenu T&hemes.blue.softblue :colo softblue<CR>
|
||||
|
||||
"submenu cyan
|
||||
amenu T&hemes.cyan.darkslategray :colo darkslategray<CR>
|
||||
amenu T&hemes.cyan.marklar :colo marklar<CR>
|
||||
|
||||
"submenu darkgrey
|
||||
amenu T&hemes.darkgrey.candycode :colo candycode<CR>
|
||||
amenu T&hemes.darkgrey.darktango :colo darktango<CR>
|
||||
amenu T&hemes.darkgrey.hhspring :colo hhspring<CR>
|
||||
amenu T&hemes.darkgrey.hhteal :colo hhteal<CR>
|
||||
amenu T&hemes.darkgrey.hhviolet :colo hhviolet<CR>
|
||||
amenu T&hemes.darkgrey.lettuce :colo lettuce<CR>
|
||||
amenu T&hemes.darkgrey.night :colo night<CR>
|
||||
amenu T&hemes.darkgrey.rdark :colo rdark<CR>
|
||||
|
||||
"submenu green
|
||||
amenu T&hemes.green.*tabula :colo tabula<CR>
|
||||
|
||||
"submenu grey
|
||||
amenu T&hemes.grey.biogoo :colo biogoo<CR>
|
||||
amenu T&hemes.grey.camo :colo camo<CR>
|
||||
amenu T&hemes.grey.*dawn :colo dawn<CR>
|
||||
amenu T&hemes.grey.desert :colo desert<CR>
|
||||
amenu T&hemes.grey.desertEx :colo desertEx<CR>
|
||||
amenu T&hemes.grey.evening :colo evening<CR>
|
||||
amenu T&hemes.grey.fog :colo fog<CR>
|
||||
amenu T&hemes.grey.freya :colo freya<CR>
|
||||
amenu T&hemes.grey.neon :colo neon<CR>
|
||||
amenu T&hemes.grey.slate :colo slate<CR>
|
||||
amenu T&hemes.grey.umber-green :colo umber-green<CR>
|
||||
amenu T&hemes.grey.xemacs :colo xemacs<CR>
|
||||
amenu T&hemes.grey.*zenburn :colo zenburn<CR>
|
||||
|
||||
"submenu magenta
|
||||
amenu T&hemes.magenta.lilac :colo lilac<CR>
|
||||
|
||||
"submenu offwhite
|
||||
amenu T&hemes.offwhite.autumn :colo autumn<CR>
|
||||
amenu T&hemes.offwhite.autumnleaf :colo autumnleaf<CR>
|
||||
amenu T&hemes.offwhite.*baycomb :colo baycomb<CR>
|
||||
amenu T&hemes.offwhite.fine_blue :colo fine_blue<CR>
|
||||
amenu T&hemes.offwhite.fruit :colo fruit<CR>
|
||||
amenu T&hemes.offwhite.habiLight :colo habiLight<CR>
|
||||
amenu T&hemes.offwhite.ironman :colo ironman<CR>
|
||||
amenu T&hemes.offwhite.morning :colo morning<CR>
|
||||
amenu T&hemes.offwhite.nuvola :colo nuvola<CR>
|
||||
amenu T&hemes.offwhite.oceanlight :colo oceanlight<CR>
|
||||
amenu T&hemes.offwhite.pyte :colo pyte<CR>
|
||||
amenu T&hemes.offwhite.simpleandfriendly :colo simpleandfriendly<CR>
|
||||
|
||||
"submenu red
|
||||
amenu T&hemes.red.ChocolateLiquor :colo ChocolateLiquor<CR>
|
||||
amenu T&hemes.red.hhpink :colo hhpink<CR>
|
||||
amenu T&hemes.red.*navajo :colo navajo<CR>
|
||||
amenu T&hemes.red.peachpuff :colo peachpuff<CR>
|
||||
amenu T&hemes.red.tomatosoup :colo tomatosoup<CR>
|
||||
|
||||
"submenu unknown
|
||||
amenu T&hemes.unknown.bw :colo bw<CR>
|
||||
amenu T&hemes.unknown.calmar256-light :colo calmar256-light<CR>
|
||||
amenu T&hemes.unknown.chela_light :colo chela_light<CR>
|
||||
amenu T&hemes.unknown.colorscheme_template :colo colorscheme_template<CR>
|
||||
amenu T&hemes.unknown.default :colo default<CR>
|
||||
amenu T&hemes.unknown.desert256 :colo desert256<CR>
|
||||
amenu T&hemes.unknown.impact :colo impact<CR>
|
||||
amenu T&hemes.unknown.psql :colo psql<CR>
|
||||
amenu T&hemes.unknown.vc :colo vc<CR>
|
||||
|
||||
"submenu white
|
||||
amenu T&hemes.white.delek :colo delek<CR>
|
||||
amenu T&hemes.white.eclipse :colo eclipse<CR>
|
||||
amenu T&hemes.white.martin_krischik :colo martin_krischik<CR>
|
||||
amenu T&hemes.white.*moria :colo moria<CR>
|
||||
amenu T&hemes.white.print_bw :colo print_bw<CR>
|
||||
amenu T&hemes.white.shine :colo shine<CR>
|
||||
amenu T&hemes.white.*sienna :colo sienna<CR>
|
||||
amenu T&hemes.white.tolerable :colo tolerable<CR>
|
||||
amenu T&hemes.white.zellner :colo zellner<CR>
|
||||
|
||||
"submenu yellow
|
||||
amenu T&hemes.yellow.PapayaWhip :colo PapayaWhip<CR>
|
||||
amenu T&hemes.yellow.buttercream :colo buttercream<CR>
|
||||
amenu T&hemes.yellow.hhorange :colo hhorange<CR>
|
||||
amenu T&hemes.yellow.olive :colo olive<CR>
|
||||
amenu T&hemes.yellow.professional :colo professional<CR>
|
||||
amenu T&hemes.yellow.robinhood :colo robinhood<CR>
|
||||
216
vim/plugin/conque_term.vim
Normal file
216
vim/plugin/conque_term.vim
Normal file
@@ -0,0 +1,216 @@
|
||||
" FILE: plugin/conque_term.vim {{{
|
||||
" AUTHOR: Nico Raffo <nicoraffo@gmail.com>
|
||||
" WEBSITE: http://conque.googlecode.com
|
||||
" MODIFIED: 2011-09-02
|
||||
" VERSION: 2.3, for Vim 7.0
|
||||
" LICENSE:
|
||||
" Conque - Vim terminal/console emulator
|
||||
" Copyright (C) 2009-2011 Nico Raffo
|
||||
"
|
||||
" MIT License
|
||||
"
|
||||
" 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.
|
||||
" }}}
|
||||
|
||||
" See docs/conque_term.txt for help or type :help ConqueTerm
|
||||
|
||||
if exists('g:ConqueTerm_Loaded') || v:version < 700
|
||||
finish
|
||||
endif
|
||||
|
||||
" **********************************************************************************************************
|
||||
" **** DEFAULT CONFIGURATION *******************************************************************************
|
||||
" **********************************************************************************************************
|
||||
|
||||
" DO NOT EDIT CONFIGURATION SETTINGS IN THIS FILE!
|
||||
" Define these variables in your local .vimrc to over-ride the default values
|
||||
|
||||
" {{{
|
||||
|
||||
" Fast mode {{{
|
||||
" Disables all features which could cause Conque to run slowly, including:
|
||||
" * Disables terminal colors
|
||||
" * Disables some multi-byte character handling
|
||||
if !exists('g:ConqueTerm_FastMode')
|
||||
let g:ConqueTerm_FastMode = 0
|
||||
endif " }}}
|
||||
|
||||
" automatically go into insert mode when entering buffer {{{
|
||||
if !exists('g:ConqueTerm_InsertOnEnter')
|
||||
let g:ConqueTerm_InsertOnEnter = 0
|
||||
endif " }}}
|
||||
|
||||
" Allow user to use <C-w> keys to switch window in insert mode. {{{
|
||||
if !exists('g:ConqueTerm_CWInsert')
|
||||
let g:ConqueTerm_CWInsert = 0
|
||||
endif " }}}
|
||||
|
||||
" Choose key mapping to leave insert mode {{{
|
||||
" If you choose something other than '<Esc>', then <Esc> will be sent to terminal
|
||||
" Using a different key will usually fix Alt/Meta key issues
|
||||
if !exists('g:ConqueTerm_EscKey')
|
||||
let g:ConqueTerm_EscKey = '<Esc>'
|
||||
endif " }}}
|
||||
|
||||
" Use this key to execute the current file in a split window. {{{
|
||||
" THIS IS A GLOBAL KEY MAPPING
|
||||
if !exists('g:ConqueTerm_ExecFileKey')
|
||||
let g:ConqueTerm_ExecFileKey = '<F11>'
|
||||
endif " }}}
|
||||
|
||||
" Use this key to send the current file contents to conque. {{{
|
||||
" THIS IS A GLOBAL KEY MAPPING
|
||||
if !exists('g:ConqueTerm_SendFileKey')
|
||||
let g:ConqueTerm_SendFileKey = '<F10>'
|
||||
endif " }}}
|
||||
|
||||
" Use this key to send selected text to conque. {{{
|
||||
" THIS IS A GLOBAL KEY MAPPING
|
||||
if !exists('g:ConqueTerm_SendVisKey')
|
||||
let g:ConqueTerm_SendVisKey = '<F9>'
|
||||
endif " }}}
|
||||
|
||||
" Use this key to toggle terminal key mappings. {{{
|
||||
" Only mapped inside of Conque buffers.
|
||||
if !exists('g:ConqueTerm_ToggleKey')
|
||||
let g:ConqueTerm_ToggleKey = '<F8>'
|
||||
endif " }}}
|
||||
|
||||
" Enable color. {{{
|
||||
" If your apps use a lot of color it will slow down the shell.
|
||||
" 0 - no terminal colors. You still will see Vim syntax highlighting.
|
||||
" 1 - limited terminal colors (recommended). Past terminal color history cleared regularly.
|
||||
" 2 - all terminal colors. Terminal color history never cleared.
|
||||
if !exists('g:ConqueTerm_Color')
|
||||
let g:ConqueTerm_Color = 1
|
||||
endif " }}}
|
||||
|
||||
" Color mode. Windows ONLY {{{
|
||||
" Set this variable to 'conceal' to use Vim's conceal mode for terminal colors.
|
||||
" This makes colors render much faster, but has some odd baggage.
|
||||
if !exists('g:ConqueTerm_ColorMode')
|
||||
let g:ConqueTerm_ColorMode = ''
|
||||
endif " }}}
|
||||
|
||||
" TERM environment setting {{{
|
||||
if !exists('g:ConqueTerm_TERM')
|
||||
let g:ConqueTerm_TERM = 'vt100'
|
||||
endif " }}}
|
||||
|
||||
" Syntax for your buffer {{{
|
||||
if !exists('g:ConqueTerm_Syntax')
|
||||
let g:ConqueTerm_Syntax = 'conque_term'
|
||||
endif " }}}
|
||||
|
||||
" Keep on updating the shell window after you've switched to another buffer {{{
|
||||
if !exists('g:ConqueTerm_ReadUnfocused')
|
||||
let g:ConqueTerm_ReadUnfocused = 0
|
||||
endif " }}}
|
||||
|
||||
" Use this regular expression to highlight prompt {{{
|
||||
if !exists('g:ConqueTerm_PromptRegex')
|
||||
let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$'
|
||||
endif " }}}
|
||||
|
||||
" Choose which Python version to attempt to load first {{{
|
||||
" Valid values are 2, 3 or 0 (no preference)
|
||||
if !exists('g:ConqueTerm_PyVersion')
|
||||
let g:ConqueTerm_PyVersion = 2
|
||||
endif " }}}
|
||||
|
||||
" Path to python.exe. (Windows only) {{{
|
||||
" By default, Conque will check C:\PythonNN\python.exe then will search system path
|
||||
" If you have installed Python in an unusual location and it's not in your path, fill in the full path below
|
||||
" E.g. 'C:\Program Files\Python\Python27\python.exe'
|
||||
if !exists('g:ConqueTerm_PyExe')
|
||||
let g:ConqueTerm_PyExe = ''
|
||||
endif " }}}
|
||||
|
||||
" Automatically close buffer when program exits {{{
|
||||
if !exists('g:ConqueTerm_CloseOnEnd')
|
||||
let g:ConqueTerm_CloseOnEnd = 0
|
||||
endif " }}}
|
||||
|
||||
" Send function key presses to terminal {{{
|
||||
if !exists('g:ConqueTerm_SendFunctionKeys')
|
||||
let g:ConqueTerm_SendFunctionKeys = 0
|
||||
endif " }}}
|
||||
|
||||
" Session support {{{
|
||||
if !exists('g:ConqueTerm_SessionSupport')
|
||||
let g:ConqueTerm_SessionSupport = 0
|
||||
endif " }}}
|
||||
|
||||
" hide Conque startup messages {{{
|
||||
" messages should only appear the first 3 times you start Vim with a new version of Conque
|
||||
" and include important Conque feature and option descriptions
|
||||
" TODO - disabled and unused for now
|
||||
if !exists('g:ConqueTerm_StartMessages')
|
||||
let g:ConqueTerm_StartMessages = 1
|
||||
endif " }}}
|
||||
|
||||
" Windows character code page {{{
|
||||
" Leave at 0 to use current environment code page.
|
||||
" Use 65001 for utf-8, although many console apps do not support it.
|
||||
if !exists('g:ConqueTerm_CodePage')
|
||||
let g:ConqueTerm_CodePage = 0
|
||||
endif " }}}
|
||||
|
||||
" InsertCharPre support {{{
|
||||
" Disable this feature by default, still in Beta
|
||||
if !exists('g:ConqueTerm_InsertCharPre')
|
||||
let g:ConqueTerm_InsertCharPre = 0
|
||||
endif " }}}
|
||||
|
||||
" }}}
|
||||
|
||||
" **********************************************************************************************************
|
||||
" **** Startup *********************************************************************************************
|
||||
" **********************************************************************************************************
|
||||
|
||||
" Startup {{{
|
||||
|
||||
let g:ConqueTerm_Loaded = 1
|
||||
let g:ConqueTerm_Idx = 0
|
||||
let g:ConqueTerm_Version = 230
|
||||
|
||||
command! -nargs=+ -complete=shellcmd ConqueTerm call conque_term#open(<q-args>)
|
||||
command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(<q-args>, ['belowright split'])
|
||||
command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(<q-args>, ['belowright vsplit'])
|
||||
command! -nargs=+ -complete=shellcmd ConqueTermTab call conque_term#open(<q-args>, ['tabnew'])
|
||||
|
||||
" }}}
|
||||
|
||||
" **********************************************************************************************************
|
||||
" **** Global Mappings & Autocommands **********************************************************************
|
||||
" **********************************************************************************************************
|
||||
|
||||
" Startup {{{
|
||||
|
||||
if exists('g:ConqueTerm_SessionSupport') && g:ConqueTerm_SessionSupport == 1
|
||||
autocmd SessionLoadPost * call conque_term#resume_session()
|
||||
endif
|
||||
|
||||
if maparg(g:ConqueTerm_ExecFileKey, 'n') == ''
|
||||
exe 'nnoremap <silent> ' . g:ConqueTerm_ExecFileKey . ' :call conque_term#exec_file()<CR>'
|
||||
endif
|
||||
|
||||
" }}}
|
||||
|
||||
" vim:foldmethod=marker
|
||||
434
vim/plugin/delimitMate.vim
Normal file
434
vim/plugin/delimitMate.vim
Normal file
@@ -0,0 +1,434 @@
|
||||
" File: plugin/delimitMate.vim
|
||||
" Version: 2.6
|
||||
" Modified: 2011-01-14
|
||||
" Description: This plugin provides auto-completion for quotes, parens, etc.
|
||||
" Maintainer: Israel Chauca F. <israelchauca@gmail.com>
|
||||
" Manual: Read ":help delimitMate".
|
||||
" ============================================================================
|
||||
|
||||
" Initialization: {{{
|
||||
|
||||
if exists("g:loaded_delimitMate") || &cp
|
||||
" User doesn't want this plugin or compatible is set, let's get out!
|
||||
finish
|
||||
endif
|
||||
let g:loaded_delimitMate = 1
|
||||
|
||||
if exists("s:loaded_delimitMate") && !exists("g:delimitMate_testing")
|
||||
" Don't define the functions if they already exist: just do the work
|
||||
" (unless we are testing):
|
||||
call s:DelimitMateDo()
|
||||
finish
|
||||
endif
|
||||
|
||||
if v:version < 700
|
||||
echoerr "delimitMate: this plugin requires vim >= 7!"
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:loaded_delimitMate = 1
|
||||
let delimitMate_version = "2.6"
|
||||
|
||||
function! s:option_init(name, default) "{{{
|
||||
let b = exists("b:delimitMate_" . a:name)
|
||||
let g = exists("g:delimitMate_" . a:name)
|
||||
let prefix = "_l_delimitMate_"
|
||||
|
||||
if !b && !g
|
||||
let sufix = a:default
|
||||
elseif !b && g
|
||||
exec "let sufix = g:delimitMate_" . a:name
|
||||
else
|
||||
exec "let sufix = b:delimitMate_" . a:name
|
||||
endif
|
||||
if exists("b:" . prefix . a:name)
|
||||
exec "unlockvar! b:" . prefix . a:name
|
||||
endif
|
||||
exec "let b:" . prefix . a:name . " = " . string(sufix)
|
||||
exec "lockvar! b:" . prefix . a:name
|
||||
endfunction "}}}
|
||||
|
||||
function! s:init() "{{{
|
||||
" Initialize variables:
|
||||
|
||||
" autoclose
|
||||
call s:option_init("autoclose", 1)
|
||||
|
||||
" matchpairs
|
||||
call s:option_init("matchpairs", string(&matchpairs)[1:-2])
|
||||
call s:option_init("matchpairs_list", split(b:_l_delimitMate_matchpairs, ','))
|
||||
call s:option_init("left_delims", split(b:_l_delimitMate_matchpairs, ':.,\='))
|
||||
call s:option_init("right_delims", split(b:_l_delimitMate_matchpairs, ',\=.:'))
|
||||
|
||||
" quotes
|
||||
call s:option_init("quotes", "\" ' `")
|
||||
call s:option_init("quotes_list", split(b:_l_delimitMate_quotes))
|
||||
|
||||
" nesting_quotes
|
||||
call s:option_init("nesting_quotes", [])
|
||||
|
||||
" excluded_regions
|
||||
call s:option_init("excluded_regions", "Comment")
|
||||
call s:option_init("excluded_regions_list", split(b:_l_delimitMate_excluded_regions, ',\s*'))
|
||||
let enabled = len(b:_l_delimitMate_excluded_regions_list) > 0
|
||||
call s:option_init("excluded_regions_enabled", enabled)
|
||||
|
||||
" excluded filetypes
|
||||
call s:option_init("excluded_ft", "")
|
||||
|
||||
" expand_space
|
||||
if exists("b:delimitMate_expand_space") && type(b:delimitMate_expand_space) == type("")
|
||||
echom "b:delimitMate_expand_space is '".b:delimitMate_expand_space."' but it must be either 1 or 0!"
|
||||
echom "Read :help 'delimitMate_expand_space' for more details."
|
||||
unlet b:delimitMate_expand_space
|
||||
let b:delimitMate_expand_space = 1
|
||||
endif
|
||||
if exists("g:delimitMate_expand_space") && type(g:delimitMate_expand_space) == type("")
|
||||
echom "delimitMate_expand_space is '".g:delimitMate_expand_space."' but it must be either 1 or 0!"
|
||||
echom "Read :help 'delimitMate_expand_space' for more details."
|
||||
unlet g:delimitMate_expand_space
|
||||
let g:delimitMate_expand_space = 1
|
||||
endif
|
||||
call s:option_init("expand_space", 0)
|
||||
|
||||
" expand_cr
|
||||
if exists("b:delimitMate_expand_cr") && type(b:delimitMate_expand_cr) == type("")
|
||||
echom "b:delimitMate_expand_cr is '".b:delimitMate_expand_cr."' but it must be either 1 or 0!"
|
||||
echom "Read :help 'delimitMate_expand_cr' for more details."
|
||||
unlet b:delimitMate_expand_cr
|
||||
let b:delimitMate_expand_cr = 1
|
||||
endif
|
||||
if exists("g:delimitMate_expand_cr") && type(g:delimitMate_expand_cr) == type("")
|
||||
echom "delimitMate_expand_cr is '".g:delimitMate_expand_cr."' but it must be either 1 or 0!"
|
||||
echom "Read :help 'delimitMate_expand_cr' for more details."
|
||||
unlet g:delimitMate_expand_cr
|
||||
let g:delimitMate_expand_cr = 1
|
||||
endif
|
||||
if ((&backspace !~ 'eol' || &backspace !~ 'start') && &backspace != 2) &&
|
||||
\ ((exists('b:delimitMate_expand_cr') && b:delimitMate_expand_cr == 1) ||
|
||||
\ (exists('g:delimitMate_expand_cr') && g:delimitMate_expand_cr == 1))
|
||||
echom "delimitMate: There seems to be some incompatibility with your settings that may interfer with the expansion of <CR>. See :help 'delimitMate_expand_cr' for details."
|
||||
endif
|
||||
call s:option_init("expand_cr", 0)
|
||||
|
||||
" smart_matchpairs
|
||||
call s:option_init("smart_matchpairs", '^\%(\w\|\!\|£\|\$\|_\|["'']\s*\S\)')
|
||||
|
||||
" smart_quotes
|
||||
call s:option_init("smart_quotes", 1)
|
||||
|
||||
" apostrophes
|
||||
call s:option_init("apostrophes", "")
|
||||
call s:option_init("apostrophes_list", split(b:_l_delimitMate_apostrophes, ":\s*"))
|
||||
|
||||
" tab2exit
|
||||
call s:option_init("tab2exit", 1)
|
||||
|
||||
" balance_matchpairs
|
||||
call s:option_init("balance_matchpairs", 0)
|
||||
|
||||
let b:_l_delimitMate_buffer = []
|
||||
|
||||
endfunction "}}} Init()
|
||||
|
||||
"}}}
|
||||
|
||||
" Functions: {{{
|
||||
|
||||
function! s:Map() "{{{
|
||||
" Set mappings:
|
||||
try
|
||||
let save_cpo = &cpo
|
||||
let save_keymap = &keymap
|
||||
let save_iminsert = &iminsert
|
||||
let save_imsearch = &imsearch
|
||||
set keymap=
|
||||
set cpo&vim
|
||||
if b:_l_delimitMate_autoclose
|
||||
call s:AutoClose()
|
||||
else
|
||||
call s:NoAutoClose()
|
||||
endif
|
||||
call s:ExtraMappings()
|
||||
finally
|
||||
let &cpo = save_cpo
|
||||
let &keymap = save_keymap
|
||||
let &iminsert = save_iminsert
|
||||
let &imsearch = save_imsearch
|
||||
endtry
|
||||
|
||||
let b:delimitMate_enabled = 1
|
||||
|
||||
endfunction "}}} Map()
|
||||
|
||||
function! s:Unmap() " {{{
|
||||
let imaps =
|
||||
\ b:_l_delimitMate_right_delims +
|
||||
\ b:_l_delimitMate_left_delims +
|
||||
\ b:_l_delimitMate_quotes_list +
|
||||
\ b:_l_delimitMate_apostrophes_list +
|
||||
\ ['<BS>', '<S-BS>', '<Del>', '<CR>', '<Space>', '<S-Tab>', '<Esc>'] +
|
||||
\ ['<Up>', '<Down>', '<Left>', '<Right>', '<LeftMouse>', '<RightMouse>'] +
|
||||
\ ['<Home>', '<End>', '<PageUp>', '<PageDown>', '<S-Down>', '<S-Up>', '<C-G>g']
|
||||
|
||||
for map in imaps
|
||||
if maparg(map, "i") =~? 'delimitMate'
|
||||
if map == '|'
|
||||
let map = '<Bar>'
|
||||
endif
|
||||
exec 'silent! iunmap <buffer> ' . map
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !has('gui_running')
|
||||
silent! iunmap <C-[>OC
|
||||
endif
|
||||
|
||||
let b:delimitMate_enabled = 0
|
||||
endfunction " }}} s:Unmap()
|
||||
|
||||
function! s:TestMappingsDo() "{{{
|
||||
%d
|
||||
if !exists("g:delimitMate_testing")
|
||||
silent call delimitMate#TestMappings()
|
||||
else
|
||||
let temp_varsDM = [b:_l_delimitMate_expand_space, b:_l_delimitMate_expand_cr, b:_l_delimitMate_autoclose]
|
||||
for i in [0,1]
|
||||
let b:delimitMate_expand_space = i
|
||||
let b:delimitMate_expand_cr = i
|
||||
for a in [0,1]
|
||||
let b:delimitMate_autoclose = a
|
||||
call s:init()
|
||||
call s:Unmap()
|
||||
call s:Map()
|
||||
call delimitMate#TestMappings()
|
||||
call append(line('$'),'')
|
||||
endfor
|
||||
endfor
|
||||
let b:delimitMate_expand_space = temp_varsDM[0]
|
||||
let b:delimitMate_expand_cr = temp_varsDM[1]
|
||||
let b:delimitMate_autoclose = temp_varsDM[2]
|
||||
unlet temp_varsDM
|
||||
endif
|
||||
normal gg
|
||||
g/\%^$/d
|
||||
endfunction "}}}
|
||||
|
||||
function! s:DelimitMateDo(...) "{{{
|
||||
|
||||
" First, remove all magic, if needed:
|
||||
if exists("b:delimitMate_enabled") && b:delimitMate_enabled == 1
|
||||
call s:Unmap()
|
||||
endif
|
||||
|
||||
" Check if this file type is excluded:
|
||||
if exists("g:delimitMate_excluded_ft") &&
|
||||
\ index(split(g:delimitMate_excluded_ft, ','), &filetype, 0, 1) >= 0
|
||||
|
||||
" Finish here:
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Check if user tried to disable using b:loaded_delimitMate
|
||||
if exists("b:loaded_delimitMate")
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Initialize settings:
|
||||
call s:init()
|
||||
|
||||
" Now, add magic:
|
||||
call s:Map()
|
||||
|
||||
if a:0 > 0
|
||||
echo "delimitMate has been reset."
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! s:DelimitMateSwitch() "{{{
|
||||
if exists("b:delimitMate_enabled") && b:delimitMate_enabled
|
||||
call s:Unmap()
|
||||
echo "delimitMate has been disabled."
|
||||
else
|
||||
call s:Unmap()
|
||||
call s:init()
|
||||
call s:Map()
|
||||
echo "delimitMate has been enabled."
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! s:Finish() " {{{
|
||||
if exists('g:delimitMate_loaded')
|
||||
return delimitMate#Finish(1)
|
||||
endif
|
||||
return ''
|
||||
endfunction " }}}
|
||||
|
||||
function! s:FlushBuffer() " {{{
|
||||
if exists('g:delimitMate_loaded')
|
||||
return delimitMate#FlushBuffer()
|
||||
endif
|
||||
return ''
|
||||
endfunction " }}}
|
||||
|
||||
"}}}
|
||||
|
||||
" Mappers: {{{
|
||||
function! s:NoAutoClose() "{{{
|
||||
" inoremap <buffer> ) <C-R>=delimitMate#SkipDelim('\)')<CR>
|
||||
for delim in b:_l_delimitMate_right_delims + b:_l_delimitMate_quotes_list
|
||||
if delim == '|'
|
||||
let delim = '<Bar>'
|
||||
endif
|
||||
exec 'inoremap <silent> <Plug>delimitMate' . delim . ' <C-R>=delimitMate#SkipDelim("' . escape(delim,'"') . '")<CR>'
|
||||
exec 'silent! imap <unique> <buffer> '.delim.' <Plug>delimitMate'.delim
|
||||
endfor
|
||||
endfunction "}}}
|
||||
|
||||
function! s:AutoClose() "{{{
|
||||
" Add matching pair and jump to the midle:
|
||||
" inoremap <silent> <buffer> ( ()<Left>
|
||||
let i = 0
|
||||
while i < len(b:_l_delimitMate_matchpairs_list)
|
||||
let ld = b:_l_delimitMate_left_delims[i] == '|' ? '<bar>' : b:_l_delimitMate_left_delims[i]
|
||||
let rd = b:_l_delimitMate_right_delims[i] == '|' ? '<bar>' : b:_l_delimitMate_right_delims[i]
|
||||
exec 'inoremap <silent> <Plug>delimitMate' . ld . ' ' . ld . '<C-R>=delimitMate#ParenDelim("' . escape(rd, '|') . '")<CR>'
|
||||
exec 'silent! imap <unique> <buffer> '.ld.' <Plug>delimitMate'.ld
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
" Exit from inside the matching pair:
|
||||
for delim in b:_l_delimitMate_right_delims
|
||||
exec 'inoremap <silent> <Plug>delimitMate' . delim . ' <C-R>=delimitMate#JumpOut("\' . delim . '")<CR>'
|
||||
exec 'silent! imap <unique> <buffer> ' . delim . ' <Plug>delimitMate'. delim
|
||||
endfor
|
||||
|
||||
" Add matching quote and jump to the midle, or exit if inside a pair of matching quotes:
|
||||
" inoremap <silent> <buffer> " <C-R>=delimitMate#QuoteDelim("\"")<CR>
|
||||
for delim in b:_l_delimitMate_quotes_list
|
||||
if delim == '|'
|
||||
let delim = '<Bar>'
|
||||
endif
|
||||
exec 'inoremap <silent> <Plug>delimitMate' . delim . ' <C-R>=delimitMate#QuoteDelim("\' . delim . '")<CR>'
|
||||
exec 'silent! imap <unique> <buffer> ' . delim . ' <Plug>delimitMate' . delim
|
||||
endfor
|
||||
|
||||
" Try to fix the use of apostrophes (kept for backward compatibility):
|
||||
" inoremap <silent> <buffer> n't n't
|
||||
for map in b:_l_delimitMate_apostrophes_list
|
||||
exec "inoremap <silent> " . map . " " . map
|
||||
exec 'silent! imap <unique> <buffer> ' . map . ' <Plug>delimitMate' . map
|
||||
endfor
|
||||
endfunction "}}}
|
||||
|
||||
function! s:ExtraMappings() "{{{
|
||||
" If pair is empty, delete both delimiters:
|
||||
inoremap <silent> <Plug>delimitMateBS <C-R>=delimitMate#BS()<CR>
|
||||
if !hasmapto('<Plug>delimitMateBS','i')
|
||||
silent! imap <unique> <buffer> <BS> <Plug>delimitMateBS
|
||||
endif
|
||||
" If pair is empty, delete closing delimiter:
|
||||
inoremap <silent> <expr> <Plug>delimitMateS-BS delimitMate#WithinEmptyPair() ? "\<C-R>=delimitMate#Del()\<CR>" : "\<S-BS>"
|
||||
if !hasmapto('<Plug>delimitMateS-BS','i')
|
||||
silent! imap <unique> <buffer> <S-BS> <Plug>delimitMateS-BS
|
||||
endif
|
||||
" Expand return if inside an empty pair:
|
||||
inoremap <silent> <Plug>delimitMateCR <C-R>=delimitMate#ExpandReturn()<CR>
|
||||
if b:_l_delimitMate_expand_cr != 0 && !hasmapto('<Plug>delimitMateCR', 'i')
|
||||
silent! imap <unique> <buffer> <CR> <Plug>delimitMateCR
|
||||
endif
|
||||
" Expand space if inside an empty pair:
|
||||
inoremap <silent> <Plug>delimitMateSpace <C-R>=delimitMate#ExpandSpace()<CR>
|
||||
if b:_l_delimitMate_expand_space != 0 && !hasmapto('<Plug>delimitMateSpace', 'i')
|
||||
silent! imap <unique> <buffer> <Space> <Plug>delimitMateSpace
|
||||
endif
|
||||
" Jump over any delimiter:
|
||||
inoremap <silent> <Plug>delimitMateS-Tab <C-R>=delimitMate#JumpAny("\<S-Tab>")<CR>
|
||||
if b:_l_delimitMate_tab2exit && !hasmapto('<Plug>delimitMateS-Tab', 'i')
|
||||
silent! imap <unique> <buffer> <S-Tab> <Plug>delimitMateS-Tab
|
||||
endif
|
||||
" Change char buffer on Del:
|
||||
inoremap <silent> <Plug>delimitMateDel <C-R>=delimitMate#Del()<CR>
|
||||
if !hasmapto('<Plug>delimitMateDel', 'i')
|
||||
silent! imap <unique> <buffer> <Del> <Plug>delimitMateDel
|
||||
endif
|
||||
" Flush the char buffer on movement keystrokes or when leaving insert mode:
|
||||
for map in ['Esc', 'Left', 'Right', 'Home', 'End']
|
||||
exec 'inoremap <silent> <Plug>delimitMate'.map.' <C-R>=<SID>Finish()<CR><'.map.'>'
|
||||
if !hasmapto('<Plug>delimitMate'.map, 'i')
|
||||
exec 'silent! imap <unique> <buffer> <'.map.'> <Plug>delimitMate'.map
|
||||
endif
|
||||
endfor
|
||||
" Except when pop-up menu is active:
|
||||
for map in ['Up', 'Down', 'PageUp', 'PageDown', 'S-Down', 'S-Up']
|
||||
exec 'inoremap <silent> <expr> <Plug>delimitMate'.map.' pumvisible() ? "\<'.map.'>" : "\<C-R>=\<SID>Finish()\<CR>\<'.map.'>"'
|
||||
if !hasmapto('<Plug>delimitMate'.map, 'i')
|
||||
exec 'silent! imap <unique> <buffer> <'.map.'> <Plug>delimitMate'.map
|
||||
endif
|
||||
endfor
|
||||
" Avoid ambiguous mappings:
|
||||
for map in ['LeftMouse', 'RightMouse']
|
||||
exec 'inoremap <silent> <Plug>delimitMateM'.map.' <C-R>=delimitMate#Finish(1)<CR><'.map.'>'
|
||||
if !hasmapto('<Plug>delimitMate'.map, 'i')
|
||||
exec 'silent! imap <unique> <buffer> <'.map.'> <Plug>delimitMateM'.map
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Jump over next delimiters
|
||||
inoremap <buffer> <Plug>delimitMateJumpMany <C-R>=len(b:_l_delimitMate_buffer) ? delimitMate#Finish(0) : delimitMate#JumpMany()<CR>
|
||||
if !hasmapto('<Plug>delimitMateJumpMany')
|
||||
imap <silent> <buffer> <C-G>g <Plug>delimitMateJumpMany
|
||||
endif
|
||||
|
||||
" The following simply creates an ambiguous mapping so vim fully processes
|
||||
" the escape sequence for terminal keys, see 'ttimeout' for a rough
|
||||
" explanation, this just forces it to work
|
||||
if !has('gui_running')
|
||||
imap <silent> <C-[>OC <RIGHT>
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
"}}}
|
||||
|
||||
" Commands: {{{
|
||||
|
||||
call s:DelimitMateDo()
|
||||
|
||||
" Let me refresh without re-loading the buffer:
|
||||
command! -bar DelimitMateReload call s:DelimitMateDo(1)
|
||||
|
||||
" Quick test:
|
||||
command! -bar DelimitMateTest silent call s:TestMappingsDo()
|
||||
|
||||
" Switch On/Off:
|
||||
command! -bar DelimitMateSwitch call s:DelimitMateSwitch()
|
||||
"}}}
|
||||
|
||||
" Autocommands: {{{
|
||||
|
||||
augroup delimitMate
|
||||
au!
|
||||
" Run on file type change.
|
||||
"autocmd VimEnter * autocmd FileType * call <SID>DelimitMateDo()
|
||||
autocmd FileType * call <SID>DelimitMateDo()
|
||||
|
||||
" Run on new buffers.
|
||||
autocmd BufNewFile,BufRead,BufEnter *
|
||||
\ if !exists('b:delimitMate_was_here') |
|
||||
\ call <SID>DelimitMateDo() |
|
||||
\ let b:delimitMate_was_here = 1 |
|
||||
\ endif
|
||||
|
||||
" Flush the char buffer:
|
||||
autocmd InsertEnter * call <SID>FlushBuffer()
|
||||
autocmd BufEnter *
|
||||
\ if mode() == 'i' |
|
||||
\ call <SID>FlushBuffer() |
|
||||
\ endif
|
||||
|
||||
augroup END
|
||||
|
||||
"}}}
|
||||
|
||||
" GetLatestVimScripts: 2754 1 :AutoInstall: delimitMate.vim
|
||||
" vim:foldmethod=marker:foldcolumn=4
|
||||
132
vim/plugin/endwise.vim
Normal file
132
vim/plugin/endwise.vim
Normal file
@@ -0,0 +1,132 @@
|
||||
" endwise.vim - EndWise
|
||||
" Author: Tim Pope <vimNOSPAM@tpope.info>
|
||||
" Version: 1.0
|
||||
|
||||
" Distributable under the same terms as Vim itself (see :help license)
|
||||
|
||||
" Exit quickly when:
|
||||
" - this plugin was already loaded (or disabled)
|
||||
" - when 'compatible' is set
|
||||
if (exists("g:loaded_endwise") && g:loaded_endwise) || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_endwise = 1
|
||||
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
augroup endwise " {{{1
|
||||
au!
|
||||
autocmd FileType ruby
|
||||
\ let b:endwise_addition = '\=submatch(0)=="{" ? "}" : "end"' |
|
||||
\ let b:endwise_words = 'module,class,def,if,unless,case,while,until,begin,do' |
|
||||
\ let b:endwise_pattern = '^\s*\zs\%(module\|class\|def\|if\|unless\|case\|while\|until\|for\|\|begin\)\>\%(.*[^.:@$]\<end\>\)\@!\|\<do\ze\%(\s*|.*|\)\=\s*$' |
|
||||
\ let b:endwise_syngroups = 'rubyModule,rubyClass,rubyDefine,rubyControl,rubyConditional,rubyRepeat'
|
||||
autocmd FileType vb,vbnet,aspvbs
|
||||
\ let b:endwise_addition = 'End &' |
|
||||
\ let b:endwise_words = 'Function,Sub,Class,Module,Enum,Namespace' |
|
||||
\ let b:endwise_pattern = '\%(\<End\>.*\)\@<!\<&\>' |
|
||||
\ let b:endwise_syngroups = 'vbStatement,vbnetStorage,vbnetProcedure,vbnet.*Words,AspVBSStatement'
|
||||
autocmd FileType vim
|
||||
\ let b:endwise_addition = 'end&' |
|
||||
\ let b:endwise_words = 'fu\%[nction],wh\%[ile],if,for,try' |
|
||||
\ let b:endwise_syngroups = 'vimFuncKey,vimNotFunc,vimCommand'
|
||||
augroup END " }}}1
|
||||
|
||||
" Maps {{{1
|
||||
|
||||
|
||||
if maparg("<Plug>DiscretionaryEnd") == ""
|
||||
inoremap <silent> <SID>DiscretionaryEnd <C-R>=<SID>crend(0)<CR>
|
||||
inoremap <silent> <SID>AlwaysEnd <C-R>=<SID>crend(1)<CR>
|
||||
imap <script> <Plug>DiscretionaryEnd <SID>DiscretionaryEnd
|
||||
imap <script> <Plug>AlwaysEnd <SID>AlwaysEnd
|
||||
endif
|
||||
if maparg('<CR>','i') =~# '<C-R>=.*crend(.)<CR>\|<\%(Plug\|SID\)>.*End'
|
||||
" Already mapped
|
||||
elseif maparg('<CR>','i') =~ '<CR>'
|
||||
exe "imap <script> <C-X><CR> ".maparg('<CR>','i')."<SID>AlwaysEnd"
|
||||
exe "imap <script> <CR> ".maparg('<CR>','i')."<SID>DiscretionaryEnd"
|
||||
else
|
||||
imap <C-X><CR> <CR><Plug>AlwaysEnd
|
||||
imap <CR> <CR><Plug>DiscretionaryEnd
|
||||
endif
|
||||
|
||||
if maparg('<M-o>','i') == ''
|
||||
inoremap <M-o> <C-O>o
|
||||
endif
|
||||
|
||||
" }}}1
|
||||
|
||||
" Code {{{1
|
||||
|
||||
function! s:mysearchpair(beginpat,endpat,synpat)
|
||||
let g:endwise_syntaxes = ""
|
||||
let s:lastline = line('.')
|
||||
call s:synname()
|
||||
let line = searchpair(a:beginpat,'',a:endpat,'Wn','<SID>synname() !~# "^'.substitute(a:synpat,'\\','\\\\','g').'$"',line('.')+50)
|
||||
return line
|
||||
endfunction
|
||||
|
||||
function! s:crend(always)
|
||||
let n = ""
|
||||
if !exists("b:endwise_addition") || !exists("b:endwise_words") || !exists("b:endwise_syngroups")
|
||||
return n
|
||||
end
|
||||
let synpat = '\%('.substitute(b:endwise_syngroups,',','\\|','g').'\)'
|
||||
let wordchoice = '\%('.substitute(b:endwise_words,',','\\|','g').'\)'
|
||||
if exists("b:endwise_pattern")
|
||||
let beginpat = substitute(b:endwise_pattern,'&',substitute(wordchoice,'\\','\\&','g'),'g')
|
||||
else
|
||||
let beginpat = '\<'.wordchoice.'\>'
|
||||
endif
|
||||
let lnum = line('.') - 1
|
||||
let space = matchstr(getline(lnum),'^\s*')
|
||||
let col = match(getline(lnum),beginpat) + 1
|
||||
let word = matchstr(getline(lnum),beginpat)
|
||||
let endpat = substitute(word,'.*',b:endwise_addition,'')
|
||||
let y = n.endpat."\<C-O>O"
|
||||
let endpat = '\<'.substitute(wordchoice,'.*',b:endwise_addition,'').'\>'
|
||||
if a:always
|
||||
return y
|
||||
elseif col <= 0 || synIDattr(synID(lnum,col,1),'name') !~ '^'.synpat.'$'
|
||||
return n
|
||||
elseif getline('.') !~ '^\s*#\=$'
|
||||
return n
|
||||
endif
|
||||
let line = s:mysearchpair(beginpat,endpat,synpat)
|
||||
" even is false if no end was found, or if the end found was less
|
||||
" indented than the current line
|
||||
let even = strlen(matchstr(getline(line),'^\s*')) >= strlen(space)
|
||||
if line == 0
|
||||
let even = 0
|
||||
endif
|
||||
let g:endwise_debug = line . "(" . even . ")"
|
||||
if !even && line == line('.') + 1
|
||||
return y
|
||||
endif
|
||||
if even
|
||||
return n
|
||||
endif
|
||||
return y
|
||||
endfunction
|
||||
|
||||
function! s:synname()
|
||||
" Checking this helps to force things to stay in sync
|
||||
while s:lastline < line('.')
|
||||
let s = synIDattr(synID(s:lastline,indent(s:lastline)+1,1),'name')
|
||||
let s:lastline = nextnonblank(s:lastline + 1)
|
||||
endwhile
|
||||
|
||||
let s = synIDattr(synID(line('.'),col('.'),1),'name')
|
||||
let g:endwise_syntaxes = g:endwise_syntaxes . line('.').','.col('.')."=".s."\n"
|
||||
let s:lastline = line('.')
|
||||
return s
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
|
||||
" vim:set ft=vim ff=unix ts=8 sw=4 sts=4:
|
||||
42
vim/plugin/git-grep.vim
Normal file
42
vim/plugin/git-grep.vim
Normal file
@@ -0,0 +1,42 @@
|
||||
let g:gitgrepprg="git\\ grep\\ -n"
|
||||
|
||||
function! GitGrep(args)
|
||||
let grepprg_bak=&grepprg
|
||||
exec "set grepprg=" . g:gitgrepprg
|
||||
execute "silent! grep " . a:args
|
||||
botright copen
|
||||
let &grepprg=grepprg_bak
|
||||
exec "redraw!"
|
||||
endfunction
|
||||
|
||||
function! GitGrepAdd(args)
|
||||
let grepprg_bak=&grepprg
|
||||
exec "set grepprg=" . g:gitgrepprg
|
||||
execute "silent! grepadd " . a:args
|
||||
botright copen
|
||||
let &grepprg=grepprg_bak
|
||||
exec "redraw!"
|
||||
endfunction
|
||||
|
||||
function! LGitGrep(args)
|
||||
let grepprg_bak=&grepprg
|
||||
exec "set grepprg=" . g:gitgrepprg
|
||||
execute "silent! lgrep " . a:args
|
||||
botright lopen
|
||||
let &grepprg=grepprg_bak
|
||||
exec "redraw!"
|
||||
endfunction
|
||||
|
||||
function! LGitGrepAdd(args)
|
||||
let grepprg_bak=&grepprg
|
||||
exec "set grepprg=" . g:gitgrepprg
|
||||
execute "silent! lgrepadd " . a:args
|
||||
botright lopen
|
||||
let &grepprg=grepprg_bak
|
||||
exec "redraw!"
|
||||
endfunction
|
||||
|
||||
command! -nargs=* -complete=file GitGrep call GitGrep(<q-args>)
|
||||
command! -nargs=* -complete=file GitGrepAdd call GitGrepAdd(<q-args>)
|
||||
command! -nargs=* -complete=file LGitGrep call LGitGrep(<q-args>)
|
||||
command! -nargs=* -complete=file LGitGrepAdd call LGitGrepAdd(<q-args>)
|
||||
310
vim/plugin/greplace.vim
Executable file
310
vim/plugin/greplace.vim
Executable file
@@ -0,0 +1,310 @@
|
||||
" File: greplace.vim
|
||||
" Script to search and replace pattern across multiple files
|
||||
" Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
|
||||
" Version: 1.0 Beta1
|
||||
" Last Modified: March 3, 2007
|
||||
"
|
||||
if exists("loaded_greplace")
|
||||
finish
|
||||
endif
|
||||
let loaded_greplace = 1
|
||||
|
||||
" Requires Vim 7.0 and above
|
||||
if v:version < 700
|
||||
finish
|
||||
endif
|
||||
|
||||
" Line continuation used here
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if &isfname =~ '['
|
||||
let s:gRepl_bufname = '[Global\ Replace]'
|
||||
else
|
||||
let s:gRepl_bufname = '\[Global\ Replace\]'
|
||||
endif
|
||||
|
||||
" Character to use to quote patterns
|
||||
if !exists("Greplace_Shell_Quote_Char")
|
||||
if has("win32") || has("win16") || has("win95")
|
||||
let Greplace_Shell_Quote_Char = ''
|
||||
else
|
||||
let Greplace_Shell_Quote_Char = "'"
|
||||
endif
|
||||
endif
|
||||
|
||||
let s:save_qf_list = {}
|
||||
|
||||
function! s:warn_msg(msg)
|
||||
echohl WarningMsg
|
||||
echomsg a:msg
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
highlight GReplaceText term=reverse cterm=reverse gui=reverse
|
||||
|
||||
function! s:gReplace()
|
||||
if empty(s:save_qf_list)
|
||||
return
|
||||
endif
|
||||
|
||||
let change_all = v:cmdbang
|
||||
|
||||
let changeset = {}
|
||||
|
||||
" Parse the replace buffer contents and get a List of changed lines
|
||||
let lines = getbufline('%', 1, '$')
|
||||
for l in lines
|
||||
if l !~ '[^:]\+:\d\+:.*'
|
||||
continue
|
||||
endif
|
||||
|
||||
let match_l = matchlist(l, '\([^:]\+\):\(\d\+\):\(.*\)')
|
||||
let fname = match_l[1]
|
||||
let lnum = match_l[2]
|
||||
let text = match_l[3]
|
||||
|
||||
let key = fname . ':' . lnum
|
||||
if s:save_qf_list[key].text == text
|
||||
" This line is not changed
|
||||
continue
|
||||
endif
|
||||
|
||||
let fname = s:save_qf_list[key].fname
|
||||
if !has_key(changeset, fname)
|
||||
let changeset[fname] = {}
|
||||
endif
|
||||
|
||||
let changeset[fname][lnum] = text
|
||||
endfor
|
||||
|
||||
if empty(changeset)
|
||||
" The replace buffer is not changed by the user
|
||||
call s:warn_msg('Error: No changes in the replace buffer')
|
||||
return
|
||||
endif
|
||||
|
||||
" Make the changes made by the user to the buffers
|
||||
for f in keys(changeset)
|
||||
let f_l = changeset[f]
|
||||
if !filereadable(f)
|
||||
continue
|
||||
endif
|
||||
silent! exe 'hide edit ' . f
|
||||
|
||||
let change_buf_all = 0 " Accept all the changes in this buffer
|
||||
|
||||
for lnum in keys(f_l)
|
||||
exe lnum
|
||||
|
||||
let cur_ltext = getline(lnum)
|
||||
let new_ltext = f_l[lnum]
|
||||
|
||||
let s_idx =0
|
||||
while cur_ltext[s_idx] == new_ltext[s_idx]
|
||||
let s_idx += 1
|
||||
endwhile
|
||||
|
||||
let e_idx1 = strlen(cur_ltext) - 1
|
||||
let e_idx2 = strlen(new_ltext) - 1
|
||||
while e_idx1 >= 0 && cur_ltext[e_idx1] == new_ltext[e_idx2]
|
||||
let e_idx1 -= 1
|
||||
let e_idx2 -= 1
|
||||
endwhile
|
||||
|
||||
let e_idx1 += 2
|
||||
|
||||
if (s_idx + 1) == e_idx1
|
||||
" If there is nothing to highlight, then highlight the
|
||||
" last character
|
||||
let e_idx1 += 1
|
||||
endif
|
||||
|
||||
let hl_pat = '/\%'.lnum.'l\%>'.s_idx.'v.*\%<'.e_idx1.'v/'
|
||||
exe '2match GReplaceText ' . hl_pat
|
||||
redraw!
|
||||
|
||||
try
|
||||
let change_line = 0
|
||||
|
||||
if !change_all && !change_buf_all
|
||||
let new_text_frag = strpart(new_ltext, s_idx,
|
||||
\ e_idx2 - s_idx + 1)
|
||||
|
||||
echo "Replace with '" . new_text_frag . "' (y/n/a/b/q)?"
|
||||
let ans = 'x'
|
||||
while ans !~? '[ynab]'
|
||||
let ans = nr2char(getchar())
|
||||
if ans == 'q' || ans == "\<Esc>" " Quit
|
||||
return
|
||||
endif
|
||||
endwhile
|
||||
if ans == 'a' " Accept all
|
||||
let change_all = 1
|
||||
endif
|
||||
if ans == 'b' " Accept changes in the current buffer
|
||||
let change_buf_all = 1
|
||||
endif
|
||||
if ans == 'y' " Yes
|
||||
let change_line = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
if change_all || change_buf_all || change_line
|
||||
call setline(lnum, f_l[lnum])
|
||||
endif
|
||||
finally
|
||||
2match none
|
||||
endtry
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:gReplace_show_matches()
|
||||
let qf = getqflist()
|
||||
if empty(qf)
|
||||
call s:warn_msg('Error: Quickfix list is empty')
|
||||
return
|
||||
endif
|
||||
|
||||
let new_qf = {}
|
||||
|
||||
" Populate the buffer with the current quickfix list
|
||||
let lines = []
|
||||
for l in qf
|
||||
if l.valid && l.lnum > 0 && l.bufnr > 0
|
||||
let fname = fnamemodify(bufname(l.bufnr), ':.')
|
||||
let buf_text = fname . ':' . l.lnum . ':' . l.text
|
||||
let k = fname . ':' . l.lnum
|
||||
let new_qf[k] = {}
|
||||
let new_qf[k].fname = fnamemodify(bufname(l.bufnr), ':p')
|
||||
let new_qf[k].text = l.text
|
||||
else
|
||||
let buf_text = l.text
|
||||
endif
|
||||
|
||||
call add(lines, buf_text)
|
||||
endfor
|
||||
|
||||
if empty(lines)
|
||||
" No valid matching lines
|
||||
return
|
||||
endif
|
||||
|
||||
let w = bufwinnr(s:gRepl_bufname)
|
||||
if w == -1
|
||||
" Create a new window
|
||||
silent! exe 'new ' . s:gRepl_bufname
|
||||
else
|
||||
exe w . 'wincmd w'
|
||||
|
||||
" Discard the contents of the buffer
|
||||
%d _
|
||||
endif
|
||||
|
||||
call append(0, '#')
|
||||
call append(1, '# Modify the contents of this buffer and then')
|
||||
call append(2, '# use the ":Greplace" command to merge the changes.')
|
||||
call append(3, '#')
|
||||
call append(4, lines)
|
||||
|
||||
call cursor(5, 1)
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=wipe
|
||||
setlocal nomodified
|
||||
|
||||
command! -buffer -nargs=0 -bang Greplace call s:gReplace()
|
||||
|
||||
let s:save_qf_list = new_qf
|
||||
endfunction
|
||||
|
||||
" gSearch
|
||||
" Search for a pattern in a group of files using ':grep'
|
||||
function! s:gSearch(type, ...)
|
||||
let grep_opt = '-r'
|
||||
let pattern = ''
|
||||
let filenames = ''
|
||||
|
||||
" Parse the arguments
|
||||
" grep command-line flags are specified using the "-flag" format
|
||||
" the next argument is assumed to be the pattern
|
||||
" and the next arguments are assumed to be filenames or file patterns
|
||||
let argcnt = 1
|
||||
while argcnt <= a:0
|
||||
if &grepprg =~ 'findstr' && a:{argcnt} =~ '^/'
|
||||
let grep_opt = grep_opt . ' ' . a:{argcnt}
|
||||
elseif a:{argcnt} =~ '^-'
|
||||
let grep_opt = grep_opt . ' ' . a:{argcnt}
|
||||
elseif pattern == ''
|
||||
let pattern = a:{argcnt}
|
||||
else
|
||||
let filenames = filenames . ' ' . a:{argcnt}
|
||||
endif
|
||||
let argcnt += 1
|
||||
endwhile
|
||||
|
||||
" If search pattern is not specified on command-line, ask for it
|
||||
if pattern == ''
|
||||
let pattern = input('Search pattern: ', expand('<cword>'))
|
||||
if pattern == ''
|
||||
return
|
||||
endif
|
||||
|
||||
" Quote the supplied pattern
|
||||
let pattern = g:Greplace_Shell_Quote_Char . pattern .
|
||||
\ g:Greplace_Shell_Quote_Char
|
||||
endif
|
||||
|
||||
if a:type == 'grep'
|
||||
if filenames == ''
|
||||
let filenames = input('Search in files: ', '*', 'file')
|
||||
endif
|
||||
elseif a:type == 'args'
|
||||
" Search in all the filenames in the argument list
|
||||
let arg_cnt = argc()
|
||||
|
||||
if arg_cnt == 0
|
||||
call s:warn_msg('Error: Argument list is empty')
|
||||
return
|
||||
endif
|
||||
|
||||
let filenames = ''
|
||||
for i in range(0, arg_cnt - 1)
|
||||
let filenames .= ' ' . argv(i)
|
||||
endfor
|
||||
else
|
||||
" Get a list of all the buffer names
|
||||
let filenames = ''
|
||||
for i in range(1, bufnr('$'))
|
||||
let bname = bufname(i)
|
||||
if bufexists(i) && buflisted(i) && filereadable(bname) &&
|
||||
\ getbufvar(i, '&buftype') == ''
|
||||
let filenames .= ' ' . bufname(i)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if filenames == ''
|
||||
call s:warn_msg('Error: No valid file names')
|
||||
return
|
||||
endif
|
||||
|
||||
" Use ! after grep, so that Vim doesn't automatically jump to the
|
||||
" first match
|
||||
let grep_cmd = 'grep! ' . grep_opt . ' ' . pattern . ' ' . filenames
|
||||
|
||||
" Run the grep and get the matches
|
||||
silent! exe grep_cmd
|
||||
|
||||
call s:gReplace_show_matches()
|
||||
endfunction
|
||||
|
||||
command! -nargs=0 Gqfopen call s:gReplace_show_matches()
|
||||
command! -nargs=* -complete=file Gsearch call s:gSearch('grep', <f-args>)
|
||||
command! -nargs=* Gargsearch call s:gSearch('args', <f-args>)
|
||||
command! -nargs=* Gbuffersearch call s:gSearch('buffer', <f-args>)
|
||||
|
||||
" restore 'cpo'
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
2377
vim/plugin/lusty-explorer.vim
Executable file
2377
vim/plugin/lusty-explorer.vim
Executable file
File diff suppressed because it is too large
Load Diff
1143
vim/plugin/lusty-juggler.vim
Normal file
1143
vim/plugin/lusty-juggler.vim
Normal file
File diff suppressed because it is too large
Load Diff
44
vim/plugin/markdown-preview.css
Executable file
44
vim/plugin/markdown-preview.css
Executable file
@@ -0,0 +1,44 @@
|
||||
body div#content {
|
||||
margin : 0 auto;
|
||||
width : 920px;
|
||||
background-color : #f8f8f8;
|
||||
padding : .7em;
|
||||
font-size : 13.34px;
|
||||
font-family : verdana, sans-serif;
|
||||
border : 1px #E0E0E0 solid;
|
||||
}
|
||||
|
||||
body div#content h2, body div#content h3, body div#content h4 {
|
||||
padding-top : 10px;
|
||||
border-top : 4px solid #E0E0E0;
|
||||
}
|
||||
|
||||
body div#content pre {
|
||||
padding : 5px;
|
||||
border-style : solid;
|
||||
border-width : 1px;
|
||||
border-color : #E0E0E0;
|
||||
background-color : #F8F8FF;
|
||||
}
|
||||
|
||||
body div#content pre code {
|
||||
padding : 5px;
|
||||
background-color : #F8F8FF;
|
||||
border : none;
|
||||
}
|
||||
|
||||
body div#content code {
|
||||
font-family : courier, fixed;
|
||||
display : inline-block;
|
||||
padding : 0px 2px 0px 2px;
|
||||
background-color : #F8F8FF;
|
||||
border : 1px #E0E0E0 solid;
|
||||
}
|
||||
|
||||
body h4#title {
|
||||
font-family : verdana, sans-serif;
|
||||
display : block;
|
||||
margin : 0 auto;
|
||||
width : 920px;
|
||||
}
|
||||
|
||||
812
vim/plugin/matchit.vim
Executable file
812
vim/plugin/matchit.vim
Executable file
@@ -0,0 +1,812 @@
|
||||
" matchit.vim: (global plugin) Extended "%" matching
|
||||
" Last Change: Fri Jan 25 10:00 AM 2008 EST
|
||||
" Maintainer: Benji Fisher PhD <benji@member.AMS.org>
|
||||
" Version: 1.13.2, for Vim 6.3+
|
||||
" URL: http://www.vim.org/script.php?script_id=39
|
||||
|
||||
" Documentation:
|
||||
" The documentation is in a separate file, matchit.txt .
|
||||
|
||||
" Credits:
|
||||
" Vim editor by Bram Moolenaar (Thanks, Bram!)
|
||||
" Original script and design by Raul Segura Acevedo
|
||||
" Support for comments by Douglas Potts
|
||||
" Support for back references and other improvements by Benji Fisher
|
||||
" Support for many languages by Johannes Zellner
|
||||
" Suggestions for improvement, bug reports, and support for additional
|
||||
" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
|
||||
" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
|
||||
|
||||
" Debugging:
|
||||
" If you'd like to try the built-in debugging commands...
|
||||
" :MatchDebug to activate debugging for the current buffer
|
||||
" This saves the values of several key script variables as buffer-local
|
||||
" variables. See the MatchDebug() function, below, for details.
|
||||
|
||||
" TODO: I should think about multi-line patterns for b:match_words.
|
||||
" This would require an option: how many lines to scan (default 1).
|
||||
" This would be useful for Python, maybe also for *ML.
|
||||
" TODO: Maybe I should add a menu so that people will actually use some of
|
||||
" the features that I have implemented.
|
||||
" TODO: Eliminate the MultiMatch function. Add yet another argument to
|
||||
" Match_wrapper() instead.
|
||||
" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
|
||||
" TODO: Make backrefs safer by using '\V' (very no-magic).
|
||||
" TODO: Add a level of indirection, so that custom % scripts can use my
|
||||
" work but extend it.
|
||||
|
||||
" allow user to prevent loading
|
||||
" and prevent duplicate loading
|
||||
if exists("loaded_matchit") || &cp
|
||||
finish
|
||||
endif
|
||||
let loaded_matchit = 1
|
||||
let s:last_mps = ""
|
||||
let s:last_words = ":"
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
nnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'n') <CR>
|
||||
nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR>
|
||||
vnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv``
|
||||
vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv``
|
||||
onoremap <silent> % v:<C-U>call <SID>Match_wrapper('',1,'o') <CR>
|
||||
onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR>
|
||||
|
||||
" Analogues of [{ and ]} using matching patterns:
|
||||
nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR>
|
||||
nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "n") <CR>
|
||||
vmap [% <Esc>[%m'gv``
|
||||
vmap ]% <Esc>]%m'gv``
|
||||
" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv``
|
||||
" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "v") <CR>m'gv``
|
||||
onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR>
|
||||
onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W", "o") <CR>
|
||||
|
||||
" text object:
|
||||
vmap a% <Esc>[%v]%
|
||||
|
||||
" Auto-complete mappings: (not yet "ready for prime time")
|
||||
" TODO Read :help write-plugin for the "right" way to let the user
|
||||
" specify a key binding.
|
||||
" let g:match_auto = '<C-]>'
|
||||
" let g:match_autoCR = '<C-CR>'
|
||||
" if exists("g:match_auto")
|
||||
" execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
|
||||
" endif
|
||||
" if exists("g:match_autoCR")
|
||||
" execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
|
||||
" endif
|
||||
" if exists("g:match_gthhoh")
|
||||
" execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
|
||||
" endif " gthhoh = "Get the heck out of here!"
|
||||
|
||||
let s:notslash = '\\\@<!\%(\\\\\)*'
|
||||
|
||||
function! s:Match_wrapper(word, forward, mode) range
|
||||
" In s:CleanUp(), :execute "set" restore_options .
|
||||
let restore_options = (&ic ? " " : " no") . "ignorecase"
|
||||
if exists("b:match_ignorecase")
|
||||
let &ignorecase = b:match_ignorecase
|
||||
endif
|
||||
let restore_options = " ve=" . &ve . restore_options
|
||||
set ve=
|
||||
" If this function was called from Visual mode, make sure that the cursor
|
||||
" is at the correct end of the Visual range:
|
||||
if a:mode == "v"
|
||||
execute "normal! gv\<Esc>"
|
||||
endif
|
||||
" In s:CleanUp(), we may need to check whether the cursor moved forward.
|
||||
let startline = line(".")
|
||||
let startcol = col(".")
|
||||
" Use default behavior if called with a count.
|
||||
if v:count
|
||||
exe "normal! " . v:count . "%"
|
||||
return s:CleanUp(restore_options, a:mode, startline, startcol)
|
||||
end
|
||||
|
||||
" First step: if not already done, set the script variables
|
||||
" s:do_BR flag for whether there are backrefs
|
||||
" s:pat parsed version of b:match_words
|
||||
" s:all regexp based on s:pat and the default groups
|
||||
"
|
||||
if !exists("b:match_words") || b:match_words == ""
|
||||
let match_words = ""
|
||||
" Allow b:match_words = "GetVimMatchWords()" .
|
||||
elseif b:match_words =~ ":"
|
||||
let match_words = b:match_words
|
||||
else
|
||||
execute "let match_words =" b:match_words
|
||||
endif
|
||||
" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion!
|
||||
if (match_words != s:last_words) || (&mps != s:last_mps) ||
|
||||
\ exists("b:match_debug")
|
||||
let s:last_words = match_words
|
||||
let s:last_mps = &mps
|
||||
" The next several lines were here before
|
||||
" BF started messing with this script.
|
||||
" quote the special chars in 'matchpairs', replace [,:] with \| and then
|
||||
" append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif)
|
||||
" let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+',
|
||||
" \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>'
|
||||
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
|
||||
\ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>'
|
||||
" s:all = pattern with all the keywords
|
||||
let match_words = match_words . (strlen(match_words) ? "," : "") . default
|
||||
if match_words !~ s:notslash . '\\\d'
|
||||
let s:do_BR = 0
|
||||
let s:pat = match_words
|
||||
else
|
||||
let s:do_BR = 1
|
||||
let s:pat = s:ParseWords(match_words)
|
||||
endif
|
||||
let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
|
||||
let s:all = '\%(' . s:all . '\)'
|
||||
" let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)'
|
||||
if exists("b:match_debug")
|
||||
let b:match_pat = s:pat
|
||||
endif
|
||||
endif
|
||||
|
||||
" Second step: set the following local variables:
|
||||
" matchline = line on which the cursor started
|
||||
" curcol = number of characters before match
|
||||
" prefix = regexp for start of line to start of match
|
||||
" suffix = regexp for end of match to end of line
|
||||
" Require match to end on or after the cursor and prefer it to
|
||||
" start on or before the cursor.
|
||||
let matchline = getline(startline)
|
||||
if a:word != ''
|
||||
" word given
|
||||
if a:word !~ s:all
|
||||
echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
|
||||
return s:CleanUp(restore_options, a:mode, startline, startcol)
|
||||
endif
|
||||
let matchline = a:word
|
||||
let curcol = 0
|
||||
let prefix = '^\%('
|
||||
let suffix = '\)$'
|
||||
" Now the case when "word" is not given
|
||||
else " Find the match that ends on or after the cursor and set curcol.
|
||||
let regexp = s:Wholematch(matchline, s:all, startcol-1)
|
||||
let curcol = match(matchline, regexp)
|
||||
" If there is no match, give up.
|
||||
if curcol == -1
|
||||
return s:CleanUp(restore_options, a:mode, startline, startcol)
|
||||
endif
|
||||
let endcol = matchend(matchline, regexp)
|
||||
let suf = strlen(matchline) - endcol
|
||||
let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(')
|
||||
let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$')
|
||||
endif
|
||||
if exists("b:match_debug")
|
||||
let b:match_match = matchstr(matchline, regexp)
|
||||
let b:match_col = curcol+1
|
||||
endif
|
||||
|
||||
" Third step: Find the group and single word that match, and the original
|
||||
" (backref) versions of these. Then, resolve the backrefs.
|
||||
" Set the following local variable:
|
||||
" group = colon-separated list of patterns, one of which matches
|
||||
" = ini:mid:fin or ini:fin
|
||||
"
|
||||
" Reconstruct the version with unresolved backrefs.
|
||||
let patBR = substitute(match_words.',',
|
||||
\ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
|
||||
let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g')
|
||||
" Now, set group and groupBR to the matching group: 'if:endif' or
|
||||
" 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns
|
||||
" group . "," . groupBR, and we pick it apart.
|
||||
let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
|
||||
let i = matchend(group, s:notslash . ",")
|
||||
let groupBR = strpart(group, i)
|
||||
let group = strpart(group, 0, i-1)
|
||||
" Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
|
||||
if s:do_BR " Do the hard part: resolve those backrefs!
|
||||
let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
|
||||
endif
|
||||
if exists("b:match_debug")
|
||||
let b:match_wholeBR = groupBR
|
||||
let i = matchend(groupBR, s:notslash . ":")
|
||||
let b:match_iniBR = strpart(groupBR, 0, i-1)
|
||||
endif
|
||||
|
||||
" Fourth step: Set the arguments for searchpair().
|
||||
let i = matchend(group, s:notslash . ":")
|
||||
let j = matchend(group, '.*' . s:notslash . ":")
|
||||
let ini = strpart(group, 0, i-1)
|
||||
let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
|
||||
let fin = strpart(group, j)
|
||||
"Un-escape the remaining , and : characters.
|
||||
let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
|
||||
let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
|
||||
let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
|
||||
" searchpair() requires that these patterns avoid \(\) groups.
|
||||
let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
|
||||
let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
|
||||
let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
|
||||
" Set mid. This is optimized for readability, not micro-efficiency!
|
||||
if a:forward && matchline =~ prefix . fin . suffix
|
||||
\ || !a:forward && matchline =~ prefix . ini . suffix
|
||||
let mid = ""
|
||||
endif
|
||||
" Set flag. This is optimized for readability, not micro-efficiency!
|
||||
if a:forward && matchline =~ prefix . fin . suffix
|
||||
\ || !a:forward && matchline !~ prefix . ini . suffix
|
||||
let flag = "bW"
|
||||
else
|
||||
let flag = "W"
|
||||
endif
|
||||
" Set skip.
|
||||
if exists("b:match_skip")
|
||||
let skip = b:match_skip
|
||||
elseif exists("b:match_comment") " backwards compatibility and testing!
|
||||
let skip = "r:" . b:match_comment
|
||||
else
|
||||
let skip = 's:comment\|string'
|
||||
endif
|
||||
let skip = s:ParseSkip(skip)
|
||||
if exists("b:match_debug")
|
||||
let b:match_ini = ini
|
||||
let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
|
||||
endif
|
||||
|
||||
" Fifth step: actually start moving the cursor and call searchpair().
|
||||
" Later, :execute restore_cursor to get to the original screen.
|
||||
let restore_cursor = virtcol(".") . "|"
|
||||
normal! g0
|
||||
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
|
||||
normal! H
|
||||
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
|
||||
execute restore_cursor
|
||||
call cursor(0, curcol + 1)
|
||||
" normal! 0
|
||||
" if curcol
|
||||
" execute "normal!" . curcol . "l"
|
||||
" endif
|
||||
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
|
||||
let skip = "0"
|
||||
else
|
||||
execute "if " . skip . "| let skip = '0' | endif"
|
||||
endif
|
||||
let sp_return = searchpair(ini, mid, fin, flag, skip)
|
||||
let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
|
||||
" Restore cursor position and original screen.
|
||||
execute restore_cursor
|
||||
normal! m'
|
||||
if sp_return > 0
|
||||
execute final_position
|
||||
endif
|
||||
return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin)
|
||||
endfun
|
||||
|
||||
" Restore options and do some special handling for Operator-pending mode.
|
||||
" The optional argument is the tail of the matching group.
|
||||
fun! s:CleanUp(options, mode, startline, startcol, ...)
|
||||
execute "set" a:options
|
||||
" Open folds, if appropriate.
|
||||
if a:mode != "o"
|
||||
if &foldopen =~ "percent"
|
||||
normal! zv
|
||||
endif
|
||||
" In Operator-pending mode, we want to include the whole match
|
||||
" (for example, d%).
|
||||
" This is only a problem if we end up moving in the forward direction.
|
||||
elseif (a:startline < line(".")) ||
|
||||
\ (a:startline == line(".") && a:startcol < col("."))
|
||||
if a:0
|
||||
" Check whether the match is a single character. If not, move to the
|
||||
" end of the match.
|
||||
let matchline = getline(".")
|
||||
let currcol = col(".")
|
||||
let regexp = s:Wholematch(matchline, a:1, currcol-1)
|
||||
let endcol = matchend(matchline, regexp)
|
||||
if endcol > currcol " This is NOT off by one!
|
||||
execute "normal!" . (endcol - currcol) . "l"
|
||||
endif
|
||||
endif " a:0
|
||||
endif " a:mode != "o" && etc.
|
||||
return 0
|
||||
endfun
|
||||
|
||||
" Example (simplified HTML patterns): if
|
||||
" a:groupBR = '<\(\k\+\)>:</\1>'
|
||||
" a:prefix = '^.\{3}\('
|
||||
" a:group = '<\(\k\+\)>:</\(\k\+\)>'
|
||||
" a:suffix = '\).\{2}$'
|
||||
" a:matchline = "123<tag>12" or "123</tag>12"
|
||||
" then extract "tag" from a:matchline and return "<tag>:</tag>" .
|
||||
fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
|
||||
if a:matchline !~ a:prefix .
|
||||
\ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
|
||||
return a:group
|
||||
endif
|
||||
let i = matchend(a:groupBR, s:notslash . ':')
|
||||
let ini = strpart(a:groupBR, 0, i-1)
|
||||
let tailBR = strpart(a:groupBR, i)
|
||||
let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
|
||||
\ a:groupBR)
|
||||
let i = matchend(word, s:notslash . ":")
|
||||
let wordBR = strpart(word, i)
|
||||
let word = strpart(word, 0, i-1)
|
||||
" Now, a:matchline =~ a:prefix . word . a:suffix
|
||||
if wordBR != ini
|
||||
let table = s:Resolve(ini, wordBR, "table")
|
||||
else
|
||||
" let table = "----------"
|
||||
let table = ""
|
||||
let d = 0
|
||||
while d < 10
|
||||
if tailBR =~ s:notslash . '\\' . d
|
||||
" let table[d] = d
|
||||
let table = table . d
|
||||
else
|
||||
let table = table . "-"
|
||||
endif
|
||||
let d = d + 1
|
||||
endwhile
|
||||
endif
|
||||
let d = 9
|
||||
while d
|
||||
if table[d] != "-"
|
||||
let backref = substitute(a:matchline, a:prefix.word.a:suffix,
|
||||
\ '\'.table[d], "")
|
||||
" Are there any other characters that should be escaped?
|
||||
let backref = escape(backref, '*,:')
|
||||
execute s:Ref(ini, d, "start", "len")
|
||||
let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
|
||||
let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
|
||||
\ escape(backref, '\\'), 'g')
|
||||
endif
|
||||
let d = d-1
|
||||
endwhile
|
||||
if exists("b:match_debug")
|
||||
if s:do_BR
|
||||
let b:match_table = table
|
||||
let b:match_word = word
|
||||
else
|
||||
let b:match_table = ""
|
||||
let b:match_word = ""
|
||||
endif
|
||||
endif
|
||||
return ini . ":" . tailBR
|
||||
endfun
|
||||
|
||||
" Input a comma-separated list of groups with backrefs, such as
|
||||
" a:groups = '\(foo\):end\1,\(bar\):end\1'
|
||||
" and return a comma-separated list of groups with backrefs replaced:
|
||||
" return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
|
||||
fun! s:ParseWords(groups)
|
||||
let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
|
||||
let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
|
||||
let parsed = ""
|
||||
while groups =~ '[^,:]'
|
||||
let i = matchend(groups, s:notslash . ':')
|
||||
let j = matchend(groups, s:notslash . ',')
|
||||
let ini = strpart(groups, 0, i-1)
|
||||
let tail = strpart(groups, i, j-i-1) . ":"
|
||||
let groups = strpart(groups, j)
|
||||
let parsed = parsed . ini
|
||||
let i = matchend(tail, s:notslash . ':')
|
||||
while i != -1
|
||||
" In 'if:else:endif', ini='if' and word='else' and then word='endif'.
|
||||
let word = strpart(tail, 0, i-1)
|
||||
let tail = strpart(tail, i)
|
||||
let i = matchend(tail, s:notslash . ':')
|
||||
let parsed = parsed . ":" . s:Resolve(ini, word, "word")
|
||||
endwhile " Now, tail has been used up.
|
||||
let parsed = parsed . ","
|
||||
endwhile " groups =~ '[^,:]'
|
||||
let parsed = substitute(parsed, ',$', '', '')
|
||||
return parsed
|
||||
endfun
|
||||
|
||||
" TODO I think this can be simplified and/or made more efficient.
|
||||
" TODO What should I do if a:start is out of range?
|
||||
" Return a regexp that matches all of a:string, such that
|
||||
" matchstr(a:string, regexp) represents the match for a:pat that starts
|
||||
" as close to a:start as possible, before being preferred to after, and
|
||||
" ends after a:start .
|
||||
" Usage:
|
||||
" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
|
||||
" let i = match(getline("."), regexp)
|
||||
" let j = matchend(getline("."), regexp)
|
||||
" let match = matchstr(getline("."), regexp)
|
||||
fun! s:Wholematch(string, pat, start)
|
||||
let group = '\%(' . a:pat . '\)'
|
||||
let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
|
||||
let len = strlen(a:string)
|
||||
let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
|
||||
if a:string !~ prefix . group . suffix
|
||||
let prefix = ''
|
||||
endif
|
||||
return prefix . group . suffix
|
||||
endfun
|
||||
|
||||
" No extra arguments: s:Ref(string, d) will
|
||||
" find the d'th occurrence of '\(' and return it, along with everything up
|
||||
" to and including the matching '\)'.
|
||||
" One argument: s:Ref(string, d, "start") returns the index of the start
|
||||
" of the d'th '\(' and any other argument returns the length of the group.
|
||||
" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be
|
||||
" executed, having the effect of
|
||||
" :let foo = s:Ref(string, d, "start")
|
||||
" :let bar = s:Ref(string, d, "len")
|
||||
fun! s:Ref(string, d, ...)
|
||||
let len = strlen(a:string)
|
||||
if a:d == 0
|
||||
let start = 0
|
||||
else
|
||||
let cnt = a:d
|
||||
let match = a:string
|
||||
while cnt
|
||||
let cnt = cnt - 1
|
||||
let index = matchend(match, s:notslash . '\\(')
|
||||
if index == -1
|
||||
return ""
|
||||
endif
|
||||
let match = strpart(match, index)
|
||||
endwhile
|
||||
let start = len - strlen(match)
|
||||
if a:0 == 1 && a:1 == "start"
|
||||
return start - 2
|
||||
endif
|
||||
let cnt = 1
|
||||
while cnt
|
||||
let index = matchend(match, s:notslash . '\\(\|\\)') - 1
|
||||
if index == -2
|
||||
return ""
|
||||
endif
|
||||
" Increment if an open, decrement if a ')':
|
||||
let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')'
|
||||
" let cnt = stridx('0(', match[index]) + cnt
|
||||
let match = strpart(match, index+1)
|
||||
endwhile
|
||||
let start = start - 2
|
||||
let len = len - start - strlen(match)
|
||||
endif
|
||||
if a:0 == 1
|
||||
return len
|
||||
elseif a:0 == 2
|
||||
return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
|
||||
else
|
||||
return strpart(a:string, start, len)
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Count the number of disjoint copies of pattern in string.
|
||||
" If the pattern is a literal string and contains no '0' or '1' characters
|
||||
" then s:Count(string, pattern, '0', '1') should be faster than
|
||||
" s:Count(string, pattern).
|
||||
fun! s:Count(string, pattern, ...)
|
||||
let pat = escape(a:pattern, '\\')
|
||||
if a:0 > 1
|
||||
let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
|
||||
let foo = substitute(a:string, pat, a:2, "g")
|
||||
let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
|
||||
return strlen(foo)
|
||||
endif
|
||||
let result = 0
|
||||
let foo = a:string
|
||||
let index = matchend(foo, pat)
|
||||
while index != -1
|
||||
let result = result + 1
|
||||
let foo = strpart(foo, index)
|
||||
let index = matchend(foo, pat)
|
||||
endwhile
|
||||
return result
|
||||
endfun
|
||||
|
||||
" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
|
||||
" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first
|
||||
" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
|
||||
" indicates that all other instances of '\1' in target are to be replaced
|
||||
" by '\3'. The hard part is dealing with nesting...
|
||||
" Note that ":" is an illegal character for source and target,
|
||||
" unless it is preceded by "\".
|
||||
fun! s:Resolve(source, target, output)
|
||||
let word = a:target
|
||||
let i = matchend(word, s:notslash . '\\\d') - 1
|
||||
let table = "----------"
|
||||
while i != -2 " There are back references to be replaced.
|
||||
let d = word[i]
|
||||
let backref = s:Ref(a:source, d)
|
||||
" The idea is to replace '\d' with backref. Before we do this,
|
||||
" replace any \(\) groups in backref with :1, :2, ... if they
|
||||
" correspond to the first, second, ... group already inserted
|
||||
" into backref. Later, replace :1 with \1 and so on. The group
|
||||
" number w+b within backref corresponds to the group number
|
||||
" s within a:source.
|
||||
" w = number of '\(' in word before the current one
|
||||
let w = s:Count(
|
||||
\ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
|
||||
let b = 1 " number of the current '\(' in backref
|
||||
let s = d " number of the current '\(' in a:source
|
||||
while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
|
||||
\ && s < 10
|
||||
if table[s] == "-"
|
||||
if w + b < 10
|
||||
" let table[s] = w + b
|
||||
let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
|
||||
endif
|
||||
let b = b + 1
|
||||
let s = s + 1
|
||||
else
|
||||
execute s:Ref(backref, b, "start", "len")
|
||||
let ref = strpart(backref, start, len)
|
||||
let backref = strpart(backref, 0, start) . ":". table[s]
|
||||
\ . strpart(backref, start+len)
|
||||
let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
|
||||
endif
|
||||
endwhile
|
||||
let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
|
||||
let i = matchend(word, s:notslash . '\\\d') - 1
|
||||
endwhile
|
||||
let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
|
||||
if a:output == "table"
|
||||
return table
|
||||
elseif a:output == "word"
|
||||
return word
|
||||
else
|
||||
return table . word
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Assume a:comma = ",". Then the format for a:patterns and a:1 is
|
||||
" a:patterns = "<pat1>,<pat2>,..."
|
||||
" a:1 = "<alt1>,<alt2>,..."
|
||||
" If <patn> is the first pattern that matches a:string then return <patn>
|
||||
" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
|
||||
fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
|
||||
let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
|
||||
let i = matchend(tail, s:notslash . a:comma)
|
||||
if a:0
|
||||
let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
|
||||
let j = matchend(alttail, s:notslash . a:comma)
|
||||
endif
|
||||
let current = strpart(tail, 0, i-1)
|
||||
if a:branch == ""
|
||||
let currpat = current
|
||||
else
|
||||
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
|
||||
endif
|
||||
while a:string !~ a:prefix . currpat . a:suffix
|
||||
let tail = strpart(tail, i)
|
||||
let i = matchend(tail, s:notslash . a:comma)
|
||||
if i == -1
|
||||
return -1
|
||||
endif
|
||||
let current = strpart(tail, 0, i-1)
|
||||
if a:branch == ""
|
||||
let currpat = current
|
||||
else
|
||||
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
|
||||
endif
|
||||
if a:0
|
||||
let alttail = strpart(alttail, j)
|
||||
let j = matchend(alttail, s:notslash . a:comma)
|
||||
endif
|
||||
endwhile
|
||||
if a:0
|
||||
let current = current . a:comma . strpart(alttail, 0, j-1)
|
||||
endif
|
||||
return current
|
||||
endfun
|
||||
|
||||
" Call this function to turn on debugging information. Every time the main
|
||||
" script is run, buffer variables will be saved. These can be used directly
|
||||
" or viewed using the menu items below.
|
||||
if !exists(":MatchDebug")
|
||||
command! -nargs=0 MatchDebug call s:Match_debug()
|
||||
endif
|
||||
|
||||
fun! s:Match_debug()
|
||||
let b:match_debug = 1 " Save debugging information.
|
||||
" pat = all of b:match_words with backrefs parsed
|
||||
amenu &Matchit.&pat :echo b:match_pat<CR>
|
||||
" match = bit of text that is recognized as a match
|
||||
amenu &Matchit.&match :echo b:match_match<CR>
|
||||
" curcol = cursor column of the start of the matching text
|
||||
amenu &Matchit.&curcol :echo b:match_col<CR>
|
||||
" wholeBR = matching group, original version
|
||||
amenu &Matchit.wh&oleBR :echo b:match_wholeBR<CR>
|
||||
" iniBR = 'if' piece, original version
|
||||
amenu &Matchit.ini&BR :echo b:match_iniBR<CR>
|
||||
" ini = 'if' piece, with all backrefs resolved from match
|
||||
amenu &Matchit.&ini :echo b:match_ini<CR>
|
||||
" tail = 'else\|endif' piece, with all backrefs resolved from match
|
||||
amenu &Matchit.&tail :echo b:match_tail<CR>
|
||||
" fin = 'endif' piece, with all backrefs resolved from match
|
||||
amenu &Matchit.&word :echo b:match_word<CR>
|
||||
" '\'.d in ini refers to the same thing as '\'.table[d] in word.
|
||||
amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR>
|
||||
endfun
|
||||
|
||||
" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
|
||||
" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
|
||||
" Return a "mark" for the original position, so that
|
||||
" let m = MultiMatch("bW", "n") ... execute m
|
||||
" will return to the original position. If there is a problem, do not
|
||||
" move the cursor and return "", unless a count is given, in which case
|
||||
" go up or down as many levels as possible and again return "".
|
||||
" TODO This relies on the same patterns as % matching. It might be a good
|
||||
" idea to give it its own matching patterns.
|
||||
fun! s:MultiMatch(spflag, mode)
|
||||
if !exists("b:match_words") || b:match_words == ""
|
||||
return ""
|
||||
end
|
||||
let restore_options = (&ic ? "" : "no") . "ignorecase"
|
||||
if exists("b:match_ignorecase")
|
||||
let &ignorecase = b:match_ignorecase
|
||||
endif
|
||||
let startline = line(".")
|
||||
let startcol = col(".")
|
||||
|
||||
" First step: if not already done, set the script variables
|
||||
" s:do_BR flag for whether there are backrefs
|
||||
" s:pat parsed version of b:match_words
|
||||
" s:all regexp based on s:pat and the default groups
|
||||
" This part is copied and slightly modified from s:Match_wrapper().
|
||||
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
|
||||
\ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>'
|
||||
" Allow b:match_words = "GetVimMatchWords()" .
|
||||
if b:match_words =~ ":"
|
||||
let match_words = b:match_words
|
||||
else
|
||||
execute "let match_words =" b:match_words
|
||||
endif
|
||||
if (match_words != s:last_words) || (&mps != s:last_mps) ||
|
||||
\ exists("b:match_debug")
|
||||
let s:last_words = match_words
|
||||
let s:last_mps = &mps
|
||||
if match_words !~ s:notslash . '\\\d'
|
||||
let s:do_BR = 0
|
||||
let s:pat = match_words
|
||||
else
|
||||
let s:do_BR = 1
|
||||
let s:pat = s:ParseWords(match_words)
|
||||
endif
|
||||
let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default,
|
||||
\ '[,:]\+','\\|','g') . '\)'
|
||||
if exists("b:match_debug")
|
||||
let b:match_pat = s:pat
|
||||
endif
|
||||
endif
|
||||
|
||||
" Second step: figure out the patterns for searchpair()
|
||||
" and save the screen, cursor position, and 'ignorecase'.
|
||||
" - TODO: A lot of this is copied from s:Match_wrapper().
|
||||
" - maybe even more functionality should be split off
|
||||
" - into separate functions!
|
||||
let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default
|
||||
let open = substitute(s:pat . cdefault,
|
||||
\ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g')
|
||||
let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '')
|
||||
let close = substitute(s:pat . cdefault,
|
||||
\ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g')
|
||||
let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)'
|
||||
if exists("b:match_skip")
|
||||
let skip = b:match_skip
|
||||
elseif exists("b:match_comment") " backwards compatibility and testing!
|
||||
let skip = "r:" . b:match_comment
|
||||
else
|
||||
let skip = 's:comment\|string'
|
||||
endif
|
||||
let skip = s:ParseSkip(skip)
|
||||
" let restore_cursor = line(".") . "G" . virtcol(".") . "|"
|
||||
" normal! H
|
||||
" let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
|
||||
let restore_cursor = virtcol(".") . "|"
|
||||
normal! g0
|
||||
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor
|
||||
normal! H
|
||||
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
|
||||
execute restore_cursor
|
||||
|
||||
" Third step: call searchpair().
|
||||
" Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
|
||||
let openpat = substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
|
||||
let openpat = substitute(openpat, ',', '\\|', 'g')
|
||||
let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
|
||||
let closepat = substitute(closepat, ',', '\\|', 'g')
|
||||
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
|
||||
let skip = '0'
|
||||
else
|
||||
execute "if " . skip . "| let skip = '0' | endif"
|
||||
endif
|
||||
mark '
|
||||
let level = v:count1
|
||||
while level
|
||||
if searchpair(openpat, '', closepat, a:spflag, skip) < 1
|
||||
call s:CleanUp(restore_options, a:mode, startline, startcol)
|
||||
return ""
|
||||
endif
|
||||
let level = level - 1
|
||||
endwhile
|
||||
|
||||
" Restore options and return a string to restore the original position.
|
||||
call s:CleanUp(restore_options, a:mode, startline, startcol)
|
||||
return restore_cursor
|
||||
endfun
|
||||
|
||||
" Search backwards for "if" or "while" or "<tag>" or ...
|
||||
" and return "endif" or "endwhile" or "</tag>" or ... .
|
||||
" For now, this uses b:match_words and the same script variables
|
||||
" as s:Match_wrapper() . Later, it may get its own patterns,
|
||||
" either from a buffer variable or passed as arguments.
|
||||
" fun! s:Autocomplete()
|
||||
" echo "autocomplete not yet implemented :-("
|
||||
" if !exists("b:match_words") || b:match_words == ""
|
||||
" return ""
|
||||
" end
|
||||
" let startpos = s:MultiMatch("bW")
|
||||
"
|
||||
" if startpos == ""
|
||||
" return ""
|
||||
" endif
|
||||
" " - TODO: figure out whether 'if' or '<tag>' matched, and construct
|
||||
" " - the appropriate closing.
|
||||
" let matchline = getline(".")
|
||||
" let curcol = col(".") - 1
|
||||
" " - TODO: Change the s:all argument if there is a new set of match pats.
|
||||
" let regexp = s:Wholematch(matchline, s:all, curcol)
|
||||
" let suf = strlen(matchline) - matchend(matchline, regexp)
|
||||
" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(')
|
||||
" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$')
|
||||
" " Reconstruct the version with unresolved backrefs.
|
||||
" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
|
||||
" let patBR = substitute(patBR, ':\{2,}', ':', "g")
|
||||
" " Now, set group and groupBR to the matching group: 'if:endif' or
|
||||
" " 'while:endwhile' or whatever.
|
||||
" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
|
||||
" let i = matchend(group, s:notslash . ",")
|
||||
" let groupBR = strpart(group, i)
|
||||
" let group = strpart(group, 0, i-1)
|
||||
" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
|
||||
" if s:do_BR
|
||||
" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
|
||||
" endif
|
||||
" " let g:group = group
|
||||
"
|
||||
" " - TODO: Construct the closing from group.
|
||||
" let fake = "end" . expand("<cword>")
|
||||
" execute startpos
|
||||
" return fake
|
||||
" endfun
|
||||
|
||||
" Close all open structures. "Get the heck out of here!"
|
||||
" fun! s:Gthhoh()
|
||||
" let close = s:Autocomplete()
|
||||
" while strlen(close)
|
||||
" put=close
|
||||
" let close = s:Autocomplete()
|
||||
" endwhile
|
||||
" endfun
|
||||
|
||||
" Parse special strings as typical skip arguments for searchpair():
|
||||
" s:foo becomes (current syntax item) =~ foo
|
||||
" S:foo becomes (current syntax item) !~ foo
|
||||
" r:foo becomes (line before cursor) =~ foo
|
||||
" R:foo becomes (line before cursor) !~ foo
|
||||
fun! s:ParseSkip(str)
|
||||
let skip = a:str
|
||||
if skip[1] == ":"
|
||||
if skip[0] == "s"
|
||||
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
|
||||
\ strpart(skip,2) . "'"
|
||||
elseif skip[0] == "S"
|
||||
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
|
||||
\ strpart(skip,2) . "'"
|
||||
elseif skip[0] == "r"
|
||||
let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
|
||||
elseif skip[0] == "R"
|
||||
let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
|
||||
endif
|
||||
endif
|
||||
return skip
|
||||
endfun
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
|
||||
" vim:sts=2:sw=2:
|
||||
537
vim/plugin/pastie.vim
Normal file
537
vim/plugin/pastie.vim
Normal file
@@ -0,0 +1,537 @@
|
||||
" pastie.vim: Vim plugin for pastie.caboo.se
|
||||
" Maintainer: Tim Pope <vimNOSPAM@tpope.info>
|
||||
" URL: http://www.vim.org/scripts/script.php?script_id=1624
|
||||
" GetLatestVimScripts: 1624 1
|
||||
" $Id: pastie.vim,v 1.15 2007-12-13 16:44:26 tpope Exp $
|
||||
|
||||
" Installation:
|
||||
" Place in ~/.vim/plugin or vimfiles/plugin
|
||||
" A working ruby install is required (Vim interface not necessary).
|
||||
|
||||
" Usage:
|
||||
" :Pastie creates a new paste (example arguments shown below). Use :w to save
|
||||
" it by posting it to the server (the parser used is derived from the Vim
|
||||
" filetype). This updates the filename and stores the new url in the primary
|
||||
" selection/clipboard when successful. :Pastie! creates a paste, saves, and
|
||||
" closes the buffer, except when loading an existing paste.
|
||||
|
||||
" :Pastie Create a paste from all open windows
|
||||
" :Pastie! Create a paste from all open windows and paste it
|
||||
" :1,10Pastie Create a paste from the specified range
|
||||
" :%Pastie Use the entire current file to create a new paste
|
||||
" :Pastie foo.txt bar.txt Create a paste from foo.txt and bar.txt
|
||||
" :Pastie! foo.txt Paste directly from foo.txt
|
||||
" :Pastie a Create a paste from the "a register
|
||||
" :Pastie @ Create a paste from the default (unnamed) register
|
||||
" :Pastie * Create a paste from the primary selection/clipboard
|
||||
" :Pastie _ Create a new, blank paste
|
||||
" :768Pastie Load existing paste 768
|
||||
" :0Pastie Load the newest paste
|
||||
" :Pastie http://pastie.caboo.se/768 Load existing paste 768
|
||||
" :Pastie http://pastie.caboo.se/123456?key=... Use login from pastie bot
|
||||
|
||||
" Regardless of the command used, on the first write, this script will create
|
||||
" a new paste, and on subsequent writes, it will update the existing paste.
|
||||
" If a bang is passed to a command that load an existing paste (:768), the
|
||||
" first write will update as well. If the loaded paste was not created in the
|
||||
" same vim session, or with an account extracted from your Firefox cookies,
|
||||
" updates will almost certainly silently fail. (Advanced users can muck
|
||||
" around with g:pastie_session_id if desired).
|
||||
|
||||
" As hinted at earlier, pastie.vim will snoop around in your Firefox cookies,
|
||||
" and use an account cookie if one is found. The only way to create one of
|
||||
" these account cookies is by talking to pastie on IRC.
|
||||
|
||||
" At the shell you can directly create a new pastie with a command like
|
||||
" $ vim +Pastie
|
||||
" or, assuming no other plugins conflict
|
||||
" $ vim +Pa
|
||||
" And, to read an existing paste
|
||||
" $ vim +768Pa
|
||||
" You could even paste a file directly
|
||||
" $ vim '+Pa!~/.irbrc' +q
|
||||
" You can even edit a pastie URL directly, but this is not recommended because
|
||||
" netrw can sometimes interfere.
|
||||
|
||||
" Lines ending in #!! will be sent as lines beginning with !!. This alternate
|
||||
" format is easier to read and is less likely to interfere with code
|
||||
" execution. In Vim 7 highlighting is done with :2match (use ":2match none"
|
||||
" to disable it) and in previous versions, :match (use ":match none" to
|
||||
" disable).
|
||||
"
|
||||
" Known Issues:
|
||||
" URL sometimes disappears with the bang (:Pastie!) variant. You can still
|
||||
" retrieve it from the clipboard.
|
||||
|
||||
if exists("g:loaded_pastie") || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_pastie = 1
|
||||
|
||||
augroup pastie
|
||||
autocmd!
|
||||
autocmd BufReadPre http://pastie.caboo.se/*[0-9]?key=* call s:extractcookies(expand("<amatch>"))
|
||||
autocmd BufReadPost http://pastie.caboo.se/*[0-9]?key=* call s:PastieSwapout(expand("<amatch>"))
|
||||
autocmd BufReadPost http://pastie.caboo.se/*[0-9] call s:PastieSwapout(expand("<amatch>"))
|
||||
autocmd BufReadPost http://pastie.caboo.se/pastes/*[0-9]/download call s:PastieRead(expand("<amatch>"))
|
||||
autocmd BufReadPost http://pastie.caboo.se/*[0-9].* call s:PastieRead(expand("<amatch>"))
|
||||
autocmd BufWriteCmd http://pastie.caboo.se/pastes/*[0-9]/download call s:PastieWrite(expand("<amatch>"))
|
||||
autocmd BufWriteCmd http://pastie.caboo.se/*[0-9].* call s:PastieWrite(expand("<amatch>"))
|
||||
autocmd BufWriteCmd http://pastie.caboo.se/pastes/ call s:PastieWrite(expand("<amatch>"))
|
||||
augroup END
|
||||
|
||||
let s:domain = "pastie.caboo.se"
|
||||
|
||||
let s:dl_suffix = ".txt" " Used only for :file
|
||||
|
||||
if !exists("g:pastie_destination")
|
||||
if version >= 700
|
||||
let g:pastie_destination = 'tab'
|
||||
else
|
||||
let g:pastie_destination = 'window'
|
||||
endif
|
||||
"let g:pastie_destination = 'buffer'
|
||||
endif
|
||||
|
||||
command! -bar -bang -nargs=* -range=0 -complete=file Pastie :call s:Pastie(<bang>0,<line1>,<line2>,<count>,<f-args>)
|
||||
|
||||
function! s:Pastie(bang,line1,line2,count,...)
|
||||
if exists(":tab")
|
||||
let tabnr = tabpagenr()
|
||||
endif
|
||||
let newfile = "http://".s:domain."/pastes/"
|
||||
let loggedin = 0
|
||||
let ft = &ft
|
||||
let num = 0
|
||||
if a:0 == 0 && a:count == a:line1 && a:count > line('$')
|
||||
let num = a:count
|
||||
elseif a:0 == 0 && a:line1 == 0 && a:line2 == 0
|
||||
let num = s:latestid()
|
||||
if num == 0
|
||||
return s:error("Could not determine latest paste")
|
||||
endif
|
||||
elseif !a:count && a:0 == 1
|
||||
if a:1 == '*'
|
||||
let numcheck = @*
|
||||
elseif a:1 == '+'
|
||||
let numcheck = @+
|
||||
elseif a:1 == '@'
|
||||
let numcheck = @@
|
||||
else
|
||||
let numcheck = a:1
|
||||
endif
|
||||
let numcheck = substitute(numcheck,'\n\+$','','')
|
||||
let numcheck = substitute(numcheck,'^\n\+','','g')
|
||||
if numcheck =~ '\n'
|
||||
let numcheck = ''
|
||||
endif
|
||||
if numcheck =~ '^\d\d+$'
|
||||
let num = numcheck
|
||||
elseif numcheck =~ '\%(^\|/\)\d\+?key=\x\{8,\}'
|
||||
if exists("b:pastie_fake_login")
|
||||
unlet b:pastie_fake_login
|
||||
else
|
||||
call s:extractcookies('/'.matchstr(numcheck,'\%(^\|/\)\zs\d\+?.*'))
|
||||
endif
|
||||
if exists("g:pastie_account")
|
||||
let loggedin = 1
|
||||
endif
|
||||
let num = matchstr(numcheck,'\%(^\|/\)\zs\d\+\ze?')
|
||||
elseif numcheck =~ '\%(^\|^/\|^http://.*\)\d\+\%([/?]\|$\)'
|
||||
let num = matchstr(numcheck,'\%(^\|/\)\zs\d\+')
|
||||
endif
|
||||
endif
|
||||
if num
|
||||
call s:newwindow()
|
||||
let file = "http://".s:domain."/".num.s:dl_suffix
|
||||
silent exe 'doautocmd BufReadPre '.file
|
||||
silent exe 'read !ruby -rnet/http -e "r = Net::HTTP.get_response(\%{'.s:domain.'}, \%{/pastes/'.num.'/download}); if r.code == \%{200} then print r.body else exit 10+r.code.to_i/100 end"'
|
||||
if v:shell_error && v:shell_error != 14 && v:shell_error !=15
|
||||
return s:error("Something went wrong: shell returned ".v:shell_error)
|
||||
else
|
||||
let err = v:shell_error
|
||||
silent exe "file ".file
|
||||
1d_
|
||||
set nomodified
|
||||
call s:dobufreadpost()
|
||||
if err
|
||||
if loggedin
|
||||
let b:pastie_update = 1
|
||||
else
|
||||
echohl WarningMsg
|
||||
echo "Warning: Failed to retrieve existing paste"
|
||||
echohl None
|
||||
endif
|
||||
endif
|
||||
"call s:PastieRead(file)
|
||||
if a:bang
|
||||
" Instead of saving an identical paste, take ! to mean "do not
|
||||
" create a new paste on first save"
|
||||
let b:pastie_update = 1
|
||||
endif
|
||||
return
|
||||
endif
|
||||
elseif a:0 == 0 && !a:count && a:bang && expand("%") =~ '^http://'.s:domain.'/\d\+'
|
||||
" If the :Pastie! form is used in an existing paste, switch to
|
||||
" updating instead of creating.
|
||||
"echohl Question
|
||||
echo "Will update, not create"
|
||||
echohl None
|
||||
let b:pastie_update = 1
|
||||
return
|
||||
elseif a:0 == 1 && !a:count && a:1 =~ '^[&?]\x\{32,\}'
|
||||
" Set session id with :Pastie&deadbeefcafebabe
|
||||
let g:pastie_session_id = strpart(a:1,1)
|
||||
elseif a:0 == 1 && !a:count && (a:1 == '&' || a:1 == '?')
|
||||
" Extract session id with :Pastie&
|
||||
call s:cookies()
|
||||
if exists("g:pastie_session_id")
|
||||
echo g:pastie_session_id
|
||||
"silent! let @* = g:pastie_session_id
|
||||
endif
|
||||
elseif a:0 == 0 && !a:count && a:line1
|
||||
let ft = 'conf'
|
||||
let sum = ""
|
||||
let cnt = 0
|
||||
let keep = @"
|
||||
windo let tmp = s:grabwin() | if tmp != "" | let cnt = cnt + 1 | let sum = sum . tmp | end
|
||||
let sum = substitute(sum,'\n\+$',"\n",'')
|
||||
if cnt == 1
|
||||
let ft = matchstr(sum,'^##.\{-\} \[\zs\w*\ze\]')
|
||||
if ft != ""
|
||||
let sum = substitute(sum,'^##.\{-\} \[\w*\]\n','','')
|
||||
endif
|
||||
endif
|
||||
call s:newwindow()
|
||||
silent exe "file ".newfile
|
||||
"silent exe "doautocmd BufReadPre ".newfile
|
||||
if sum != ""
|
||||
let @" = sum
|
||||
silent $put
|
||||
1d _
|
||||
endif
|
||||
if ft == 'plaintext' || ft == 'plain_text'
|
||||
"set ft=conf
|
||||
elseif ft != '' && sum != ""
|
||||
let &ft = ft
|
||||
endif
|
||||
let @" = keep
|
||||
call s:dobufreadpost()
|
||||
else
|
||||
let keep = @"
|
||||
let args = ""
|
||||
if a:0 > 0 && a:1 =~ '^[-"@0-9a-zA-Z:.%#*+~_/]$'
|
||||
let i = 1
|
||||
let register = a:1
|
||||
else
|
||||
let i = 0
|
||||
let register = ""
|
||||
endif
|
||||
while i < a:0
|
||||
let i = i+1
|
||||
if strlen(a:{i})
|
||||
let file = fnamemodify(expand(a:{i}),':~:.')
|
||||
let args = args . file . "\n"
|
||||
endif
|
||||
endwhile
|
||||
let range = ""
|
||||
if a:count
|
||||
silent exe a:line1.",".a:line2."yank"
|
||||
let range = @"
|
||||
let @" = keep
|
||||
endif
|
||||
call s:newwindow()
|
||||
silent exe "file ".newfile
|
||||
"silent exe "doautocmd BufReadPre ".newfile
|
||||
if range != ""
|
||||
let &ft = ft
|
||||
let @" = range
|
||||
silent $put
|
||||
endif
|
||||
if register != '' && register != '_'
|
||||
"exe "let regvalue = @".register
|
||||
silent exe "$put ".(register =~ '^[@"]$' ? '' : register)
|
||||
endif
|
||||
while args != ''
|
||||
let file = matchstr(args,'^.\{-\}\ze\n')
|
||||
let args = substitute(args,'^.\{-\}\n','','')
|
||||
let @" = "## ".file." [".s:parser(file)."]\n"
|
||||
if a:0 != 1 || a:count
|
||||
silent $put
|
||||
else
|
||||
let &ft = s:filetype(file)
|
||||
endif
|
||||
silent exe "$read ".substitute(file,' ','\ ','g')
|
||||
endwhile
|
||||
let @" = keep
|
||||
1d_
|
||||
call s:dobufreadpost()
|
||||
if (a:0 + (a:count > 0)) > 1
|
||||
set ft=conf
|
||||
endif
|
||||
endif
|
||||
1
|
||||
call s:afterload()
|
||||
if a:bang
|
||||
write
|
||||
let name = bufname('%')
|
||||
" TODO: re-echo the URL in a way that doesn't disappear. Stupid Vim.
|
||||
silent! bdel
|
||||
if exists("tabnr")
|
||||
silent exe "norm! ".tabnr."gt"
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:dobufreadpost()
|
||||
if expand("%") =~ '/\d\+\.\@!'
|
||||
silent exe "doautocmd BufReadPost ".expand("%")
|
||||
else
|
||||
silent exe "doautocmd BufNewFile ".expand("%")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:PastieSwapout(file)
|
||||
if a:file =~ '?key='
|
||||
let b:pastie_fake_login = 1
|
||||
endif
|
||||
exe "Pastie ".a:file
|
||||
endfunction
|
||||
|
||||
function! s:PastieRead(file)
|
||||
let lnum = line(".")
|
||||
silent %s/^!!\(.*\)/\1 #!!/e
|
||||
exe lnum
|
||||
set nomodified
|
||||
let num = matchstr(a:file,'/\@<!/\zs\d\+')
|
||||
let url = "http://".s:domain."/pastes/".num
|
||||
"let url = substitute(a:file,'\c/\%(download/\=\|text/\=\)\=$','','')
|
||||
let url = url."/download"
|
||||
let result = system('ruby -rnet/http -e "puts Net::HTTP.get_response(URI.parse(%{'.url.'}))[%{Content-Disposition}]"')
|
||||
let fn = matchstr(result,'filename="\zs.*\ze"')
|
||||
let &ft = s:filetype(fn)
|
||||
if &ft =~ '^\%(html\|ruby\)$' && getline(1).getline(2).getline(3) =~ '<%'
|
||||
set ft=eruby
|
||||
endif
|
||||
call s:afterload()
|
||||
endfunction
|
||||
|
||||
function! s:afterload()
|
||||
set commentstring=%s\ #!! "
|
||||
hi def link pastieIgnore Ignore
|
||||
hi def link pastieNonText NonText
|
||||
if exists(":match")
|
||||
hi def link pastieHighlight MatchParen
|
||||
if version >= 700
|
||||
2match pastieHighlight /^!!\s*.*\|^.\{-\}\ze\s*#!!\s*$/
|
||||
else
|
||||
match pastieHighlight /^!!\s*.*\|^.\{-\}\ze\s*#!!\s*$/
|
||||
endif
|
||||
else
|
||||
hi def link pastieHighlight Search
|
||||
syn match pastieHighlight '^.\{-\}\ze\s*#!!\s*$' nextgroup=pastieIgnore skipwhite
|
||||
syn region pastieHighlight start='^!!\s*' end='$' contains=pastieNonText
|
||||
endif
|
||||
syn match pastieIgnore '#!!\ze\s*$' containedin=rubyComment,rubyString
|
||||
syn match pastieNonText '^!!' containedin=rubyString
|
||||
endfunction
|
||||
|
||||
function! s:PastieWrite(file)
|
||||
let parser = s:parser(&ft)
|
||||
let tmp = tempname()
|
||||
let num = matchstr(a:file,'/\@<!/\zs\d\+')
|
||||
if num == ''
|
||||
let num = 'pastes'
|
||||
endif
|
||||
if exists("b:pastie_update") && s:cookies() != '' && num != ""
|
||||
let url = "/pastes/".num
|
||||
let method = "_method=put&"
|
||||
else
|
||||
let url = "/pastes"
|
||||
let method = ""
|
||||
endif
|
||||
if exists("b:pastie_display_name")
|
||||
let pdn = "&paste[display_name]=".s:urlencode(b:pastie_display_name)
|
||||
elseif exists("g:pastie_display_name")
|
||||
let pdn = "&paste[display_name]=".s:urlencode(g:pastie_display_name)
|
||||
else
|
||||
let pdn = ""
|
||||
endif
|
||||
silent exe "write ".tmp
|
||||
let result = ""
|
||||
let rubycmd = 'obj = Net::HTTP.start(%{'.s:domain.'}){|h|h.post(%{'.url.'}, %q{'.method.'paste[parser]='.parser.pdn.'&paste[authorization]=burger&paste[key]=&paste[body]=} + File.read(%q{'.tmp.'}).gsub(/^(.*?) *#\!\! *#{36.chr}/,%{!\!}+92.chr+%{1}).gsub(/[^a-zA-Z0-9_.-]/n) {|s| %{%%%02x} % s[0]},{%{Cookie} => %{'.s:cookies().'}})}; print obj[%{Location}].to_s+%{ }+obj[%{Set-Cookie}].to_s'
|
||||
let result = system('ruby -rnet/http -e "'.rubycmd.'"')
|
||||
let redirect = matchstr(result,'^[^ ]*')
|
||||
let cookies = matchstr(result,'^[^ ]* \zs.*')
|
||||
call s:extractcookiesfromheader(cookies)
|
||||
call delete(tmp)
|
||||
if redirect =~ '^\w\+://'
|
||||
set nomodified
|
||||
let b:pastie_update = 1
|
||||
"silent! let @+ = result
|
||||
silent! let @* = redirect
|
||||
silent exe "file ".redirect.s:dl_suffix
|
||||
" TODO: make a proper status message
|
||||
echo '"'.redirect.'" written'
|
||||
silent exe "doautocmd BufWritePost ".redirect.s:dl_suffix
|
||||
else
|
||||
if redirect == ''
|
||||
let redirect = "Could not post to ".url
|
||||
endif
|
||||
let redirect = substitute(redirect,'^-e:1:\s*','','')
|
||||
call s:error(redirect)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:error(msg)
|
||||
echohl Error
|
||||
echo a:msg
|
||||
echohl NONE
|
||||
let v:errmsg = a:msg
|
||||
endfunction
|
||||
|
||||
function! s:filetype(type)
|
||||
" Accepts a filename, extension, pastie parser, or vim filetype
|
||||
let type = tolower(substitute(a:type,'.*\.','',''))
|
||||
if type =~ '^\%(x\=html\|asp\w*\)$'
|
||||
return 'html'
|
||||
elseif type =~ '^\%(eruby\|erb\|rhtml\)$'
|
||||
return 'eruby'
|
||||
elseif type =~ '^\%(ruby\|ruby_on_rails\|rb\|rake\|builder\|rjs\|irbrc\)'
|
||||
return 'ruby'
|
||||
elseif type == 'js' || type == 'javascript'
|
||||
return 'javascript'
|
||||
elseif type == 'c' || type == 'cpp' || type == 'c++'
|
||||
return 'cpp'
|
||||
elseif type =~ '^\%(css\|diff\|java\|php\|python\|sql\|sh\|shell-unix-generic\)$'
|
||||
return type
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:parser(type)
|
||||
let type = s:filetype(a:type)
|
||||
if type == 'text' || type == ''
|
||||
return 'plain_text'
|
||||
elseif type == 'eruby'
|
||||
return 'html_rails'
|
||||
elseif type == 'ruby'
|
||||
return 'ruby_on_rails'
|
||||
elseif type == 'sh'
|
||||
return 'shell-unix-generic'
|
||||
elseif type == 'cpp'
|
||||
return 'c++'
|
||||
else
|
||||
return type
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:grabwin()
|
||||
let ft = (&ft == '' ? expand("%:e") : &ft)
|
||||
let top = "## ".expand("%:~:.")." [".s:parser(ft)."]\n"
|
||||
let keep = @"
|
||||
silent %yank
|
||||
let file = @"
|
||||
let @" = keep
|
||||
if file == "" || file == "\n"
|
||||
return ""
|
||||
else
|
||||
return top.file."\n"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:cookies()
|
||||
if exists("g:pastie_session_id")
|
||||
let cookies = "_pastie_session_id=".g:pastie_session_id
|
||||
else
|
||||
call s:extractcookies('/')
|
||||
if !exists("g:pastie_session_id")
|
||||
if !exists("s:session_warning")
|
||||
echohl WarningMsg
|
||||
echo "Warning: could not extract session id"
|
||||
let s:session_warning = 1
|
||||
echohl NONE
|
||||
endif
|
||||
let cookies = ""
|
||||
else
|
||||
let cookies = "_pastie_session_id=".g:pastie_session_id
|
||||
endif
|
||||
endif
|
||||
if !exists("g:pastie_account")
|
||||
let rubycmd = '%w(~/.mozilla/firefox ~/.firefox/default ~/.phoenix/default ~/Application\ Data/Mozilla/Firefox/Profiles ~/Library/Application\ Support/Firefox/Profiles)'
|
||||
let rubycmd = rubycmd . '.each {|dir| Dir[File.join(File.expand_path(dir),%{*})].select {|p| File.exists?(File.join(p,%{cookies.txt}))}.each {|p| File.open(File.join(p,%{cookies.txt})).each_line { |l| a=l.split(9.chr); puts [a[4],a[6]].join(%{ }) if a[0] =~ /pastie\.caboo\.se#{36.chr}/ && Time.now.to_i < a[4].to_i && a[5] == %{account} }}}'
|
||||
let output = ''
|
||||
let output = system('ruby -e "'.rubycmd.'"')
|
||||
if output =~ '\n' && output !~ '-e:'
|
||||
let output = substitute(output,'\n.*','','')
|
||||
let g:pastie_account = matchstr(output,' \zs.*')
|
||||
let g:pastie_account_expires = matchstr(output,'.\{-\}\ze ')
|
||||
else
|
||||
let g:pastie_account = ''
|
||||
endif
|
||||
endif
|
||||
if exists("g:pastie_account") && g:pastie_account != ""
|
||||
" You cannot set this arbitrarily, it must be a valid cookie
|
||||
let cookies = cookies . (cookies == "" ? "" : "; ")
|
||||
let cookies = cookies . 'account='.substitute(g:pastie_account,':','%3A','g')
|
||||
endif
|
||||
return cookies
|
||||
endfunction
|
||||
|
||||
function! s:extractcookies(path)
|
||||
let path = substitute(a:path,'\c^http://'.s:domain,'','')
|
||||
if path !~ '^/'
|
||||
let path = '/'.path
|
||||
endif
|
||||
let cookie = system('ruby -rnet/http -e "print Net::HTTP.get_response(%{'.s:domain.'},%{'.path.'})[%{Set-Cookie}]"')
|
||||
if exists("g:pastie_debug")
|
||||
let g:pastie_cookies_path = path
|
||||
let g:pastie_cookies = cookie
|
||||
endif
|
||||
return s:extractcookiesfromheader(cookie)
|
||||
endfunction
|
||||
|
||||
function! s:extractcookiesfromheader(cookie)
|
||||
let cookie = a:cookie
|
||||
if cookie !~ '-e:'
|
||||
let session_id = matchstr(cookie,'\<_pastie_session_id=\zs.\{-\}\ze\%([;,]\|$\)')
|
||||
let account = matchstr(cookie,'\<account=\zs.\{-\}\ze\%([;,]\|$\)')
|
||||
if session_id != ""
|
||||
let g:pastie_session_id = session_id
|
||||
endif
|
||||
if account != ""
|
||||
let g:pastie_account = account
|
||||
let time = matchstr(cookie,'\<[Ee]xpires=\zs\w\w\w,.\{-\}\ze\%([;,]\|$\)')
|
||||
if time != ""
|
||||
let g:pastie_account_expires = system('ruby -e "print Time.parse(%{'.time.'}).to_i"')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:latestid()
|
||||
return system('ruby -rnet/http -e "print Net::HTTP.get_response(URI.parse(%{http://'.s:domain.'/all})).body.match(%r{<a href=.http://'.s:domain.'/(\d+).>View})[1]"')
|
||||
endfunction
|
||||
|
||||
function! s:urlencode(str)
|
||||
" Vim 6.2, how did we ever live with you?
|
||||
return substitute(substitute(a:str,"[\001-\037%&?=\\\\]",'\="%".printf("%02X",char2nr(submatch(0)))','g'),' ','%20','g')
|
||||
endfunction
|
||||
|
||||
function! s:newwindow()
|
||||
if !(&modified) && (expand("%") == '' || (version >= 700 && winnr("$") == 1 && tabpagenr("$") == 1))
|
||||
enew
|
||||
else
|
||||
if g:pastie_destination == 'tab'
|
||||
tabnew
|
||||
elseif g:pastie_destination == 'window'
|
||||
new
|
||||
else
|
||||
enew
|
||||
endif
|
||||
endif
|
||||
setlocal noswapfile
|
||||
endfunction
|
||||
|
||||
" vim:set sw=4 sts=4 et:
|
||||
44
vim/plugin/peepopen.vim
Normal file
44
vim/plugin/peepopen.vim
Normal file
@@ -0,0 +1,44 @@
|
||||
" plugin/peepopen.vim
|
||||
" Author: Geoffrey Grosenbach <boss@topfunky.com>
|
||||
" License: MIT License
|
||||
|
||||
" Install this file as plugin/peepopen.vim.
|
||||
|
||||
" If you prefer Command-T, use this snippet in your .gvimrc:
|
||||
|
||||
" if has("gui_macvim")
|
||||
" macmenu &File.New\ Tab key=<nop>
|
||||
" map <D-t> <Plug>PeepOpen
|
||||
" end
|
||||
|
||||
" ============================================================================
|
||||
|
||||
" Exit quickly when:
|
||||
" - this plugin was already loaded (or disabled)
|
||||
" - when 'compatible' is set
|
||||
if &cp || exists("g:peepopen_loaded") && g:peepopen_loaded
|
||||
finish
|
||||
endif
|
||||
let g:peepopen_loaded = 1
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function s:LaunchPeepOpenViaVim()
|
||||
let cwd = getcwd()
|
||||
silent exe "!open -a PeepOpen " . shellescape(cwd)
|
||||
endfunction
|
||||
|
||||
command! PeepOpen :call <SID>LaunchPeepOpenViaVim()
|
||||
|
||||
noremap <unique> <script> <Plug>PeepOpen <SID>Launch
|
||||
noremap <SID>Launch :call <SID>LaunchPeepOpenViaVim()<CR>
|
||||
|
||||
if !hasmapto('<Plug>PeepOpen')
|
||||
map <unique> <silent> <C-f> <Plug>PeepOpen
|
||||
endif
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set sw=2 sts=2:
|
||||
486
vim/plugin/ragtag.vim
Normal file
486
vim/plugin/ragtag.vim
Normal file
@@ -0,0 +1,486 @@
|
||||
" ragtag.vim - Ghetto XML/HTML mappings (formerly allml.vim)
|
||||
" Author: Tim Pope <vimNOSPAM@tpope.org>
|
||||
" Version: 2.0
|
||||
" GetLatestVimScripts: 1896 1 :AutoInstall: ragtag.vim
|
||||
|
||||
if exists("g:loaded_ragtag") || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_ragtag = 1
|
||||
|
||||
if has("autocmd")
|
||||
augroup ragtag
|
||||
autocmd!
|
||||
autocmd FileType *html*,wml,xml,xslt,xsd,jsp call s:Init()
|
||||
autocmd FileType php,asp*,cf,mason,eruby call s:Init()
|
||||
if version >= 700
|
||||
autocmd InsertLeave * call s:Leave()
|
||||
endif
|
||||
autocmd CursorHold * if exists("b:loaded_ragtag") | call s:Leave() | endif
|
||||
augroup END
|
||||
endif
|
||||
|
||||
inoremap <silent> <Plug>ragtagHtmlComplete <C-R>=<SID>htmlEn()<CR><C-X><C-O><C-P><C-R>=<SID>htmlDis()<CR><C-N>
|
||||
|
||||
" Public interface, for if you have your own filetypes to activate on
|
||||
function! RagtagInit()
|
||||
call s:Init()
|
||||
endfunction
|
||||
|
||||
function! AllmlInit()
|
||||
call s:Init()
|
||||
endfunction
|
||||
|
||||
function! s:Init()
|
||||
let b:loaded_ragtag = 1
|
||||
inoremap <silent> <buffer> <SID>xmlversion <?xml version="1.0" encoding="<C-R>=toupper(<SID>charset())<CR>"?>
|
||||
inoremap <buffer> <SID>htmltrans <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
inoremap <buffer> <SID>xhtmltrans <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
if s:subtype() == "xml"
|
||||
imap <script> <buffer> <SID>doctype <SID>xmlversion
|
||||
elseif exists("+omnifunc")
|
||||
inoremap <silent> <buffer> <SID>doctype <C-R>=<SID>htmlEn()<CR><!DOCTYPE<C-X><C-O><C-P><C-R>=<SID>htmlDis()<CR><C-N><C-R>=<SID>doctypeSeek()<CR>
|
||||
elseif s:subtype() == "xhtml"
|
||||
imap <script> <buffer> <SID>doctype <SID>xhtmltrans
|
||||
else
|
||||
imap <script> <buffer> <SID>doctype <SID>htmltrans
|
||||
endif
|
||||
imap <script> <buffer> <C-X>! <SID>doctype
|
||||
|
||||
imap <silent> <buffer> <C-X># <meta http-equiv="Content-Type" content="text/html; charset=<C-R>=<SID>charset()<CR>"<C-R>=<SID>closetag()<CR>
|
||||
inoremap <silent> <buffer> <SID>HtmlComplete <C-R>=<SID>htmlEn()<CR><C-X><C-O><C-P><C-R>=<SID>htmlDis()<CR><C-N>
|
||||
imap <buffer> <C-X>H <SID>HtmlComplete
|
||||
inoremap <silent> <buffer> <C-X>$ <C-R>=<SID>javascriptIncludeTag()<CR>
|
||||
inoremap <silent> <buffer> <C-X>@ <C-R>=<SID>stylesheetTag()<CR>
|
||||
inoremap <silent> <buffer> <C-X><Space> <Esc>ciw<Lt><C-R>"<C-R>=<SID>tagextras()<CR>></<C-R>"><Esc>b2hi
|
||||
inoremap <silent> <buffer> <C-X><CR> <Esc>ciw<Lt><C-R>"<C-R>=<SID>tagextras()<CR>><CR></<C-R>"><Esc>O
|
||||
if exists("&omnifunc")
|
||||
inoremap <silent> <buffer> <C-X>/ <Lt>/<C-R>=<SID>htmlEn()<CR><C-X><C-O><C-R>=<SID>htmlDis()<CR><C-F>
|
||||
if exists(":XMLns")
|
||||
XMLns xhtml10s
|
||||
endif
|
||||
else
|
||||
inoremap <silent> <buffer> <C-X>/ <Lt>/><Left>
|
||||
endif
|
||||
let g:surround_{char2nr("p")} = "<p>\n\t\r\n</p>"
|
||||
let g:surround_{char2nr("d")} = "<div\1div: \r^[^ ]\r &\1>\n\t\r\n</div>"
|
||||
imap <buffer> <C-X><C-_> <C-X>/
|
||||
imap <buffer> <SID>ragtagOopen <C-X><Lt><Space>
|
||||
imap <buffer> <SID>ragtagOclose <Space><C-X>><Left><Left>
|
||||
if &ft == "php"
|
||||
inoremap <buffer> <C-X><Lt> <?php
|
||||
inoremap <buffer> <C-X>> ?>
|
||||
inoremap <buffer> <SID>ragtagOopen <?php<Space>print<Space>
|
||||
let b:surround_45 = "<?php \r ?>"
|
||||
let b:surround_61 = "<?php print \r ?>"
|
||||
elseif &ft == "htmltt" || &ft == "tt2html"
|
||||
inoremap <buffer> <C-X><Lt> [%
|
||||
inoremap <buffer> <C-X>> %]
|
||||
let b:surround_45 = "[% \r %]"
|
||||
let b:surround_61 = "[% \r %]"
|
||||
if !exists("b:surround_101")
|
||||
let b:surround_101 = "[% \r %]\n[% END %]"
|
||||
endif
|
||||
elseif &ft =~ "django"
|
||||
inoremap <buffer> <C-X><Lt> {{
|
||||
inoremap <buffer> <C-X>> }}
|
||||
let b:surround_45 = "{% \r %}"
|
||||
let b:surround_61 = "{{ \r }}"
|
||||
elseif &ft == "mason"
|
||||
inoremap <buffer> <SID>ragtagOopen <&<Space>
|
||||
inoremap <buffer> <SID>ragtagOclose <Space>&><Left><Left>
|
||||
inoremap <buffer> <C-X><Lt> <%
|
||||
inoremap <buffer> <C-X>> %>
|
||||
let b:surround_45 = "<% \r %>"
|
||||
let b:surround_61 = "<& \r &>"
|
||||
elseif &ft == "cf"
|
||||
inoremap <buffer> <SID>ragtagOopen <cfoutput>
|
||||
inoremap <buffer> <SID>ragtagOclose </cfoutput><Left><C-Left><Left>
|
||||
inoremap <buffer> <C-X><Lt> <cf
|
||||
inoremap <buffer> <C-X>> >
|
||||
let b:surround_45 = "<cf\r>"
|
||||
let b:surround_61 = "<cfoutput>\r</cfoutput>"
|
||||
else
|
||||
inoremap <buffer> <SID>ragtagOopen <%=<Space>
|
||||
inoremap <buffer> <C-X><Lt> <%
|
||||
inoremap <buffer> <C-X>> %>
|
||||
let b:surround_45 = "<% \r %>"
|
||||
let b:surround_61 = "<%= \r %>"
|
||||
endif
|
||||
imap <buffer> <C-X>= <SID>ragtagOopen<SID>ragtagOclose<Left>
|
||||
imap <buffer> <C-X>+ <C-V><NL><Esc>I<SID>ragtagOopen<Space><Esc>A<Space><SID>ragtagOclose<Esc>F<NL>s
|
||||
" <%\n\n%>
|
||||
if &ft == "cf"
|
||||
inoremap <buffer> <C-X>] <cfscript><CR></cfscript><Esc>O
|
||||
elseif &ft == "mason"
|
||||
inoremap <buffer> <C-X>] <%perl><CR></%perl><Esc>O
|
||||
elseif &ft == "html" || &ft == "xhtml" || &ft == "xml"
|
||||
imap <buffer> <C-X>] <script<Space>type="text/javascript"><CR></script><Esc>O
|
||||
else
|
||||
imap <buffer> <C-X>] <C-X><Lt><CR><C-X>><Esc>O
|
||||
endif
|
||||
" <% %>
|
||||
if &ft == "eruby"
|
||||
inoremap <buffer> <C-X>- <%<Space><Space>-%><Esc>3hi
|
||||
inoremap <buffer> <C-X>_ <C-V><NL><Esc>I<%<Space><Esc>A<Space>-%><Esc>F<NL>s
|
||||
elseif &ft == "cf"
|
||||
inoremap <buffer> <C-X>- <cf><Left>
|
||||
inoremap <buffer> <C-X>_ <cfset ><Left>
|
||||
else
|
||||
imap <buffer> <C-X>- <C-X><Lt><Space><Space><C-X>><Esc>2hi
|
||||
imap <buffer> <C-X>_ <C-V><NL><Esc>I<C-X><Lt><Space><Esc>A<Space><C-X>><Esc>F<NL>s
|
||||
endif
|
||||
" Comments
|
||||
if &ft =~ '^asp'
|
||||
imap <buffer> <C-X>' <C-X><Lt>'<Space><Space><C-X>><Esc>2hi
|
||||
imap <buffer> <C-X>" <C-V><NL><Esc>I<C-X><Lt>'<Space><Esc>A<Space><C-X>><Esc>F<NL>s
|
||||
let b:surround_35 = maparg("<C-X><Lt>","i")."' \r ".maparg("<C-X>>","i")
|
||||
elseif &ft == "jsp"
|
||||
inoremap <buffer> <C-X>' <Lt>%--<Space><Space>--%><Esc>4hi
|
||||
inoremap <buffer> <C-X>" <C-V><NL><Esc>I<%--<Space><Esc>A<Space>--%><Esc>F<NL>s
|
||||
let b:surround_35 = "<%-- \r --%>"
|
||||
elseif &ft == "cf"
|
||||
inoremap <buffer> <C-X>' <Lt>!---<Space><Space>---><Esc>4hi
|
||||
inoremap <buffer> <C-X>" <C-V><NL><Esc>I<!---<Space><Esc>A<Space>---><Esc>F<NL>s
|
||||
setlocal commentstring=<!---%s--->
|
||||
let b:surround_35 = "<!--- \r --->"
|
||||
elseif &ft == "html" || &ft == "xml" || &ft == "xhtml"
|
||||
inoremap <buffer> <C-X>' <Lt>!--<Space><Space>--><Esc>3hi
|
||||
inoremap <buffer> <C-X>" <C-V><NL><Esc>I<!--<Space><Esc>A<Space>--><Esc>F<NL>s
|
||||
let b:surround_35 = "<!-- \r -->"
|
||||
elseif &ft == "django"
|
||||
inoremap <buffer> <C-X>' {#<Space><Space>#}<Esc>2hi
|
||||
inoremap <buffer> <C-X>" <C-V><NL><Esc>I<C-X>{#<Space><Esc>A<Space>#}<Esc>F<NL>s
|
||||
let b:surround_35 = "{# \r #}"
|
||||
else
|
||||
imap <buffer> <C-X>' <C-X><Lt>#<Space><Space><C-X>><Esc>2hi
|
||||
imap <buffer> <C-X>" <C-V><NL><Esc>I<C-X><Lt>#<Space><Esc>A<Space><C-X>><Esc>F<NL>s
|
||||
let b:surround_35 = maparg("<C-X><Lt>","i")."# \r ".maparg("<C-X>>","i")
|
||||
endif
|
||||
imap <buffer> <C-X>% <Plug>ragtagUrlEncode
|
||||
imap <buffer> <C-X>& <Plug>ragtagXmlEncode
|
||||
imap <buffer> <C-V>% <Plug>ragtagUrlV
|
||||
imap <buffer> <C-V>& <Plug>ragtagXmlV
|
||||
if !exists("b:did_indent")
|
||||
if s:subtype() == "xml"
|
||||
runtime! indent/xml.vim
|
||||
else
|
||||
runtime! indent/html.vim
|
||||
endif
|
||||
endif
|
||||
" Pet peeve. Do people still not close their <p> and <li> tags?
|
||||
if exists("g:html_indent_tags") && g:html_indent_tags !~ '\\|p\>'
|
||||
let g:html_indent_tags = g:html_indent_tags.'\|p\|li\|dt\|dd'
|
||||
endif
|
||||
set indentkeys+=!^F
|
||||
let b:surround_indent = 1
|
||||
silent doautocmd User ragtag
|
||||
silent doautocmd User allml
|
||||
endfunction
|
||||
|
||||
function! s:Leave()
|
||||
call s:disableescape()
|
||||
endfunction
|
||||
|
||||
function! s:length(str)
|
||||
return strlen(substitute(a:str,'.','.','g'))
|
||||
endfunction
|
||||
|
||||
function! s:repeat(str,cnt)
|
||||
let cnt = a:cnt
|
||||
let str = ""
|
||||
while cnt > 0
|
||||
let str = str . a:str
|
||||
let cnt = cnt - 1
|
||||
endwhile
|
||||
return str
|
||||
endfunction
|
||||
|
||||
function! s:doctypeSeek()
|
||||
if !exists("b:ragtag_doctype_index")
|
||||
if exists("b:allml_doctype_index")
|
||||
let b:ragtag_doctype_index = b:allml_doctype_index
|
||||
elseif &ft == 'xhtml' || &ft == 'eruby'
|
||||
let b:ragtag_doctype_index = 10
|
||||
elseif &ft != 'xml'
|
||||
let b:ragtag_doctype_index = 7
|
||||
endif
|
||||
endif
|
||||
let index = b:ragtag_doctype_index - 1
|
||||
return (index < 0 ? s:repeat("\<C-P>",-index) : s:repeat("\<C-N>",index))
|
||||
endfunction
|
||||
|
||||
function! s:stylesheetTag()
|
||||
if !exists("b:ragtag_stylesheet_link_tag")
|
||||
if exists("b:allml_stylesheet_link_tag")
|
||||
let b:ragtag_stylesheet_link_tag = b:allml_stylesheet_link_tag
|
||||
else
|
||||
let b:ragtag_stylesheet_link_tag = "<link rel=\"stylesheet\" type=\"text/css\" href=\"/stylesheets/\r.css\" />"
|
||||
endif
|
||||
endif
|
||||
return s:insertTag(b:ragtag_stylesheet_link_tag)
|
||||
endfunction
|
||||
|
||||
function! s:javascriptIncludeTag()
|
||||
if !exists("b:ragtag_javascript_include_tag")
|
||||
if exists("b:allml_javascript_include_tag")
|
||||
let b:ragtag_javascript_include_tag = b:allml_javascript_include_tag
|
||||
else
|
||||
let b:ragtag_javascript_include_tag = "<script type=\"text/javascript\" src=\"/javascripts/\r.js\"></script>"
|
||||
endif
|
||||
endif
|
||||
return s:insertTag(b:ragtag_javascript_include_tag)
|
||||
endfunction
|
||||
|
||||
function! s:insertTag(tag)
|
||||
let tag = a:tag
|
||||
if s:subtype() == "html"
|
||||
let tag = substitute(a:tag,'\s*/>','>','g')
|
||||
endif
|
||||
let before = matchstr(tag,'^.\{-\}\ze\r')
|
||||
let after = matchstr(tag,'\r\zs\%(.*\r\)\@!.\{-\}$')
|
||||
" middle isn't currently used
|
||||
let middle = matchstr(tag,'\r\zs.\{-\}\ze\r')
|
||||
return before.after.s:repeat("\<Left>",s:length(after))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:htmlEn()
|
||||
let b:ragtag_omni = &l:omnifunc
|
||||
let b:ragtag_isk = &l:isk
|
||||
" : is for namespaced xml attributes
|
||||
setlocal omnifunc=htmlcomplete#CompleteTags isk+=:
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! s:htmlDis()
|
||||
if exists("b:ragtag_omni")
|
||||
let &l:omnifunc = b:ragtag_omni
|
||||
unlet b:ragtag_omni
|
||||
endif
|
||||
if exists("b:ragtag_isk")
|
||||
let &l:isk = b:ragtag_isk
|
||||
unlet b:ragtag_isk
|
||||
endif
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! s:subtype()
|
||||
let top = getline(1)."\n".getline(2)
|
||||
if (top =~ '<?xml\>' && &ft !~? 'html') || &ft =~? '^\%(xml\|xsd\|xslt\)$'
|
||||
return "xml"
|
||||
elseif top =~? '\<xhtml\>'
|
||||
return 'xhtml'
|
||||
elseif top =~ '[^<]\<html\>'
|
||||
return "html"
|
||||
elseif &ft == "xhtml" || &ft == "eruby"
|
||||
return "xhtml"
|
||||
elseif exists("b:loaded_ragtag")
|
||||
return "html"
|
||||
else
|
||||
return ""
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:closetagback()
|
||||
if s:subtype() == "html"
|
||||
return ">\<Left>"
|
||||
else
|
||||
return " />\<Left>\<Left>\<Left>"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:closetag()
|
||||
if s:subtype() == "html"
|
||||
return ">"
|
||||
else
|
||||
return " />"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:charset()
|
||||
let enc = &fileencoding
|
||||
if enc == ""
|
||||
let enc = &encoding
|
||||
endif
|
||||
if enc == "latin1"
|
||||
return "ISO-8859-1"
|
||||
elseif enc == ""
|
||||
return "US-ASCII"
|
||||
else
|
||||
return enc
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:tagextras()
|
||||
if s:subtype() == "xml"
|
||||
return ""
|
||||
elseif @" == 'html' && s:subtype() == 'xhtml'
|
||||
let lang = "en"
|
||||
if exists("$LANG") && $LANG =~ '^..'
|
||||
let lang = strpart($LANG,0,2)
|
||||
endif
|
||||
return ' xmlns="http://www.w3.org/1999/xhtml" lang="'.lang.'" xml:lang="'.lang.'"'
|
||||
elseif @" == 'style'
|
||||
return ' type="text/css"'
|
||||
elseif @" == 'script'
|
||||
return ' type="text/javascript"'
|
||||
elseif @" == 'table'
|
||||
return ' cellspacing="0"'
|
||||
else
|
||||
return ""
|
||||
endif
|
||||
endfunction
|
||||
|
||||
inoremap <silent> <SID>urlspace <C-R>=<SID>getinput()=~?'\%([?&]\<Bar>&\)[%a-z0-9._~+-]*=[%a-z0-9._~+-]*$'?'+':'%20'<CR>
|
||||
|
||||
function! s:urltab(htmlesc)
|
||||
let line = s:getinput()
|
||||
let g:line = line
|
||||
if line =~ '[^ <>"'."'".']\@<!\w\+$'
|
||||
return ":"
|
||||
elseif line =~ '[^ <>"'."'".']\@<!\w\+:/\=/\=[%a-z0-9._~+-]*$'
|
||||
return "/"
|
||||
elseif line =~? '\%([?&]\|&\)[%a-z0-9._~+-]*$'
|
||||
return "="
|
||||
elseif line =~? '\%([?&]\|&\)[%a-z0-9._~+-]*=[%a-z0-9._~+-]*$'
|
||||
if a:htmlesc || synIDattr(synID(line('.'),col('.')-1,1),"name") =~ 'mlString$'
|
||||
return "&"
|
||||
else
|
||||
return "&"
|
||||
endif
|
||||
elseif line =~ '/$\|\.\w\+$'
|
||||
return "?"
|
||||
else
|
||||
return "/"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:toggleurlescape()
|
||||
let htmllayer = 0
|
||||
if exists("b:ragtag_escape_mode")
|
||||
if b:ragtag_escape_mode == "url"
|
||||
call s:disableescape()
|
||||
return ""
|
||||
elseif b:ragtag_escape_mode == "xml"
|
||||
let htmllayer = 1
|
||||
endif
|
||||
call s:disableescape()
|
||||
endif
|
||||
let b:ragtag_escape_mode = "url"
|
||||
imap <buffer> <BS> <Plug>ragtagBSUrl
|
||||
inoremap <buffer> <CR> %0A
|
||||
imap <script> <buffer> <Space> <SID>urlspace
|
||||
inoremap <buffer> <Tab> &
|
||||
inoremap <buffer> <Bar> %7C
|
||||
if htmllayer
|
||||
inoremap <silent> <buffer> <Tab> <C-R>=<SID>urltab(1)<CR>
|
||||
else
|
||||
inoremap <silent> <buffer> <Tab> <C-R>=<SID>urltab(0)<CR>
|
||||
endif
|
||||
let i = 33
|
||||
while i < 127
|
||||
" RFC3986: reserved = :/?#[]@ !$&'()*+,;=
|
||||
if nr2char(i) =~# '[|=A-Za-z0-9_.~-]'
|
||||
else
|
||||
call s:urlmap(nr2char(i))
|
||||
endif
|
||||
let i = i + 1
|
||||
endwhile
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! s:urlencode(char)
|
||||
let i = 0
|
||||
let repl = ""
|
||||
while i < strlen(a:char)
|
||||
let repl = repl . printf("%%%02X",char2nr(strpart(a:char,i,1)))
|
||||
let i = i + 1
|
||||
endwhile
|
||||
return repl
|
||||
endfunction
|
||||
|
||||
function! s:urlmap(char)
|
||||
let repl = s:urlencode(a:char)
|
||||
exe "inoremap <buffer> ".a:char." ".repl
|
||||
endfunction
|
||||
|
||||
function! s:urlv()
|
||||
return s:urlencode(nr2char(getchar()))
|
||||
endfunction
|
||||
|
||||
function! s:togglexmlescape()
|
||||
if exists("b:ragtag_escape_mode")
|
||||
if b:ragtag_escape_mode == "xml"
|
||||
call s:disableescape()
|
||||
return ""
|
||||
endif
|
||||
call s:disableescape()
|
||||
endif
|
||||
let b:ragtag_escape_mode = "xml"
|
||||
imap <buffer> <BS> <Plug>ragtagBSXml
|
||||
inoremap <buffer> <Lt> <
|
||||
inoremap <buffer> > >
|
||||
inoremap <buffer> & &
|
||||
inoremap <buffer> " "
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! s:disableescape()
|
||||
if exists("b:ragtag_escape_mode")
|
||||
if b:ragtag_escape_mode == "xml"
|
||||
silent! iunmap <buffer> <BS>
|
||||
silent! iunmap <buffer> <Lt>
|
||||
silent! iunmap <buffer> >
|
||||
silent! iunmap <buffer> &
|
||||
silent! iunmap <buffer> "
|
||||
elseif b:ragtag_escape_mode == "url"
|
||||
silent! iunmap <buffer> <BS>
|
||||
silent! iunmap <buffer> <Tab>
|
||||
silent! iunmap <buffer> <CR>
|
||||
silent! iunmap <buffer> <Space>
|
||||
silent! iunmap <buffer> <Bar>
|
||||
let i = 33
|
||||
while i < 127
|
||||
if nr2char(i) =~# '[|A-Za-z0-9_.~-]'
|
||||
else
|
||||
exe "silent! iunmap <buffer> ".nr2char(i)
|
||||
endif
|
||||
let i = i + 1
|
||||
endwhile
|
||||
endif
|
||||
unlet b:ragtag_escape_mode
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:getinput()
|
||||
return strpart(getline('.'),0,col('.')-1)
|
||||
endfunction
|
||||
|
||||
function! s:bspattern(pattern)
|
||||
let start = s:getinput()
|
||||
let match = matchstr(start,'\%('.a:pattern.'\)$')
|
||||
if match == ""
|
||||
return "\<BS>"
|
||||
else
|
||||
return s:repeat("\<BS>",strlen(match))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
inoremap <silent> <Plug>ragtagBSUrl <C-R>=<SID>bspattern('%\x\x\=\<Bar>&')<CR>
|
||||
inoremap <silent> <Plug>ragtagBSXml <C-R>=<SID>bspattern('&#\=\w*;\<Bar><[^><]*>\=')<CR>
|
||||
inoremap <silent> <SID>ragtagUrlEncode <C-R>=<SID>toggleurlescape()<CR>
|
||||
inoremap <silent> <SID>ragtagXmlEncode <C-R>=<SID>togglexmlescape()<CR>
|
||||
inoremap <silent> <Plug>ragtagUrlEncode <C-R>=<SID>toggleurlescape()<CR>
|
||||
inoremap <silent> <Plug>ragtagXmlEncode <C-R>=<SID>togglexmlescape()<CR>
|
||||
inoremap <silent> <Plug>ragtagUrlV <C-R>=<SID>urlv()<CR>
|
||||
inoremap <silent> <Plug>ragtagXmlV <C-R>="&#".getchar().";"<CR>
|
||||
|
||||
if exists("g:ragtag_global_maps")
|
||||
imap <C-X>H <Plug>ragtagHtmlComplete
|
||||
imap <C-X>/ </<Plug>ragtagHtmlComplete
|
||||
imap <C-X>% <Plug>ragtagUrlEncode
|
||||
imap <C-X>& <Plug>ragtagXmlEncode
|
||||
imap <C-V>% <Plug>ragtagUrlV
|
||||
imap <C-V>& <Plug>ragtagXmlV
|
||||
endif
|
||||
340
vim/plugin/rails.vim
Executable file
340
vim/plugin/rails.vim
Executable file
@@ -0,0 +1,340 @@
|
||||
" rails.vim - Detect a rails application
|
||||
" Author: Tim Pope <vimNOSPAM@tpope.org>
|
||||
" GetLatestVimScripts: 1567 1 :AutoInstall: rails.vim
|
||||
" URL: http://rails.vim.tpope.net/
|
||||
|
||||
" Install this file as plugin/rails.vim. See doc/rails.txt for details. (Grab
|
||||
" it from the URL above if you don't have it.) To access it from Vim, see
|
||||
" :help add-local-help (hint: :helptags ~/.vim/doc) Afterwards, you should be
|
||||
" able to do :help rails
|
||||
|
||||
if exists('g:loaded_rails') || &cp || v:version < 700
|
||||
finish
|
||||
endif
|
||||
let g:loaded_rails = 1
|
||||
|
||||
" Utility Functions {{{1
|
||||
|
||||
function! s:error(str)
|
||||
echohl ErrorMsg
|
||||
echomsg a:str
|
||||
echohl None
|
||||
let v:errmsg = a:str
|
||||
endfunction
|
||||
|
||||
function! s:autoload(...)
|
||||
if !exists("g:autoloaded_rails") && v:version >= 700
|
||||
runtime! autoload/rails.vim
|
||||
endif
|
||||
if exists("g:autoloaded_rails")
|
||||
if a:0
|
||||
exe a:1
|
||||
endif
|
||||
return 1
|
||||
endif
|
||||
if !exists("g:rails_no_autoload_warning")
|
||||
let g:rails_no_autoload_warning = 1
|
||||
if v:version >= 700
|
||||
call s:error("Disabling rails.vim: autoload/rails.vim is missing")
|
||||
else
|
||||
call s:error("Disabling rails.vim: Vim version 7 or higher required")
|
||||
endif
|
||||
endif
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
" Configuration {{{
|
||||
|
||||
function! s:SetOptDefault(opt,val)
|
||||
if !exists("g:".a:opt)
|
||||
let g:{a:opt} = a:val
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:SetOptDefault("rails_statusline",1)
|
||||
call s:SetOptDefault("rails_syntax",1)
|
||||
call s:SetOptDefault("rails_mappings",1)
|
||||
call s:SetOptDefault("rails_abbreviations",1)
|
||||
call s:SetOptDefault("rails_ctags_arguments","--exclude=\"*.js\"")
|
||||
call s:SetOptDefault("rails_default_file","README")
|
||||
call s:SetOptDefault("rails_root_url",'http://localhost:3000/')
|
||||
call s:SetOptDefault("rails_modelines",0)
|
||||
call s:SetOptDefault("rails_menu",!has('mac'))
|
||||
call s:SetOptDefault("rails_gnu_screen",1)
|
||||
call s:SetOptDefault("rails_history_size",5)
|
||||
call s:SetOptDefault("rails_generators","controller\ngenerator\nhelper\nintegration_test\nmailer\nmetal\nmigration\nmodel\nobserver\nperformance_test\nplugin\nresource\nscaffold\nscaffold_controller\nsession_migration\nstylesheets")
|
||||
if exists("g:loaded_dbext") && executable("sqlite3") && ! executable("sqlite")
|
||||
" Since dbext can't find it by itself
|
||||
call s:SetOptDefault("dbext_default_SQLITE_bin","sqlite3")
|
||||
endif
|
||||
|
||||
" }}}1
|
||||
" Detection {{{1
|
||||
|
||||
function! s:escvar(r)
|
||||
let r = fnamemodify(a:r,':~')
|
||||
let r = substitute(r,'\W','\="_".char2nr(submatch(0))."_"','g')
|
||||
let r = substitute(r,'^\d','_&','')
|
||||
return r
|
||||
endfunction
|
||||
|
||||
function! s:Detect(filename)
|
||||
let fn = substitute(fnamemodify(a:filename,":p"),'\c^file://','','')
|
||||
let sep = matchstr(fn,'^[^\\/]\{3,\}\zs[\\/]')
|
||||
if sep != ""
|
||||
let fn = getcwd().sep.fn
|
||||
endif
|
||||
if fn =~ '[\/]config[\/]environment\.rb$'
|
||||
return s:BufInit(strpart(fn,0,strlen(fn)-22))
|
||||
endif
|
||||
if isdirectory(fn)
|
||||
let fn = fnamemodify(fn,':s?[\/]$??')
|
||||
else
|
||||
let fn = fnamemodify(fn,':s?\(.*\)[\/][^\/]*$?\1?')
|
||||
endif
|
||||
let ofn = ""
|
||||
let nfn = fn
|
||||
while nfn != ofn && nfn != ""
|
||||
if exists("s:_".s:escvar(nfn))
|
||||
return s:BufInit(nfn)
|
||||
endif
|
||||
let ofn = nfn
|
||||
let nfn = fnamemodify(nfn,':h')
|
||||
endwhile
|
||||
let ofn = ""
|
||||
while fn != ofn
|
||||
if filereadable(fn . "/config/environment.rb")
|
||||
return s:BufInit(fn)
|
||||
endif
|
||||
let ofn = fn
|
||||
let fn = fnamemodify(ofn,':s?\(.*\)[\/]\(app\|config\|db\|doc\|features\|lib\|log\|public\|script\|spec\|stories\|test\|tmp\|vendor\)\($\|[\/].*$\)?\1?')
|
||||
endwhile
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:BufInit(path)
|
||||
let s:_{s:escvar(a:path)} = 1
|
||||
if s:autoload()
|
||||
return RailsBufInit(a:path)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
" Initialization {{{1
|
||||
|
||||
augroup railsPluginDetect
|
||||
autocmd!
|
||||
autocmd BufNewFile,BufRead * call s:Detect(expand("<afile>:p"))
|
||||
autocmd VimEnter * if expand("<amatch>") == "" && !exists("b:rails_root") | call s:Detect(getcwd()) | endif | if exists("b:rails_root") | silent doau User BufEnterRails | endif
|
||||
autocmd FileType netrw if !exists("b:rails_root") | call s:Detect(expand("<afile>:p")) | endif | if exists("b:rails_root") | silent doau User BufEnterRails | endif
|
||||
autocmd BufEnter * if exists("b:rails_root")|silent doau User BufEnterRails|endif
|
||||
autocmd BufLeave * if exists("b:rails_root")|silent doau User BufLeaveRails|endif
|
||||
autocmd Syntax railslog if s:autoload()|call rails#log_syntax()|endif
|
||||
augroup END
|
||||
|
||||
command! -bar -bang -nargs=* -complete=dir Rails :if s:autoload()|call rails#new_app_command(<bang>0,<f-args>)|endif
|
||||
|
||||
" }}}1
|
||||
" abolish.vim support {{{1
|
||||
|
||||
function! s:function(name)
|
||||
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
|
||||
endfunction
|
||||
|
||||
augroup railsPluginAbolish
|
||||
autocmd!
|
||||
autocmd VimEnter * call s:abolish_setup()
|
||||
augroup END
|
||||
|
||||
function! s:abolish_setup()
|
||||
if exists('g:Abolish') && has_key(g:Abolish,'Coercions')
|
||||
if !has_key(g:Abolish.Coercions,'l')
|
||||
let g:Abolish.Coercions.l = s:function('s:abolish_l')
|
||||
endif
|
||||
if !has_key(g:Abolish.Coercions,'t')
|
||||
let g:Abolish.Coercions.t = s:function('s:abolish_t')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:abolish_l(word)
|
||||
let singular = rails#singularize(a:word)
|
||||
return a:word ==? singular ? rails#pluralize(a:word) : singular
|
||||
endfunction
|
||||
|
||||
function! s:abolish_t(word)
|
||||
if a:word =~# '\u'
|
||||
return rails#pluralize(rails#underscore(a:word))
|
||||
else
|
||||
return rails#singularize(rails#camelize(a:word))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
" Menus {{{1
|
||||
|
||||
if !(g:rails_menu && has("menu"))
|
||||
finish
|
||||
endif
|
||||
|
||||
function! s:sub(str,pat,rep)
|
||||
return substitute(a:str,'\v\C'.a:pat,a:rep,'')
|
||||
endfunction
|
||||
|
||||
function! s:gsub(str,pat,rep)
|
||||
return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
|
||||
endfunction
|
||||
|
||||
function! s:menucmd(priority)
|
||||
return 'anoremenu <script> '.(exists("$CREAM") ? 87 : '').s:gsub(g:rails_installed_menu,'[^.]','').'.'.a:priority.' '
|
||||
endfunction
|
||||
|
||||
function! s:CreateMenus() abort
|
||||
if exists("g:rails_installed_menu") && g:rails_installed_menu != ""
|
||||
exe "aunmenu ".s:gsub(g:rails_installed_menu,'\&','')
|
||||
unlet g:rails_installed_menu
|
||||
endif
|
||||
if has("menu") && (exists("g:did_install_default_menus") || exists("$CREAM")) && g:rails_menu
|
||||
if g:rails_menu > 1
|
||||
let g:rails_installed_menu = '&Rails'
|
||||
else
|
||||
let g:rails_installed_menu = '&Plugin.&Rails'
|
||||
endif
|
||||
let dots = s:gsub(g:rails_installed_menu,'[^.]','')
|
||||
let menucmd = s:menucmd(200)
|
||||
if exists("$CREAM")
|
||||
exe menucmd.g:rails_installed_menu.'.-PSep- :'
|
||||
exe menucmd.g:rails_installed_menu.'.&Related\ file\ :R\ /\ Alt+] :R<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Alternate\ file\ :A\ /\ Alt+[ :A<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&File\ under\ cursor\ Ctrl+Enter :Rfind<CR>'
|
||||
else
|
||||
exe menucmd.g:rails_installed_menu.'.-PSep- :'
|
||||
exe menucmd.g:rails_installed_menu.'.&Related\ file\ :R\ /\ ]f :R<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Alternate\ file\ :A\ /\ [f :A<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&File\ under\ cursor\ gf :Rfind<CR>'
|
||||
endif
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Controller :find app/controllers/application.rb<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Helper :find app/helpers/application_helper.rb<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Javascript :find public/javascripts/application.js<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &Layout :Rlayout application<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.Application\ &README :find doc/README_FOR_APP<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.&Environment :find config/environment.rb<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.&Database\ Configuration :find config/database.yml<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.Database\ &Schema :Rmigration 0<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.R&outes :find config/routes.rb<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Other\ files.&Test\ Helper :find test/test_helper.rb<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.-FSep- :'
|
||||
exe menucmd.g:rails_installed_menu.'.Ra&ke\ :Rake :Rake<CR>'
|
||||
let menucmd = substitute(menucmd,'200 $','500 ','')
|
||||
exe menucmd.g:rails_installed_menu.'.&Server\ :Rserver.&Start\ :Rserver :Rserver<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Server\ :Rserver.&Force\ start\ :Rserver! :Rserver!<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Server\ :Rserver.&Kill\ :Rserver!\ - :Rserver! -<CR>'
|
||||
exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.&Evaluate\ Ruby\.\.\.\ :Rp :call <SID>menuprompt("Rp","Code to execute and output: ")<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Console\ :Rscript :Rscript console<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Preview\ :Rpreview :Rpreview<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Log\ file\ :Rlog :Rlog<CR>'
|
||||
exe substitute(s:sub(menucmd,'anoremenu','vnoremenu'),'<script>','<script> <silent>','').g:rails_installed_menu.'.E&xtract\ as\ partial\ :Rextract :call <SID>menuprompt("'."'".'<,'."'".'>Rextract","Partial name (e.g., template or /controller/template): ")<CR>'
|
||||
exe menucmd.g:rails_installed_menu.'.&Migration\ writer\ :Rinvert :Rinvert<CR>'
|
||||
exe menucmd.' '.g:rails_installed_menu.'.-HSep- :'
|
||||
exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.&Help\ :help\ rails :if <SID>autoload()<Bar>exe RailsHelpCommand("")<Bar>endif<CR>'
|
||||
exe substitute(menucmd,'<script>','<script> <silent>','').g:rails_installed_menu.'.Abo&ut\ :if <SID>autoload()<Bar>exe RailsHelpCommand("about")<Bar>endif<CR>'
|
||||
let g:rails_did_menus = 1
|
||||
call s:ProjectMenu()
|
||||
call s:menuBufLeave()
|
||||
if exists("b:rails_root")
|
||||
call s:menuBufEnter()
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ProjectMenu()
|
||||
if exists("g:rails_did_menus") && g:rails_history_size > 0
|
||||
if !exists("g:RAILS_HISTORY")
|
||||
let g:RAILS_HISTORY = ""
|
||||
endif
|
||||
let history = g:RAILS_HISTORY
|
||||
let menu = s:gsub(g:rails_installed_menu,'\&','')
|
||||
silent! exe "aunmenu <script> ".menu.".Projects"
|
||||
let dots = s:gsub(menu,'[^.]','')
|
||||
exe 'anoremenu <script> <silent> '.(exists("$CREAM") ? '87' : '').dots.'.100 '.menu.'.Pro&jects.&New\.\.\.\ :Rails :call <SID>menuprompt("Rails","New application path and additional arguments: ")<CR>'
|
||||
exe 'anoremenu <script> '.menu.'.Pro&jects.-FSep- :'
|
||||
while history =~ '\n'
|
||||
let proj = matchstr(history,'^.\{-\}\ze\n')
|
||||
let history = s:sub(history,'^.{-}\n','')
|
||||
exe 'anoremenu <script> '.menu.'.Pro&jects.'.s:gsub(proj,'[.\\ ]','\\&').' :e '.s:gsub(proj."/".g:rails_default_file,'[ !%#]','\\&')."<CR>"
|
||||
endwhile
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:menuBufEnter()
|
||||
if exists("g:rails_installed_menu") && g:rails_installed_menu != ""
|
||||
let menu = s:gsub(g:rails_installed_menu,'\&','')
|
||||
exe 'amenu enable '.menu.'.*'
|
||||
if RailsFileType() !~ '^view\>'
|
||||
exe 'vmenu disable '.menu.'.Extract\ as\ partial'
|
||||
endif
|
||||
if RailsFileType() !~ '^\%(db-\)\=migration$' || RailsFilePath() =~ '\<db/schema\.rb$'
|
||||
exe 'amenu disable '.menu.'.Migration\ writer'
|
||||
endif
|
||||
call s:ProjectMenu()
|
||||
silent! exe 'aunmenu '.menu.'.Rake\ tasks'
|
||||
silent! exe 'aunmenu '.menu.'.Generate'
|
||||
silent! exe 'aunmenu '.menu.'.Destroy'
|
||||
if rails#app().cache.needs('rake_tasks') || empty(rails#app().rake_tasks())
|
||||
exe substitute(s:menucmd(300),'<script>','<script> <silent>','').g:rails_installed_menu.'.Rake\ &tasks\ :Rake.Fill\ this\ menu :call rails#app().rake_tasks()<Bar>call <SID>menuBufLeave()<Bar>call <SID>menuBufEnter()<CR>'
|
||||
else
|
||||
let i = 0
|
||||
while i < len(rails#app().rake_tasks())
|
||||
let task = rails#app().rake_tasks()[i]
|
||||
exe s:menucmd(300).g:rails_installed_menu.'.Rake\ &tasks\ :Rake.'.s:sub(task,':',':.').' :Rake '.task.'<CR>'
|
||||
let i += 1
|
||||
endwhile
|
||||
endif
|
||||
let i = 0
|
||||
let menucmd = substitute(s:menucmd(400),'<script>','<script> <silent>','').g:rails_installed_menu
|
||||
while i < len(rails#app().generators())
|
||||
let generator = rails#app().generators()[i]
|
||||
exe menucmd.'.&Generate\ :Rgen.'.s:gsub(generator,'_','\\ ').' :call <SID>menuprompt("Rgenerate '.generator.'","Arguments for script/generate '.generator.': ")<CR>'
|
||||
exe menucmd.'.&Destroy\ :Rdestroy.'.s:gsub(generator,'_','\\ ').' :call <SID>menuprompt("Rdestroy '.generator.'","Arguments for script/destroy '.generator.': ")<CR>'
|
||||
let i += 1
|
||||
endwhile
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:menuBufLeave()
|
||||
if exists("g:rails_installed_menu") && g:rails_installed_menu != ""
|
||||
let menu = s:gsub(g:rails_installed_menu,'\&','')
|
||||
exe 'amenu disable '.menu.'.*'
|
||||
exe 'amenu enable '.menu.'.Help\ '
|
||||
exe 'amenu enable '.menu.'.About\ '
|
||||
exe 'amenu enable '.menu.'.Projects'
|
||||
silent! exe 'aunmenu '.menu.'.Rake\ tasks'
|
||||
silent! exe 'aunmenu '.menu.'.Generate'
|
||||
silent! exe 'aunmenu '.menu.'.Destroy'
|
||||
exe s:menucmd(300).g:rails_installed_menu.'.Rake\ tasks\ :Rake.-TSep- :'
|
||||
exe s:menucmd(400).g:rails_installed_menu.'.&Generate\ :Rgen.-GSep- :'
|
||||
exe s:menucmd(400).g:rails_installed_menu.'.&Destroy\ :Rdestroy.-DSep- :'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:menuprompt(vimcmd,prompt)
|
||||
let res = inputdialog(a:prompt,'','!!!')
|
||||
if res == '!!!'
|
||||
return ""
|
||||
endif
|
||||
exe a:vimcmd." ".res
|
||||
endfunction
|
||||
|
||||
call s:CreateMenus()
|
||||
|
||||
augroup railsPluginMenu
|
||||
autocmd!
|
||||
autocmd User BufEnterRails call s:menuBufEnter()
|
||||
autocmd User BufLeaveRails call s:menuBufLeave()
|
||||
" g:RAILS_HISTORY hasn't been set when s:InitPlugin() is called.
|
||||
autocmd VimEnter * call s:ProjectMenu()
|
||||
augroup END
|
||||
|
||||
" }}}1
|
||||
" vim:set sw=2 sts=2:
|
||||
72
vim/plugin/repeat.vim
Normal file
72
vim/plugin/repeat.vim
Normal file
@@ -0,0 +1,72 @@
|
||||
" repeat.vim - Let the repeat command repeat plugin maps
|
||||
" Maintainer: Tim Pope
|
||||
" Version: 1.0
|
||||
|
||||
" Installation:
|
||||
" Place in either ~/.vim/plugin/repeat.vim (to load at start up) or
|
||||
" ~/.vim/autoload/repeat.vim (to load automatically as needed).
|
||||
"
|
||||
" Developers:
|
||||
" Basic usage is as follows:
|
||||
"
|
||||
" silent! call repeat#set("\<Plug>MappingToRepeatCommand",3)
|
||||
"
|
||||
" The first argument is the mapping that will be invoked when the |.| key is
|
||||
" pressed. Typically, it will be the same as the mapping the user invoked.
|
||||
" This sequence will be stuffed into the input queue literally. Thus you must
|
||||
" encode special keys by prefixing them with a backslash inside double quotes.
|
||||
"
|
||||
" The second argument is the default count. This is the number that will be
|
||||
" prefixed to the mapping if no explicit numeric argument was given. The
|
||||
" value of the v:count variable is usually correct and it will be used if the
|
||||
" second parameter is omitted. If your mapping doesn't accept a numeric
|
||||
" argument and you never want to receive one, pass a value of -1.
|
||||
"
|
||||
" Make sure to call the repeat#set function _after_ making changes to the
|
||||
" file.
|
||||
|
||||
if exists("g:loaded_repeat") || &cp || v:version < 700
|
||||
finish
|
||||
endif
|
||||
let g:loaded_repeat = 1
|
||||
|
||||
let g:repeat_tick = -1
|
||||
|
||||
function! repeat#set(sequence,...)
|
||||
silent exe "norm! \"=''\<CR>p"
|
||||
let g:repeat_sequence = a:sequence
|
||||
let g:repeat_count = a:0 ? a:1 : v:count
|
||||
let g:repeat_tick = b:changedtick
|
||||
endfunction
|
||||
|
||||
function! s:repeat(count)
|
||||
if g:repeat_tick == b:changedtick
|
||||
let c = g:repeat_count
|
||||
let s = g:repeat_sequence
|
||||
let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : ''))
|
||||
call feedkeys(cnt . s)
|
||||
else
|
||||
call feedkeys((a:count ? a:count : '') . '.', 'n')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:wrap(command,count)
|
||||
let preserve = (g:repeat_tick == b:changedtick)
|
||||
exe 'norm! '.(a:count ? a:count : '').a:command
|
||||
if preserve
|
||||
let g:repeat_tick = b:changedtick
|
||||
endif
|
||||
endfunction
|
||||
|
||||
nnoremap <silent> . :<C-U>call <SID>repeat(v:count)<CR>
|
||||
nnoremap <silent> u :<C-U>call <SID>wrap('u',v:count)<CR>
|
||||
nnoremap <silent> U :<C-U>call <SID>wrap('U',v:count)<CR>
|
||||
nnoremap <silent> <C-R> :<C-U>call <SID>wrap("\<Lt>C-R>",v:count)<CR>
|
||||
|
||||
augroup repeatPlugin
|
||||
autocmd!
|
||||
autocmd BufLeave,BufWritePre,BufReadPre * let g:repeat_tick = (g:repeat_tick == b:changedtick || g:repeat_tick == 0) ? 0 : -1
|
||||
autocmd BufEnter,BufWritePost * if g:repeat_tick == 0|let g:repeat_tick = b:changedtick|endif
|
||||
augroup END
|
||||
|
||||
" vim:set ft=vim et sw=4 sts=4:
|
||||
182
vim/plugin/ruby_focused_unit_test.vim
Normal file
182
vim/plugin/ruby_focused_unit_test.vim
Normal file
@@ -0,0 +1,182 @@
|
||||
if !has("ruby")
|
||||
finish
|
||||
end
|
||||
|
||||
command RunRubyFocusedUnitTest :call <SID>RunRubyFocusedUnitTest()
|
||||
command RunRubyFocusedContext :call <SID>RunRubyFocusedContext()
|
||||
command RunAllRubyTests :call <SID>RunAllRubyTests()
|
||||
command RunLastRubyTest :call <SID>RunLastRubyTest()
|
||||
|
||||
function! s:RunRubyFocusedUnitTest()
|
||||
ruby RubyFocusedUnitTest.new.run_test
|
||||
endfunction
|
||||
|
||||
function! s:RunRubyFocusedContext()
|
||||
ruby RubyFocusedUnitTest.new.run_context
|
||||
endfunction
|
||||
|
||||
function! s:RunAllRubyTests()
|
||||
ruby RubyFocusedUnitTest.new.run_all
|
||||
endfunction
|
||||
|
||||
function! s:RunLastRubyTest()
|
||||
ruby RubyFocusedUnitTest.new.run_last
|
||||
endfunction
|
||||
|
||||
ruby << EOF
|
||||
module VIM
|
||||
class Buffer
|
||||
class << self
|
||||
include Enumerable
|
||||
|
||||
def each(&block)
|
||||
(0...VIM::Buffer.count).each do |index|
|
||||
yield self[index]
|
||||
end
|
||||
end
|
||||
|
||||
def create(name, opts={})
|
||||
location = opts[:location] || :below
|
||||
VIM.command("#{location} new #{name}")
|
||||
buf = VIM::Buffer.current
|
||||
if opts[:text]
|
||||
buf.text = opts[:text]
|
||||
end
|
||||
buf
|
||||
end
|
||||
end
|
||||
|
||||
def text=(content)
|
||||
content.split("\n").each_with_index do |line,index|
|
||||
self.append index, line
|
||||
end
|
||||
end
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
VIM.command "#{method} #{self.name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class RubyFocusedUnitTest
|
||||
DEFAULT_OUTPUT_BUFFER = "rb_test_output"
|
||||
SAVED_TEST_COMMAND_FILE = '/tmp/last_ruby_focused_unit_test'
|
||||
|
||||
def write_output_to_buffer(test_command)
|
||||
save_test_command(test_command)
|
||||
|
||||
if buffer = VIM::Buffer.find { |b| b.name =~ /#{DEFAULT_OUTPUT_BUFFER}/ }
|
||||
buffer.bdelete!
|
||||
end
|
||||
|
||||
buffer = VIM::Buffer.create DEFAULT_OUTPUT_BUFFER, :location => :below, :text => "--- Run Focused Unit Test ---\n\n"
|
||||
VIM.command("setlocal buftype=nowrite")
|
||||
VIM.command "redraw"
|
||||
|
||||
IO.popen("#{test_command} 2>&1", "r") do |io|
|
||||
begin
|
||||
loop do
|
||||
input = io.readpartial(10)
|
||||
first, *rest = input.split(/\n/, -1)
|
||||
buffer[buffer.length] = buffer[buffer.length] + first
|
||||
rest.each {|l| buffer.append buffer.length, l }
|
||||
VIM.command "redraw"
|
||||
end
|
||||
rescue EOFError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def save_test_command(test_command)
|
||||
File.open(SAVED_TEST_COMMAND_FILE, 'w') { |f| f.write(test_command) }
|
||||
end
|
||||
|
||||
def current_file
|
||||
VIM::Buffer.current.name
|
||||
end
|
||||
|
||||
def spec_file?
|
||||
current_file =~ /spec_|_spec/
|
||||
end
|
||||
|
||||
def line_number
|
||||
VIM::Buffer.current.line_number
|
||||
end
|
||||
|
||||
def run_spec
|
||||
write_output_to_buffer("#{spec_command} '#{current_file}' -l #{line_number}")
|
||||
end
|
||||
|
||||
def run_unit_test
|
||||
method_name = nil
|
||||
|
||||
(line_number + 1).downto(1) do |line_number|
|
||||
if VIM::Buffer.current[line_number] =~ /def (test_\w+)/
|
||||
method_name = $1
|
||||
break
|
||||
elsif VIM::Buffer.current[line_number] =~ /test "([^"]+)"/ ||
|
||||
VIM::Buffer.current[line_number] =~ /test '([^']+)'/
|
||||
method_name = "test_" + $1.split(" ").join("_")
|
||||
break
|
||||
elsif VIM::Buffer.current[line_number] =~ /should "([^"]+)"/ ||
|
||||
VIM::Buffer.current[line_number] =~ /should '([^']+)'/
|
||||
method_name = "\"/#{Regexp.escape($1)}/\""
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
write_output_to_buffer("ruby #{current_file} -n #{method_name}") if method_name
|
||||
end
|
||||
|
||||
def run_test
|
||||
if spec_file?
|
||||
run_spec
|
||||
else
|
||||
run_unit_test
|
||||
end
|
||||
end
|
||||
|
||||
def run_context
|
||||
method_name = nil
|
||||
context_line_number = nil
|
||||
|
||||
(line_number + 1).downto(1) do |line_number|
|
||||
if VIM::Buffer.current[line_number] =~ /(context|describe) "([^"]+)"/ ||
|
||||
VIM::Buffer.current[line_number] =~ /(context|describe) '([^']+)'/
|
||||
method_name = $2
|
||||
context_line_number = line_number
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if method_name
|
||||
if spec_file?
|
||||
write_output_to_buffer("#{spec_command} #{current_file} -l #{context_line_number}")
|
||||
else
|
||||
method_name = "\"/#{Regexp.escape(method_name)}/\""
|
||||
write_output_to_buffer("ruby #{current_file} -n #{method_name}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_all
|
||||
if spec_file?
|
||||
write_output_to_buffer("#{spec_command} '#{current_file}'")
|
||||
else
|
||||
write_output_to_buffer("ruby '#{current_file}'")
|
||||
end
|
||||
end
|
||||
|
||||
def run_last
|
||||
write_output_to_buffer(File.read(SAVED_TEST_COMMAND_FILE))
|
||||
end
|
||||
|
||||
def spec_command
|
||||
if File.exists?("Gemfile") && match = `bundle show rspec`.match(/(\d\.\d\.\d)$/)
|
||||
match.to_a.last.to_f < 2 ? "bundle exec spec" : "bundle exec rspec"
|
||||
else
|
||||
system("rspec -v > /dev/null 2>&1") ? "rspec --no-color" : "spec"
|
||||
end
|
||||
end
|
||||
end
|
||||
EOF
|
||||
293
vim/plugin/rubytest.vim
Normal file
293
vim/plugin/rubytest.vim
Normal file
@@ -0,0 +1,293 @@
|
||||
" Vim plugin for running ruby tests
|
||||
" Last Change: May 13 2009
|
||||
" Maintainer: Jan <jan.h.xie@gmail.com>
|
||||
" License: MIT License
|
||||
|
||||
if exists("rubytest_loaded")
|
||||
finish
|
||||
endif
|
||||
let rubytest_loaded = 1
|
||||
|
||||
if !exists("g:rubytest_in_quickfix")
|
||||
let g:rubytest_in_quickfix = 0
|
||||
endif
|
||||
if !exists("g:rubytest_spec_drb")
|
||||
let g:rubytest_spec_drb = 0
|
||||
endif
|
||||
if !exists("g:rubytest_cmd_test")
|
||||
let g:rubytest_cmd_test = "ruby %p"
|
||||
endif
|
||||
if !exists("g:rubytest_cmd_testcase")
|
||||
let g:rubytest_cmd_testcase = "ruby %p -n '/%c/'"
|
||||
endif
|
||||
if !exists("g:rubytest_cmd_spec")
|
||||
let g:rubytest_cmd_spec = "spec -f specdoc %p"
|
||||
endif
|
||||
if !exists("g:rubytest_cmd_example")
|
||||
let g:rubytest_cmd_example = "spec -f specdoc %p -l %c"
|
||||
endif
|
||||
if !exists("g:rubytest_cmd_feature")
|
||||
let g:rubytest_cmd_feature = "cucumber %p"
|
||||
endif
|
||||
if !exists("g:rubytest_cmd_story")
|
||||
let g:rubytest_cmd_story = "cucumber %p -n '%c'"
|
||||
endif
|
||||
|
||||
function s:FindCase(patterns)
|
||||
let ln = a:firstline
|
||||
while ln > 0
|
||||
let line = getline(ln)
|
||||
for pattern in keys(a:patterns)
|
||||
if line =~ pattern
|
||||
if s:pattern == 'spec'
|
||||
return a:patterns[pattern](ln)
|
||||
else
|
||||
return a:patterns[pattern](line)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
let ln -= 1
|
||||
endwhile
|
||||
return 'false'
|
||||
endfunction
|
||||
|
||||
|
||||
function s:EscapeBackSlash(str)
|
||||
return substitute(a:str, '\', '\\\\', 'g')
|
||||
endfunction
|
||||
|
||||
function s:RunTest()
|
||||
if s:test_scope == 1
|
||||
let cmd = g:rubytest_cmd_testcase
|
||||
elseif s:test_scope == 2
|
||||
let cmd = g:rubytest_cmd_test
|
||||
end
|
||||
|
||||
let case = s:FindCase(s:test_case_patterns['test'])
|
||||
if s:test_scope == 2 || case != 'false'
|
||||
let case = substitute(case, "'\\|\"", '.', 'g')
|
||||
let cmd = substitute(cmd, '%c', case, '')
|
||||
let cmd = substitute(cmd, '%p', s:EscapeBackSlash(@%), '')
|
||||
|
||||
if @% =~ '^test'
|
||||
let cmd = substitute(cmd, '^ruby ', 'ruby -Itest -rtest_helper ', '')
|
||||
endif
|
||||
|
||||
if g:rubytest_in_quickfix > 0
|
||||
let s:oldefm = &efm
|
||||
let &efm = s:efm . s:efm_backtrace . ',' . s:efm_ruby . ',' . s:oldefm . ',%-G%.%#'
|
||||
|
||||
cex system(cmd)
|
||||
cw
|
||||
|
||||
let &efm = s:oldefm
|
||||
else
|
||||
exe "!echo '" . cmd . "' && " . cmd
|
||||
endif
|
||||
else
|
||||
echo 'No test case found.'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function s:RunSpec()
|
||||
if s:test_scope == 1
|
||||
let cmd = g:rubytest_cmd_example
|
||||
elseif s:test_scope == 2
|
||||
let cmd = g:rubytest_cmd_spec
|
||||
endif
|
||||
|
||||
if g:rubytest_spec_drb > 0
|
||||
let cmd = cmd . " --drb"
|
||||
endif
|
||||
|
||||
let case = s:FindCase(s:test_case_patterns['spec'])
|
||||
if s:test_scope == 2 || case != 'false'
|
||||
let cmd = substitute(cmd, '%c', case, '')
|
||||
let cmd = substitute(cmd, '%p', s:EscapeBackSlash(@%), '')
|
||||
if g:rubytest_in_quickfix > 0
|
||||
let s:oldefm = &efm
|
||||
let &efm = s:efm . s:efm_backtrace . ',' . s:efm_ruby . ',' . s:oldefm . ',%-G%.%#'
|
||||
|
||||
cex system(cmd)
|
||||
cw
|
||||
|
||||
let &efm = s:oldefm
|
||||
else
|
||||
exe "!echo '" . cmd . "' && " . cmd
|
||||
endif
|
||||
else
|
||||
echo 'No spec found.'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function s:RunFeature()
|
||||
let s:old_in_quickfix = g:rubytest_in_quickfix
|
||||
let g:rubytest_in_quickfix = 0
|
||||
|
||||
if s:test_scope == 1
|
||||
let cmd = g:rubytest_cmd_story
|
||||
elseif s:test_scope == 2
|
||||
let cmd = g:rubytest_cmd_feature
|
||||
endif
|
||||
|
||||
let case = s:FindCase(s:test_case_patterns['feature'])
|
||||
if s:test_scope == 2 || case != 'false'
|
||||
let cmd = substitute(cmd, '%c', case, '')
|
||||
let cmd = substitute(cmd, '%p', s:EscapeBackSlash(@%), '')
|
||||
if g:rubytest_in_quickfix > 0
|
||||
let s:oldefm = &efm
|
||||
let &efm = s:efm . s:efm_backtrace . ',' . s:efm_ruby . ',' . s:oldefm . ',%-G%.%#'
|
||||
|
||||
cex system(cmd)
|
||||
cw
|
||||
|
||||
let &efm = s:oldefm
|
||||
else
|
||||
exe "!echo '" . cmd . "' && " . cmd
|
||||
endif
|
||||
else
|
||||
echo 'No story found.'
|
||||
endif
|
||||
|
||||
let g:rubytest_in_quickfix = s:old_in_quickfix
|
||||
endfunction
|
||||
|
||||
let s:test_patterns = {}
|
||||
let s:test_patterns['test'] = function('s:RunTest')
|
||||
let s:test_patterns['spec'] = function('s:RunSpec')
|
||||
let s:test_patterns['\.feature$'] = function('s:RunFeature')
|
||||
|
||||
function s:GetTestCaseName1(str)
|
||||
return split(a:str)[1]
|
||||
endfunction
|
||||
|
||||
function s:GetTestCaseName2(str)
|
||||
return "test_" . join(split(split(a:str, '"')[1]), '_')
|
||||
endfunction
|
||||
|
||||
function s:GetTestCaseName3(str)
|
||||
return split(a:str, '"')[1]
|
||||
endfunction
|
||||
|
||||
function s:GetTestCaseName4(str)
|
||||
return "test_" . join(split(split(a:str, "'")[1]), '_')
|
||||
endfunction
|
||||
|
||||
function s:GetTestCaseName5(str)
|
||||
return split(a:str, "'")[1]
|
||||
endfunction
|
||||
|
||||
function s:GetSpecLine(str)
|
||||
return a:str
|
||||
endfunction
|
||||
|
||||
function s:GetStoryLine(str)
|
||||
return join(split(split(a:str, "Scenario:")[1]))
|
||||
endfunction
|
||||
|
||||
let s:test_case_patterns = {}
|
||||
let s:test_case_patterns['test'] = {'^\s*def test':function('s:GetTestCaseName1'), '^\s*test \s*"':function('s:GetTestCaseName2'), "^\\s*test \\s*'":function('s:GetTestCaseName4'), '^\s*should \s*"':function('s:GetTestCaseName3'), "^\\s*should \\s*'":function('s:GetTestCaseName5')}
|
||||
let s:test_case_patterns['spec'] = {'^\s*\(it\|example\|describe\|context\) \s*':function('s:GetSpecLine')}
|
||||
let s:test_case_patterns['feature'] = {'^\s*Scenario:':function('s:GetStoryLine')}
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if !hasmapto('<Plug>RubyTestRun')
|
||||
map <unique> <Leader>rt <Plug>RubyTestRun
|
||||
endif
|
||||
if !hasmapto('<Plug>RubyFileRun')
|
||||
map <unique> <Leader>rT <Plug>RubyFileRun
|
||||
endif
|
||||
|
||||
function s:IsRubyTest()
|
||||
for pattern in keys(s:test_patterns)
|
||||
if @% =~ pattern
|
||||
let s:pattern = pattern
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function s:Run(scope)
|
||||
if !s:IsRubyTest()
|
||||
echo "This file doesn't contain ruby test."
|
||||
else
|
||||
" test scope define what to test
|
||||
" 1: test case under cursor
|
||||
" 2: all tests in file
|
||||
let s:test_scope = a:scope
|
||||
call s:test_patterns[s:pattern]()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
noremap <unique> <script> <Plug>RubyTestRun <SID>Run
|
||||
noremap <unique> <script> <Plug>RubyFileRun <SID>RunFile
|
||||
noremap <SID>Run :call <SID>Run(1)<CR>
|
||||
noremap <SID>RunFile :call <SID>Run(2)<CR>
|
||||
|
||||
let s:efm='%A%\\d%\\+)%.%#,'
|
||||
|
||||
" below errorformats are copied from rails.vim
|
||||
" Current directory
|
||||
let s:efm=s:efm . '%D(in\ %f),'
|
||||
" Failure and Error headers, start a multiline message
|
||||
let s:efm=s:efm
|
||||
\.'%A\ %\\+%\\d%\\+)\ Failure:,'
|
||||
\.'%A\ %\\+%\\d%\\+)\ Error:,'
|
||||
\.'%+A'."'".'%.%#'."'".'\ FAILED,'
|
||||
" Exclusions
|
||||
let s:efm=s:efm
|
||||
\.'%C%.%#(eval)%.%#,'
|
||||
\.'%C-e:%.%#,'
|
||||
\.'%C%.%#/lib/gems/%\\d.%\\d/gems/%.%#,'
|
||||
\.'%C%.%#/lib/ruby/%\\d.%\\d/%.%#,'
|
||||
\.'%C%.%#/vendor/rails/%.%#,'
|
||||
" Specific to template errors
|
||||
let s:efm=s:efm
|
||||
\.'%C\ %\\+On\ line\ #%l\ of\ %f,'
|
||||
\.'%CActionView::TemplateError:\ compile\ error,'
|
||||
" stack backtrace is in brackets. if multiple lines, it starts on a new line.
|
||||
let s:efm=s:efm
|
||||
\.'%Ctest_%.%#(%.%#):%#,'
|
||||
\.'%C%.%#\ [%f:%l]:,'
|
||||
\.'%C\ \ \ \ [%f:%l:%.%#,'
|
||||
\.'%C\ \ \ \ %f:%l:%.%#,'
|
||||
\.'%C\ \ \ \ \ %f:%l:%.%#]:,'
|
||||
\.'%C\ \ \ \ \ %f:%l:%.%#,'
|
||||
" Catch all
|
||||
let s:efm=s:efm
|
||||
\.'%Z%f:%l:\ %#%m,'
|
||||
\.'%Z%f:%l:,'
|
||||
\.'%C%m,'
|
||||
" Syntax errors in the test itself
|
||||
let s:efm=s:efm
|
||||
\.'%.%#.rb:%\\d%\\+:in\ `load'."'".':\ %f:%l:\ syntax\ error\\\, %m,'
|
||||
\.'%.%#.rb:%\\d%\\+:in\ `load'."'".':\ %f:%l:\ %m,'
|
||||
" And required files
|
||||
let s:efm=s:efm
|
||||
\.'%.%#:in\ `require'."'".':in\ `require'."'".':\ %f:%l:\ syntax\ error\\\, %m,'
|
||||
\.'%.%#:in\ `require'."'".':in\ `require'."'".':\ %f:%l:\ %m,'
|
||||
" Exclusions
|
||||
let s:efm=s:efm
|
||||
\.'%-G%.%#/lib/gems/%\\d.%\\d/gems/%.%#,'
|
||||
\.'%-G%.%#/lib/ruby/%\\d.%\\d/%.%#,'
|
||||
\.'%-G%.%#/vendor/rails/%.%#,'
|
||||
\.'%-G%.%#%\\d%\\d:%\\d%\\d:%\\d%\\d%.%#,'
|
||||
" Final catch all for one line errors
|
||||
let s:efm=s:efm
|
||||
\.'%-G%\\s%#from\ %.%#,'
|
||||
\.'%f:%l:\ %#%m,'
|
||||
|
||||
let s:efm_backtrace='%D(in\ %f),'
|
||||
\.'%\\s%#from\ %f:%l:%m,'
|
||||
\.'%\\s%#from\ %f:%l:,'
|
||||
\.'%\\s#{RAILS_ROOT}/%f:%l:\ %#%m,'
|
||||
\.'%\\s%#[%f:%l:\ %#%m,'
|
||||
\.'%\\s%#%f:%l:\ %#%m,'
|
||||
\.'%\\s%#%f:%l:,'
|
||||
\.'%m\ [%f:%l]:'
|
||||
|
||||
let s:efm_ruby='\%-E-e:%.%#,\%+E%f:%l:\ parse\ error,%W%f:%l:\ warning:\ %m,%E%f:%l:in\ %*[^:]:\ %m,%E%f:%l:\ %m,%-C%\tfrom\ %f:%l:in\ %.%#,%-Z%\tfrom\ %f:%l,%-Z%p^'
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
226
vim/plugin/snipMate.vim
Normal file
226
vim/plugin/snipMate.vim
Normal file
@@ -0,0 +1,226 @@
|
||||
" File: snipMate.vim
|
||||
" Author: Michael Sanders
|
||||
" Version: 0.82
|
||||
" Description: snipMate.vim implements some of TextMate's snippets features in
|
||||
" Vim. A snippet is a piece of often-typed text that you can
|
||||
" insert into your document using a trigger word followed by a "<tab>".
|
||||
"
|
||||
" For more help see snipMate.txt; you can do this by using:
|
||||
" :helptags ~/.vim/doc
|
||||
" :h snipMate.txt
|
||||
|
||||
if exists('loaded_snips') || &cp || version < 700
|
||||
finish
|
||||
endif
|
||||
let loaded_snips = 1
|
||||
if !exists('snips_author') | let snips_author = 'Me' | endif
|
||||
|
||||
au BufRead,BufNewFile *.snippets\= set ft=snippet
|
||||
au FileType snippet setl noet fdm=indent
|
||||
|
||||
let s:snippets = {} | let s:multi_snips = {}
|
||||
|
||||
if !exists('snippets_dir')
|
||||
let snippets_dir = substitute(globpath(&rtp, 'snippets/'), "\n", ',', 'g')
|
||||
endif
|
||||
|
||||
fun! MakeSnip(scope, trigger, content, ...)
|
||||
let multisnip = a:0 && a:1 != ''
|
||||
let var = multisnip ? 's:multi_snips' : 's:snippets'
|
||||
if !has_key({var}, a:scope) | let {var}[a:scope] = {} | endif
|
||||
if !has_key({var}[a:scope], a:trigger)
|
||||
let {var}[a:scope][a:trigger] = multisnip ? [[a:1, a:content]] : a:content
|
||||
elseif multisnip | let {var}[a:scope][a:trigger] += [[a:1, a:content]]
|
||||
else
|
||||
"echom 'Warning in snipMate.vim: Snippet '.a:trigger.' is already defined.'
|
||||
" \ .' See :h multi_snip for help on snippets with multiple matches.'
|
||||
endif
|
||||
endf
|
||||
|
||||
fun! ExtractSnips(dir, ft)
|
||||
for path in split(globpath(a:dir, '*'), "\n")
|
||||
if isdirectory(path)
|
||||
let pathname = fnamemodify(path, ':t')
|
||||
for snipFile in split(globpath(path, '*.snippet'), "\n")
|
||||
call s:ProcessFile(snipFile, a:ft, pathname)
|
||||
endfor
|
||||
elseif fnamemodify(path, ':e') == 'snippet'
|
||||
call s:ProcessFile(path, a:ft)
|
||||
endif
|
||||
endfor
|
||||
endf
|
||||
|
||||
" Processes a single-snippet file; optionally add the name of the parent
|
||||
" directory for a snippet with multiple matches.
|
||||
fun s:ProcessFile(file, ft, ...)
|
||||
let keyword = fnamemodify(a:file, ':t:r')
|
||||
if keyword == '' | return | endif
|
||||
try
|
||||
let text = join(readfile(a:file), "\n")
|
||||
catch /E484/
|
||||
echom "Error in snipMate.vim: couldn't read file: ".a:file
|
||||
endtry
|
||||
return a:0 ? MakeSnip(a:ft, a:1, text, keyword)
|
||||
\ : MakeSnip(a:ft, keyword, text)
|
||||
endf
|
||||
|
||||
fun! ExtractSnipsFile(file, ft)
|
||||
if !filereadable(a:file) | return | endif
|
||||
let text = readfile(a:file)
|
||||
let inSnip = 0
|
||||
for line in text + ["\n"]
|
||||
if inSnip && (line[0] == "\t" || line == '')
|
||||
let content .= strpart(line, 1)."\n"
|
||||
continue
|
||||
elseif inSnip
|
||||
call MakeSnip(a:ft, trigger, content[:-2], name)
|
||||
let inSnip = 0
|
||||
endif
|
||||
|
||||
if line[:6] == 'snippet'
|
||||
let inSnip = 1
|
||||
let trigger = strpart(line, 8)
|
||||
let name = ''
|
||||
let space = stridx(trigger, ' ') + 1
|
||||
if space " Process multi snip
|
||||
let name = strpart(trigger, space)
|
||||
let trigger = strpart(trigger, 0, space - 1)
|
||||
endif
|
||||
let content = ''
|
||||
endif
|
||||
endfor
|
||||
endf
|
||||
|
||||
fun! ResetSnippets()
|
||||
let s:snippets = {} | let s:multi_snips = {} | let g:did_ft = {}
|
||||
endf
|
||||
|
||||
let g:did_ft = {}
|
||||
fun! GetSnippets(dir, filetypes)
|
||||
for ft in split(a:filetypes, '\.')
|
||||
if has_key(g:did_ft, ft) | continue | endif
|
||||
call s:DefineSnips(a:dir, ft, ft)
|
||||
if ft == 'objc' || ft == 'cpp' || ft == 'cs'
|
||||
call s:DefineSnips(a:dir, 'c', ft)
|
||||
elseif ft == 'xhtml'
|
||||
call s:DefineSnips(a:dir, 'html', 'xhtml')
|
||||
endif
|
||||
let g:did_ft[ft] = 1
|
||||
endfor
|
||||
endf
|
||||
|
||||
" Define "aliasft" snippets for the filetype "realft".
|
||||
fun s:DefineSnips(dir, aliasft, realft)
|
||||
for path in split(globpath(a:dir, a:aliasft.'/')."\n".
|
||||
\ globpath(a:dir, a:aliasft.'-*/'), "\n")
|
||||
call ExtractSnips(path, a:realft)
|
||||
endfor
|
||||
for path in split(globpath(a:dir, a:aliasft.'.snippets')."\n".
|
||||
\ globpath(a:dir, a:aliasft.'-*.snippets'), "\n")
|
||||
call ExtractSnipsFile(path, a:realft)
|
||||
endfor
|
||||
endf
|
||||
|
||||
fun! TriggerSnippet()
|
||||
if exists('g:SuperTabMappingForward')
|
||||
if g:SuperTabMappingForward == "<tab>"
|
||||
let SuperTabKey = "\<c-n>"
|
||||
elseif g:SuperTabMappingBackward == "<tab>"
|
||||
let SuperTabKey = "\<c-p>"
|
||||
endif
|
||||
endif
|
||||
|
||||
if pumvisible() " Update snippet if completion is used, or deal with supertab
|
||||
if exists('SuperTabKey')
|
||||
call feedkeys(SuperTabKey) | return ''
|
||||
endif
|
||||
call feedkeys("\<esc>a", 'n') " Close completion menu
|
||||
call feedkeys("\<tab>") | return ''
|
||||
endif
|
||||
|
||||
if exists('g:snipPos') | return snipMate#jumpTabStop() | endif
|
||||
|
||||
let word = matchstr(getline('.'), '\S\+\%'.col('.').'c')
|
||||
for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
|
||||
let [trigger, snippet] = s:GetSnippet(word, scope)
|
||||
" If word is a trigger for a snippet, delete the trigger & expand
|
||||
" the snippet.
|
||||
if snippet != ''
|
||||
let col = col('.') - len(trigger)
|
||||
sil exe 's/\V'.escape(trigger, '/').'\%#//'
|
||||
return snipMate#expandSnip(snippet, col)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if exists('SuperTabKey')
|
||||
call feedkeys(SuperTabKey)
|
||||
return ''
|
||||
endif
|
||||
return "\<tab>"
|
||||
endf
|
||||
|
||||
" Check if word under cursor is snippet trigger; if it isn't, try checking if
|
||||
" the text after non-word characters is (e.g. check for "foo" in "bar.foo")
|
||||
fun s:GetSnippet(word, scope)
|
||||
let word = a:word | let snippet = ''
|
||||
while snippet == ''
|
||||
if exists('s:snippets["'.a:scope.'"]["'.escape(word, '\"').'"]')
|
||||
let snippet = s:snippets[a:scope][word]
|
||||
elseif exists('s:multi_snips["'.a:scope.'"]["'.escape(word, '\"').'"]')
|
||||
let snippet = s:ChooseSnippet(a:scope, word)
|
||||
if snippet == '' | break | endif
|
||||
else
|
||||
if match(word, '\W') == -1 | break | endif
|
||||
let word = substitute(word, '.\{-}\W', '', '')
|
||||
endif
|
||||
endw
|
||||
return [word, snippet]
|
||||
endf
|
||||
|
||||
fun s:ChooseSnippet(scope, trigger)
|
||||
let snippet = []
|
||||
let i = 1
|
||||
for snip in s:multi_snips[a:scope][a:trigger]
|
||||
let snippet += [i.'. '.snip[0]]
|
||||
let i += 1
|
||||
endfor
|
||||
if i == 2 | return s:multi_snips[a:scope][a:trigger][0][1] | endif
|
||||
let num = inputlist(snippet) - 1
|
||||
return num == -1 ? '' : s:multi_snips[a:scope][a:trigger][num][1]
|
||||
endf
|
||||
|
||||
fun! ShowAvailableSnips()
|
||||
let line = getline('.')
|
||||
let col = col('.')
|
||||
let word = matchstr(getline('.'), '\S\+\%'.col.'c')
|
||||
let words = [word]
|
||||
if stridx(word, '.')
|
||||
let words += split(word, '\.', 1)
|
||||
endif
|
||||
let matchlen = 0
|
||||
let matches = []
|
||||
for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
|
||||
let triggers = has_key(s:snippets, scope) ? keys(s:snippets[scope]) : []
|
||||
if has_key(s:multi_snips, scope)
|
||||
let triggers += keys(s:multi_snips[scope])
|
||||
endif
|
||||
for trigger in triggers
|
||||
for word in words
|
||||
if word == ''
|
||||
let matches += [trigger] " Show all matches if word is empty
|
||||
elseif trigger =~ '^'.word
|
||||
let matches += [trigger]
|
||||
let len = len(word)
|
||||
if len > matchlen | let matchlen = len | endif
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfor
|
||||
|
||||
" This is to avoid a bug with Vim when using complete(col - matchlen, matches)
|
||||
" (Issue#46 on the Google Code snipMate issue tracker).
|
||||
call setline(line('.'), substitute(line, repeat('.', matchlen).'\%'.col.'c', '', ''))
|
||||
call complete(col, matches)
|
||||
return ''
|
||||
endf
|
||||
" vim:noet:sw=4:ts=4:ft=vim
|
||||
630
vim/plugin/surround.vim
Normal file
630
vim/plugin/surround.vim
Normal file
@@ -0,0 +1,630 @@
|
||||
" surround.vim - Surroundings
|
||||
" Author: Tim Pope <vimNOSPAM@tpope.info>
|
||||
" GetLatestVimScripts: 1697 1 :AutoInstall: surround.vim
|
||||
" $Id: surround.vim,v 1.33 2008-02-04 03:50:46 tpope Exp $
|
||||
"
|
||||
" See surround.txt for help. This can be accessed by doing
|
||||
"
|
||||
" :helptags ~/.vim/doc
|
||||
" :help surround
|
||||
"
|
||||
" Licensed under the same terms as Vim itself.
|
||||
|
||||
" ============================================================================
|
||||
|
||||
" Exit quickly when:
|
||||
" - this plugin was already loaded or disabled
|
||||
" - when 'compatible' is set
|
||||
if (exists("g:loaded_surround") && g:loaded_surround) || &cp
|
||||
finish
|
||||
endif
|
||||
let g:loaded_surround = 1
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Input functions {{{1
|
||||
|
||||
function! s:getchar()
|
||||
let c = getchar()
|
||||
if c =~ '^\d\+$'
|
||||
let c = nr2char(c)
|
||||
endif
|
||||
return c
|
||||
endfunction
|
||||
|
||||
function! s:inputtarget()
|
||||
let c = s:getchar()
|
||||
while c =~ '^\d\+$'
|
||||
let c = c . s:getchar()
|
||||
endwhile
|
||||
if c == " "
|
||||
let c = c . s:getchar()
|
||||
endif
|
||||
if c =~ "\<Esc>\|\<C-C>\|\0"
|
||||
return ""
|
||||
else
|
||||
return c
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:inputreplacement()
|
||||
"echo '-- SURROUND --'
|
||||
let c = s:getchar()
|
||||
if c == " "
|
||||
let c = c . s:getchar()
|
||||
endif
|
||||
if c =~ "\<Esc>" || c =~ "\<C-C>"
|
||||
return ""
|
||||
else
|
||||
return c
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:beep()
|
||||
exe "norm! \<Esc>"
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! s:redraw()
|
||||
redraw
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" Wrapping functions {{{1
|
||||
|
||||
function! s:extractbefore(str)
|
||||
if a:str =~ '\r'
|
||||
return matchstr(a:str,'.*\ze\r')
|
||||
else
|
||||
return matchstr(a:str,'.*\ze\n')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:extractafter(str)
|
||||
if a:str =~ '\r'
|
||||
return matchstr(a:str,'\r\zs.*')
|
||||
else
|
||||
return matchstr(a:str,'\n\zs.*')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:repeat(str,count)
|
||||
let cnt = a:count
|
||||
let str = ""
|
||||
while cnt > 0
|
||||
let str = str . a:str
|
||||
let cnt = cnt - 1
|
||||
endwhile
|
||||
return str
|
||||
endfunction
|
||||
|
||||
function! s:fixindent(str,spc)
|
||||
let str = substitute(a:str,'\t',s:repeat(' ',&sw),'g')
|
||||
let spc = substitute(a:spc,'\t',s:repeat(' ',&sw),'g')
|
||||
let str = substitute(str,'\(\n\|\%^\).\@=','\1'.spc,'g')
|
||||
if ! &et
|
||||
let str = substitute(str,'\s\{'.&ts.'\}',"\t",'g')
|
||||
endif
|
||||
return str
|
||||
endfunction
|
||||
|
||||
function! s:process(string)
|
||||
let i = 0
|
||||
while i < 7
|
||||
let i = i + 1
|
||||
let repl_{i} = ''
|
||||
let m = matchstr(a:string,nr2char(i).'.\{-\}\ze'.nr2char(i))
|
||||
if m != ''
|
||||
let m = substitute(strpart(m,1),'\r.*','','')
|
||||
let repl_{i} = input(substitute(m,':\s*$','','').': ')
|
||||
endif
|
||||
endwhile
|
||||
let s = ""
|
||||
let i = 0
|
||||
while i < strlen(a:string)
|
||||
let char = strpart(a:string,i,1)
|
||||
if char2nr(char) < 8
|
||||
let next = stridx(a:string,char,i+1)
|
||||
if next == -1
|
||||
let s = s . char
|
||||
else
|
||||
let insertion = repl_{char2nr(char)}
|
||||
let subs = strpart(a:string,i+1,next-i-1)
|
||||
let subs = matchstr(subs,'\r.*')
|
||||
while subs =~ '^\r.*\r'
|
||||
let sub = matchstr(subs,"^\r\\zs[^\r]*\r[^\r]*")
|
||||
let subs = strpart(subs,strlen(sub)+1)
|
||||
let r = stridx(sub,"\r")
|
||||
let insertion = substitute(insertion,strpart(sub,0,r),strpart(sub,r+1),'')
|
||||
endwhile
|
||||
let s = s . insertion
|
||||
let i = next
|
||||
endif
|
||||
else
|
||||
let s = s . char
|
||||
endif
|
||||
let i = i + 1
|
||||
endwhile
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! s:wrap(string,char,type,...)
|
||||
let keeper = a:string
|
||||
let newchar = a:char
|
||||
let type = a:type
|
||||
let linemode = type ==# 'V' ? 1 : 0
|
||||
let special = a:0 ? a:1 : 0
|
||||
let before = ""
|
||||
let after = ""
|
||||
if type == "V"
|
||||
let initspaces = matchstr(keeper,'\%^\s*')
|
||||
else
|
||||
let initspaces = matchstr(getline('.'),'\%^\s*')
|
||||
endif
|
||||
" Duplicate b's are just placeholders (removed)
|
||||
let pairs = "b()B{}r[]a<>"
|
||||
let extraspace = ""
|
||||
if newchar =~ '^ '
|
||||
let newchar = strpart(newchar,1)
|
||||
let extraspace = ' '
|
||||
endif
|
||||
let idx = stridx(pairs,newchar)
|
||||
if newchar == ' '
|
||||
let before = ''
|
||||
let after = ''
|
||||
elseif exists("b:surround_".char2nr(newchar))
|
||||
let all = s:process(b:surround_{char2nr(newchar)})
|
||||
let before = s:extractbefore(all)
|
||||
let after = s:extractafter(all)
|
||||
elseif exists("g:surround_".char2nr(newchar))
|
||||
let all = s:process(g:surround_{char2nr(newchar)})
|
||||
let before = s:extractbefore(all)
|
||||
let after = s:extractafter(all)
|
||||
elseif newchar ==# "p"
|
||||
let before = "\n"
|
||||
let after = "\n\n"
|
||||
elseif newchar =~# "[tT\<C-T><,]"
|
||||
let dounmapp = 0
|
||||
let dounmapb = 0
|
||||
if !maparg(">","c")
|
||||
let dounmapb= 1
|
||||
" Hide from AsNeeded
|
||||
exe "cn"."oremap > <CR>"
|
||||
exe "cn"."oremap % %<C-V>"
|
||||
"cm ap > <C-R>=getcmdline() =~ '^[^%?].*[%?]$' ? "\026\076" : "\026\076\015"<CR>
|
||||
endif
|
||||
let default = ""
|
||||
if !maparg("%","c")
|
||||
" This is to help when typing things like
|
||||
" <a href="/images/<%= @image.filename %>">
|
||||
" The downside is it breaks backspace, so lets disable it for now
|
||||
"let dounmapp= 1
|
||||
"exe "cn"."oremap % %<C-V>"
|
||||
endif
|
||||
if newchar ==# "T"
|
||||
if !exists("s:lastdel")
|
||||
let s:lastdel = ""
|
||||
endif
|
||||
let default = matchstr(s:lastdel,'<\zs.\{-\}\ze>')
|
||||
endif
|
||||
let tag = input("<",default)
|
||||
echo "<".substitute(tag,'>*$','>','')
|
||||
"if dounmapr
|
||||
"silent! cunmap <CR>
|
||||
"endif
|
||||
if dounmapb
|
||||
silent! cunmap >
|
||||
endif
|
||||
if dounmapp
|
||||
silent! cunmap %
|
||||
endif
|
||||
if tag != ""
|
||||
let tag = substitute(tag,'>*$','','')
|
||||
let before = '<'.tag.'>'
|
||||
if tag =~ '/$'
|
||||
let after = ''
|
||||
else
|
||||
let after = '</'.substitute(tag,' .*','','').'>'
|
||||
endif
|
||||
if newchar == "\<C-T>" || newchar == ","
|
||||
if type ==# "v" || type ==# "V"
|
||||
let before = before . "\n\t"
|
||||
endif
|
||||
if type ==# "v"
|
||||
let after = "\n". after
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
elseif newchar ==# 'l' || newchar == '\'
|
||||
" LaTeX
|
||||
let env = input('\begin{')
|
||||
let env = '{' . env
|
||||
let env = env . s:closematch(env)
|
||||
echo '\begin'.env
|
||||
if env != ""
|
||||
let before = '\begin'.env
|
||||
let after = '\end'.matchstr(env,'[^}]*').'}'
|
||||
endif
|
||||
"if type ==# 'v' || type ==# 'V'
|
||||
"let before = before ."\n\t"
|
||||
"endif
|
||||
"if type ==# 'v'
|
||||
"let after = "\n".initspaces.after
|
||||
"endif
|
||||
elseif newchar ==# 'f' || newchar ==# 'F'
|
||||
let fnc = input('function: ')
|
||||
if fnc != ""
|
||||
let before = substitute(fnc,'($','','').'('
|
||||
let after = ')'
|
||||
if newchar ==# 'F'
|
||||
let before = before . ' '
|
||||
let after = ' ' . after
|
||||
endif
|
||||
endif
|
||||
elseif idx >= 0
|
||||
let spc = (idx % 3) == 1 ? " " : ""
|
||||
let idx = idx / 3 * 3
|
||||
let before = strpart(pairs,idx+1,1) . spc
|
||||
let after = spc . strpart(pairs,idx+2,1)
|
||||
elseif newchar == "\<C-[>" || newchar == "\<C-]>"
|
||||
let before = "{\n\t"
|
||||
let after = "\n}"
|
||||
elseif newchar !~ '\a'
|
||||
let before = newchar
|
||||
let after = newchar
|
||||
else
|
||||
let before = ''
|
||||
let after = ''
|
||||
endif
|
||||
"let before = substitute(before,'\n','\n'.initspaces,'g')
|
||||
let after = substitute(after ,'\n','\n'.initspaces,'g')
|
||||
"let after = substitute(after,"\n\\s*\<C-U>\\s*",'\n','g')
|
||||
if type ==# 'V' || (special && type ==# "v")
|
||||
let before = substitute(before,' \+$','','')
|
||||
let after = substitute(after ,'^ \+','','')
|
||||
if after !~ '^\n'
|
||||
let after = initspaces.after
|
||||
endif
|
||||
if keeper !~ '\n$' && after !~ '^\n'
|
||||
let keeper = keeper . "\n"
|
||||
elseif keeper =~ '\n$' && after =~ '^\n'
|
||||
let after = strpart(after,1)
|
||||
endif
|
||||
if before !~ '\n\s*$'
|
||||
let before = before . "\n"
|
||||
if special
|
||||
let before = before . "\t"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if type ==# 'V'
|
||||
let before = initspaces.before
|
||||
endif
|
||||
if before =~ '\n\s*\%$'
|
||||
if type ==# 'v'
|
||||
let keeper = initspaces.keeper
|
||||
endif
|
||||
let padding = matchstr(before,'\n\zs\s\+\%$')
|
||||
let before = substitute(before,'\n\s\+\%$','\n','')
|
||||
let keeper = s:fixindent(keeper,padding)
|
||||
endif
|
||||
if type ==# 'V'
|
||||
let keeper = before.keeper.after
|
||||
elseif type =~ "^\<C-V>"
|
||||
" Really we should be iterating over the buffer
|
||||
let repl = substitute(before,'[\\~]','\\&','g').'\1'.substitute(after,'[\\~]','\\&','g')
|
||||
let repl = substitute(repl,'\n',' ','g')
|
||||
let keeper = substitute(keeper."\n",'\(.\{-\}\)\('.(special ? '\s\{-\}' : '').'\n\)',repl.'\n','g')
|
||||
let keeper = substitute(keeper,'\n\%$','','')
|
||||
else
|
||||
let keeper = before.extraspace.keeper.extraspace.after
|
||||
endif
|
||||
return keeper
|
||||
endfunction
|
||||
|
||||
function! s:wrapreg(reg,char,...)
|
||||
let orig = getreg(a:reg)
|
||||
let type = substitute(getregtype(a:reg),'\d\+$','','')
|
||||
let special = a:0 ? a:1 : 0
|
||||
let new = s:wrap(orig,a:char,type,special)
|
||||
call setreg(a:reg,new,type)
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
function! s:insert(...) " {{{1
|
||||
" Optional argument causes the result to appear on 3 lines, not 1
|
||||
"call inputsave()
|
||||
let linemode = a:0 ? a:1 : 0
|
||||
let char = s:inputreplacement()
|
||||
while char == "\<CR>" || char == "\<C-S>"
|
||||
" TODO: use total count for additional blank lines
|
||||
let linemode = linemode + 1
|
||||
let char = s:inputreplacement()
|
||||
endwhile
|
||||
"call inputrestore()
|
||||
if char == ""
|
||||
return ""
|
||||
endif
|
||||
"call inputsave()
|
||||
let cb_save = &clipboard
|
||||
let reg_save = @@
|
||||
call setreg('"',"\r",'v')
|
||||
call s:wrapreg('"',char,linemode)
|
||||
" If line mode is used and the surrounding consists solely of a suffix,
|
||||
" remove the initial newline. This fits a use case of mine but is a
|
||||
" little inconsistent. Is there anyone that would prefer the simpler
|
||||
" behavior of just inserting the newline?
|
||||
if linemode && match(getreg('"'),'^\n\s*\zs.*') == 0
|
||||
call setreg('"',matchstr(getreg('"'),'^\n\s*\zs.*'),getregtype('"'))
|
||||
endif
|
||||
" This can be used to append a placeholder to the end
|
||||
if exists("g:surround_insert_tail")
|
||||
call setreg('"',g:surround_insert_tail,"a".getregtype('"'))
|
||||
endif
|
||||
"if linemode
|
||||
"call setreg('"',substitute(getreg('"'),'^\s\+','',''),'c')
|
||||
"endif
|
||||
if col('.') >= col('$')
|
||||
norm! ""p
|
||||
else
|
||||
norm! ""P
|
||||
endif
|
||||
if linemode
|
||||
call s:reindent()
|
||||
endif
|
||||
norm! `]
|
||||
call search('\r','bW')
|
||||
let @@ = reg_save
|
||||
let &clipboard = cb_save
|
||||
return "\<Del>"
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:reindent() " {{{1
|
||||
if exists("b:surround_indent") ? b:surround_indent : (exists("g:surround_indent") && g:surround_indent)
|
||||
silent norm! '[=']
|
||||
endif
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:dosurround(...) " {{{1
|
||||
let scount = v:count1
|
||||
let char = (a:0 ? a:1 : s:inputtarget())
|
||||
let spc = ""
|
||||
if char =~ '^\d\+'
|
||||
let scount = scount * matchstr(char,'^\d\+')
|
||||
let char = substitute(char,'^\d\+','','')
|
||||
endif
|
||||
if char =~ '^ '
|
||||
let char = strpart(char,1)
|
||||
let spc = 1
|
||||
endif
|
||||
if char == 'a'
|
||||
let char = '>'
|
||||
endif
|
||||
if char == 'r'
|
||||
let char = ']'
|
||||
endif
|
||||
let newchar = ""
|
||||
if a:0 > 1
|
||||
let newchar = a:2
|
||||
if newchar == "\<Esc>" || newchar == "\<C-C>" || newchar == ""
|
||||
return s:beep()
|
||||
endif
|
||||
endif
|
||||
let cb_save = &clipboard
|
||||
set clipboard-=unnamed
|
||||
let append = ""
|
||||
let original = getreg('"')
|
||||
let otype = getregtype('"')
|
||||
call setreg('"',"")
|
||||
let strcount = (scount == 1 ? "" : scount)
|
||||
if char == '/'
|
||||
exe 'norm '.strcount.'[/d'.strcount.']/'
|
||||
else
|
||||
exe 'norm d'.strcount.'i'.char
|
||||
" One character backwards
|
||||
if getreg('"') != ""
|
||||
call search('.','bW')
|
||||
endif
|
||||
endif
|
||||
let keeper = getreg('"')
|
||||
let okeeper = keeper " for reindent below
|
||||
if keeper == ""
|
||||
call setreg('"',original,otype)
|
||||
let &clipboard = cb_save
|
||||
return ""
|
||||
endif
|
||||
let oldline = getline('.')
|
||||
let oldlnum = line('.')
|
||||
if char ==# "p"
|
||||
call setreg('"','','V')
|
||||
elseif char ==# "s" || char ==# "w" || char ==# "W"
|
||||
" Do nothing
|
||||
call setreg('"','')
|
||||
elseif char =~ "[\"'`]"
|
||||
exe "norm! a \<Esc>d2i".char
|
||||
call setreg('"',substitute(getreg('"'),' ','',''))
|
||||
elseif char == '/'
|
||||
norm! "_x
|
||||
call setreg('"','/**/',"c")
|
||||
let keeper = substitute(substitute(keeper,'^/\*\s\=','',''),'\s\=\*$','','')
|
||||
else
|
||||
exe "norm da".char
|
||||
endif
|
||||
let removed = getreg('"')
|
||||
let rem2 = substitute(removed,'\n.*','','')
|
||||
let oldhead = strpart(oldline,0,strlen(oldline)-strlen(rem2))
|
||||
let oldtail = strpart(oldline, strlen(oldline)-strlen(rem2))
|
||||
let regtype = getregtype('"')
|
||||
if char =~# '[\[({<T]' || spc
|
||||
let keeper = substitute(keeper,'^\s\+','','')
|
||||
let keeper = substitute(keeper,'\s\+$','','')
|
||||
endif
|
||||
if col("']") == col("$") && col('.') + 1 == col('$')
|
||||
if oldhead =~# '^\s*$' && a:0 < 2
|
||||
let keeper = substitute(keeper,'\%^\n'.oldhead.'\(\s*.\{-\}\)\n\s*\%$','\1','')
|
||||
endif
|
||||
let pcmd = "p"
|
||||
else
|
||||
let pcmd = "P"
|
||||
endif
|
||||
if line('.') < oldlnum && regtype ==# "V"
|
||||
let pcmd = "p"
|
||||
endif
|
||||
call setreg('"',keeper,regtype)
|
||||
if newchar != ""
|
||||
call s:wrapreg('"',newchar)
|
||||
endif
|
||||
silent exe 'norm! ""'.pcmd.'`['
|
||||
if removed =~ '\n' || okeeper =~ '\n' || getreg('"') =~ '\n'
|
||||
call s:reindent()
|
||||
endif
|
||||
if getline('.') =~ '^\s\+$' && keeper =~ '^\s*\n'
|
||||
silent norm! cc
|
||||
endif
|
||||
call setreg('"',removed,regtype)
|
||||
let s:lastdel = removed
|
||||
let &clipboard = cb_save
|
||||
if newchar == ""
|
||||
silent! call repeat#set("\<Plug>Dsurround".char,scount)
|
||||
else
|
||||
silent! call repeat#set("\<Plug>Csurround".char.newchar,scount)
|
||||
endif
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:changesurround() " {{{1
|
||||
let a = s:inputtarget()
|
||||
if a == ""
|
||||
return s:beep()
|
||||
endif
|
||||
let b = s:inputreplacement()
|
||||
if b == ""
|
||||
return s:beep()
|
||||
endif
|
||||
call s:dosurround(a,b)
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:opfunc(type,...) " {{{1
|
||||
let char = s:inputreplacement()
|
||||
if char == ""
|
||||
return s:beep()
|
||||
endif
|
||||
let reg = '"'
|
||||
let sel_save = &selection
|
||||
let &selection = "inclusive"
|
||||
let cb_save = &clipboard
|
||||
set clipboard-=unnamed
|
||||
let reg_save = getreg(reg)
|
||||
let reg_type = getregtype(reg)
|
||||
"call setreg(reg,"\n","c")
|
||||
let type = a:type
|
||||
if a:type == "char"
|
||||
silent exe 'norm! v`[o`]"'.reg.'y'
|
||||
let type = 'v'
|
||||
elseif a:type == "line"
|
||||
silent exe 'norm! `[V`]"'.reg.'y'
|
||||
let type = 'V'
|
||||
elseif a:type ==# "v" || a:type ==# "V" || a:type ==# "\<C-V>"
|
||||
silent exe 'norm! gv"'.reg.'y'
|
||||
elseif a:type =~ '^\d\+$'
|
||||
let type = 'v'
|
||||
silent exe 'norm! ^v'.a:type.'$h"'.reg.'y'
|
||||
if mode() == 'v'
|
||||
norm! v
|
||||
return s:beep()
|
||||
endif
|
||||
else
|
||||
let &selection = sel_save
|
||||
let &clipboard = cb_save
|
||||
return s:beep()
|
||||
endif
|
||||
let keeper = getreg(reg)
|
||||
if type == "v" && a:type != "v"
|
||||
let append = matchstr(keeper,'\_s\@<!\s*$')
|
||||
let keeper = substitute(keeper,'\_s\@<!\s*$','','')
|
||||
endif
|
||||
call setreg(reg,keeper,type)
|
||||
call s:wrapreg(reg,char,a:0)
|
||||
if type == "v" && a:type != "v" && append != ""
|
||||
call setreg(reg,append,"ac")
|
||||
endif
|
||||
silent exe 'norm! gv'.(reg == '"' ? '' : '"' . reg).'p`['
|
||||
if type == 'V' || (getreg(reg) =~ '\n' && type == 'v')
|
||||
call s:reindent()
|
||||
endif
|
||||
call setreg(reg,reg_save,reg_type)
|
||||
let &selection = sel_save
|
||||
let &clipboard = cb_save
|
||||
if a:type =~ '^\d\+$'
|
||||
silent! call repeat#set("\<Plug>Y".(a:0 ? "S" : "s")."surround".char,a:type)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:opfunc2(arg)
|
||||
call s:opfunc(a:arg,1)
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:closematch(str) " {{{1
|
||||
" Close an open (, {, [, or < on the command line.
|
||||
let tail = matchstr(a:str,'.[^\[\](){}<>]*$')
|
||||
if tail =~ '^\[.\+'
|
||||
return "]"
|
||||
elseif tail =~ '^(.\+'
|
||||
return ")"
|
||||
elseif tail =~ '^{.\+'
|
||||
return "}"
|
||||
elseif tail =~ '^<.+'
|
||||
return ">"
|
||||
else
|
||||
return ""
|
||||
endif
|
||||
endfunction " }}}1
|
||||
|
||||
nnoremap <silent> <Plug>Dsurround :<C-U>call <SID>dosurround(<SID>inputtarget())<CR>
|
||||
nnoremap <silent> <Plug>Csurround :<C-U>call <SID>changesurround()<CR>
|
||||
nnoremap <silent> <Plug>Yssurround :<C-U>call <SID>opfunc(v:count1)<CR>
|
||||
nnoremap <silent> <Plug>YSsurround :<C-U>call <SID>opfunc2(v:count1)<CR>
|
||||
" <C-U> discards the numerical argument but there's not much we can do with it
|
||||
nnoremap <silent> <Plug>Ysurround :<C-U>set opfunc=<SID>opfunc<CR>g@
|
||||
nnoremap <silent> <Plug>YSurround :<C-U>set opfunc=<SID>opfunc2<CR>g@
|
||||
vnoremap <silent> <Plug>Vsurround :<C-U>call <SID>opfunc(visualmode())<CR>
|
||||
vnoremap <silent> <Plug>VSurround :<C-U>call <SID>opfunc2(visualmode())<CR>
|
||||
inoremap <silent> <Plug>Isurround <C-R>=<SID>insert()<CR>
|
||||
inoremap <silent> <Plug>ISurround <C-R>=<SID>insert(1)<CR>
|
||||
|
||||
if !exists("g:surround_no_mappings") || ! g:surround_no_mappings
|
||||
nmap ds <Plug>Dsurround
|
||||
nmap cs <Plug>Csurround
|
||||
nmap ys <Plug>Ysurround
|
||||
nmap yS <Plug>YSurround
|
||||
nmap yss <Plug>Yssurround
|
||||
nmap ySs <Plug>YSsurround
|
||||
nmap ySS <Plug>YSsurround
|
||||
if !hasmapto("<Plug>Vsurround","v")
|
||||
if exists(":xmap")
|
||||
xmap s <Plug>Vsurround
|
||||
else
|
||||
vmap s <Plug>Vsurround
|
||||
endif
|
||||
endif
|
||||
if !hasmapto("<Plug>VSurround","v")
|
||||
if exists(":xmap")
|
||||
xmap S <Plug>VSurround
|
||||
else
|
||||
vmap S <Plug>VSurround
|
||||
endif
|
||||
endif
|
||||
if !hasmapto("<Plug>Isurround","i") && "" == mapcheck("<C-S>","i")
|
||||
imap <C-S> <Plug>Isurround
|
||||
endif
|
||||
imap <C-G>s <Plug>Isurround
|
||||
imap <C-G>S <Plug>ISurround
|
||||
"Implemented internally instead
|
||||
"imap <C-S><C-S> <Plug>ISurround
|
||||
endif
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
|
||||
" vim:set ft=vim sw=4 sts=4 et:
|
||||
333
vim/plugin/syntastic.vim
Executable file
333
vim/plugin/syntastic.vim
Executable file
@@ -0,0 +1,333 @@
|
||||
"============================================================================
|
||||
"File: syntastic.vim
|
||||
"Description: vim plugin for on the fly syntax checking
|
||||
"Maintainer: Martin Grenfell <martin.grenfell at gmail dot com>
|
||||
"Version: 1.2.0
|
||||
"Last Change: 28 Oct, 2010
|
||||
"License: This program is free software. It comes without any warranty,
|
||||
" to the extent permitted by applicable law. You can redistribute
|
||||
" it and/or modify it under the terms of the Do What The Fuck You
|
||||
" Want To Public License, Version 2, as published by Sam Hocevar.
|
||||
" See http://sam.zoy.org/wtfpl/COPYING for more details.
|
||||
"
|
||||
"============================================================================
|
||||
|
||||
if exists("g:loaded_syntastic_plugin")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_syntastic_plugin = 1
|
||||
|
||||
let s:running_windows = has("win16") || has("win32") || has("win64")
|
||||
|
||||
if !s:running_windows
|
||||
let s:uname = system('uname')
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_enable_signs") || !has('signs')
|
||||
let g:syntastic_enable_signs = 0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_enable_balloons") || !has('balloon_eval')
|
||||
let g:syntastic_enable_balloons = 0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_auto_loc_list")
|
||||
let g:syntastic_auto_loc_list = 0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_auto_jump")
|
||||
let syntastic_auto_jump=0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_quiet_warnings")
|
||||
let g:syntastic_quiet_warnings = 0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_disabled_filetypes")
|
||||
let g:syntastic_disabled_filetypes = []
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_stl_format")
|
||||
let g:syntastic_stl_format = '[Syntax: line:%F (%t)]'
|
||||
endif
|
||||
|
||||
"refresh and redraw all the error info for this buf when saving or reading
|
||||
autocmd bufreadpost,bufwritepost * call s:UpdateErrors()
|
||||
function! s:UpdateErrors()
|
||||
if &buftype == 'quickfix'
|
||||
return
|
||||
endif
|
||||
call s:CacheErrors()
|
||||
|
||||
if g:syntastic_enable_balloons && has('balloon_eval')
|
||||
let b:syntastic_balloons = {}
|
||||
for i in b:syntastic_loclist
|
||||
let b:syntastic_balloons[i['lnum']] = i['text']
|
||||
endfor
|
||||
set beval bexpr=syntastic#ErrorBalloonExpr()
|
||||
endif
|
||||
|
||||
if g:syntastic_enable_signs
|
||||
call s:RefreshSigns()
|
||||
endif
|
||||
|
||||
if s:BufHasErrorsOrWarningsToDisplay()
|
||||
call setloclist(0, b:syntastic_loclist)
|
||||
if g:syntastic_auto_jump
|
||||
silent!ll
|
||||
endif
|
||||
elseif g:syntastic_auto_loc_list == 2
|
||||
lclose
|
||||
endif
|
||||
|
||||
if g:syntastic_auto_loc_list == 1
|
||||
if s:BufHasErrorsOrWarningsToDisplay()
|
||||
call s:ShowLocList()
|
||||
else
|
||||
"TODO: this will close the loc list window if one was opened by
|
||||
"something other than syntastic
|
||||
lclose
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"detect and cache all syntax errors in this buffer
|
||||
"
|
||||
"depends on a function called SyntaxCheckers_{&ft}_GetLocList() existing
|
||||
"elsewhere
|
||||
function! s:CacheErrors()
|
||||
let b:syntastic_loclist = []
|
||||
|
||||
if filereadable(expand("%"))
|
||||
for ft in split(&ft, '\.')
|
||||
if s:Checkable(ft)
|
||||
let b:syntastic_loclist = extend(b:syntastic_loclist, SyntaxCheckers_{ft}_GetLocList())
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"return true if there are cached errors/warnings for this buf
|
||||
function! s:BufHasErrorsOrWarnings()
|
||||
return exists("b:syntastic_loclist") && !empty(b:syntastic_loclist)
|
||||
endfunction
|
||||
|
||||
"return true if there are cached errors for this buf
|
||||
function! s:BufHasErrors()
|
||||
return len(s:ErrorsForType('E')) > 0
|
||||
endfunction
|
||||
|
||||
function! s:BufHasErrorsOrWarningsToDisplay()
|
||||
return s:BufHasErrors() || (!g:syntastic_quiet_warnings && s:BufHasErrorsOrWarnings())
|
||||
endfunction
|
||||
|
||||
function! s:ErrorsForType(type)
|
||||
if !exists("b:syntastic_loclist")
|
||||
return []
|
||||
endif
|
||||
return filter(copy(b:syntastic_loclist), 'v:val["type"] ==? "' . a:type . '"')
|
||||
endfunction
|
||||
|
||||
function s:Errors()
|
||||
return extend(s:ErrorsForType("E"), s:ErrorsForType(''))
|
||||
endfunction
|
||||
|
||||
function s:Warnings()
|
||||
return s:ErrorsForType("W")
|
||||
endfunction
|
||||
|
||||
if g:syntastic_enable_signs
|
||||
"use >> to display syntax errors in the sign column
|
||||
sign define SyntasticError text=>> texthl=error
|
||||
sign define SyntasticWarning text=>> texthl=todo
|
||||
endif
|
||||
|
||||
"start counting sign ids at 5000, start here to hopefully avoid conflicting
|
||||
"with any other code that places signs (not sure if this precaution is
|
||||
"actually needed)
|
||||
let s:first_sign_id = 5000
|
||||
let s:next_sign_id = s:first_sign_id
|
||||
|
||||
"place signs by all syntax errs in the buffer
|
||||
function s:SignErrors()
|
||||
if s:BufHasErrorsOrWarningsToDisplay()
|
||||
for i in b:syntastic_loclist
|
||||
if i['bufnr'] != bufnr("")
|
||||
continue
|
||||
endif
|
||||
|
||||
let sign_type = 'SyntasticError'
|
||||
if i['type'] == 'W'
|
||||
let sign_type = 'SyntasticWarning'
|
||||
endif
|
||||
|
||||
exec "sign place ". s:next_sign_id ." line=". i['lnum'] ." name=". sign_type ." file=". expand("%:p")
|
||||
call add(s:BufSignIds(), s:next_sign_id)
|
||||
let s:next_sign_id += 1
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"remove the signs with the given ids from this buffer
|
||||
function! s:RemoveSigns(ids)
|
||||
for i in a:ids
|
||||
exec "sign unplace " . i
|
||||
call remove(s:BufSignIds(), index(s:BufSignIds(), i))
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"get all the ids of the SyntaxError signs in the buffer
|
||||
function! s:BufSignIds()
|
||||
if !exists("b:syntastic_sign_ids")
|
||||
let b:syntastic_sign_ids = []
|
||||
endif
|
||||
return b:syntastic_sign_ids
|
||||
endfunction
|
||||
|
||||
"update the error signs
|
||||
function! s:RefreshSigns()
|
||||
let old_signs = copy(s:BufSignIds())
|
||||
call s:SignErrors()
|
||||
call s:RemoveSigns(old_signs)
|
||||
let s:first_sign_id = s:next_sign_id
|
||||
endfunction
|
||||
|
||||
"display the cached errors for this buf in the location list
|
||||
function! s:ShowLocList()
|
||||
if exists("b:syntastic_loclist")
|
||||
let num = winnr()
|
||||
lopen
|
||||
if num != winnr()
|
||||
wincmd p
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
command Errors call s:ShowLocList()
|
||||
|
||||
"return a string representing the state of buffer according to
|
||||
"g:syntastic_stl_format
|
||||
"
|
||||
"return '' if no errors are cached for the buffer
|
||||
function! SyntasticStatuslineFlag()
|
||||
if s:BufHasErrorsOrWarningsToDisplay()
|
||||
let errors = s:Errors()
|
||||
let warnings = s:Warnings()
|
||||
|
||||
let output = g:syntastic_stl_format
|
||||
|
||||
"hide stuff wrapped in %E(...) unless there are errors
|
||||
let output = substitute(output, '\C%E{\([^}]*\)}', len(errors) ? '\1' : '' , 'g')
|
||||
|
||||
"hide stuff wrapped in %W(...) unless there are warnings
|
||||
let output = substitute(output, '\C%W{\([^}]*\)}', len(warnings) ? '\1' : '' , 'g')
|
||||
|
||||
"hide stuff wrapped in %B(...) unless there are both errors and warnings
|
||||
let output = substitute(output, '\C%B{\([^}]*\)}', (len(warnings) && len(errors)) ? '\1' : '' , 'g')
|
||||
|
||||
"sub in the total errors/warnings/both
|
||||
let output = substitute(output, '\C%w', len(warnings), 'g')
|
||||
let output = substitute(output, '\C%e', len(errors), 'g')
|
||||
let output = substitute(output, '\C%t', len(b:syntastic_loclist), 'g')
|
||||
|
||||
"first error/warning line num
|
||||
let output = substitute(output, '\C%F', b:syntastic_loclist[0]['lnum'], 'g')
|
||||
|
||||
"first error line num
|
||||
let output = substitute(output, '\C%fe', len(errors) ? errors[0]['lnum'] : '', 'g')
|
||||
|
||||
"first warning line num
|
||||
let output = substitute(output, '\C%fw', len(warnings) ? warnings[0]['lnum'] : '', 'g')
|
||||
|
||||
return output
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"A wrapper for the :lmake command. Sets up the make environment according to
|
||||
"the options given, runs make, resets the environment, returns the location
|
||||
"list
|
||||
"
|
||||
"a:options can contain the following keys:
|
||||
" 'makeprg'
|
||||
" 'errorformat'
|
||||
"
|
||||
"The corresponding options are set for the duration of the function call. They
|
||||
"are set with :let, so dont escape spaces.
|
||||
function! SyntasticMake(options)
|
||||
let old_loclist = getloclist(0)
|
||||
let old_makeprg = &makeprg
|
||||
let old_shellpipe = &shellpipe
|
||||
let old_shell = &shell
|
||||
let old_errorformat = &errorformat
|
||||
|
||||
if !s:running_windows && (s:uname !~ "FreeBSD")
|
||||
"this is a hack to stop the screen needing to be ':redraw'n when
|
||||
"when :lmake is run. Otherwise the screen flickers annoyingly
|
||||
let &shellpipe='&>'
|
||||
let &shell = '/bin/bash'
|
||||
endif
|
||||
|
||||
if has_key(a:options, 'makeprg')
|
||||
let &makeprg = a:options['makeprg']
|
||||
endif
|
||||
|
||||
if has_key(a:options, 'errorformat')
|
||||
let &errorformat = a:options['errorformat']
|
||||
endif
|
||||
|
||||
silent lmake!
|
||||
let errors = getloclist(0)
|
||||
|
||||
call setloclist(0, old_loclist)
|
||||
let &makeprg = old_makeprg
|
||||
let &errorformat = old_errorformat
|
||||
let &shellpipe=old_shellpipe
|
||||
let &shell=old_shell
|
||||
|
||||
return errors
|
||||
endfunction
|
||||
|
||||
function! s:Checkable(ft)
|
||||
if !exists("g:loaded_" . a:ft . "_syntax_checker")
|
||||
exec "runtime syntax_checkers/" . a:ft . ".vim"
|
||||
endif
|
||||
|
||||
return exists("*SyntaxCheckers_". a:ft ."_GetLocList") &&
|
||||
\ index(g:syntastic_disabled_filetypes, a:ft) == -1
|
||||
endfunction
|
||||
|
||||
command! -nargs=? SyntasticEnable call s:Enable(<f-args>)
|
||||
command! -nargs=? SyntasticDisable call s:Disable(<f-args>)
|
||||
|
||||
"disable syntax checking for the given filetype (defaulting to current ft)
|
||||
function! s:Disable(...)
|
||||
let ft = a:0 ? a:1 : &filetype
|
||||
|
||||
if !empty(ft) && index(g:syntastic_disabled_filetypes, ft) == -1
|
||||
call add(g:syntastic_disabled_filetypes, ft)
|
||||
endif
|
||||
|
||||
"will cause existing errors to be cleared
|
||||
call s:UpdateErrors()
|
||||
endfunction
|
||||
|
||||
"enable syntax checking for the given filetype (defaulting to current ft)
|
||||
function! s:Enable(...)
|
||||
let ft = a:0 ? a:1 : &filetype
|
||||
|
||||
let i = index(g:syntastic_disabled_filetypes, ft)
|
||||
if i != -1
|
||||
call remove(g:syntastic_disabled_filetypes, i)
|
||||
endif
|
||||
|
||||
if !&modified
|
||||
call s:UpdateErrors()
|
||||
redraw!
|
||||
else
|
||||
echom "Syntasic: enabled for the '" . ft . "' filetype. :write out to update errors"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" vim: set et sts=4 sw=4:
|
||||
385
vim/plugin/tComment.vim
Normal file
385
vim/plugin/tComment.vim
Normal file
@@ -0,0 +1,385 @@
|
||||
" tComment.vim -- An easily extensible & universal comment plugin
|
||||
" @Author: Tom Link (micathom AT gmail com)
|
||||
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
|
||||
" @Created: 27-Dez-2004.
|
||||
" @Last Change: 2009-08-07.
|
||||
" @Revision: 1.9.671
|
||||
"
|
||||
" GetLatestVimScripts: 1173 1 tComment.vim
|
||||
|
||||
if &cp || exists('loaded_tcomment')
|
||||
finish
|
||||
endif
|
||||
let loaded_tcomment = 109
|
||||
|
||||
" If true, comment blank lines too
|
||||
if !exists("g:tcommentBlankLines")
|
||||
let g:tcommentBlankLines = 1
|
||||
endif
|
||||
|
||||
if !exists("g:tcommentMapLeader1")
|
||||
let g:tcommentMapLeader1 = '<c-_>'
|
||||
endif
|
||||
if !exists("g:tcommentMapLeader2")
|
||||
let g:tcommentMapLeader2 = '<Leader>_'
|
||||
endif
|
||||
if !exists("g:tcommentMapLeaderOp1")
|
||||
let g:tcommentMapLeaderOp1 = 'gc'
|
||||
endif
|
||||
if !exists("g:tcommentMapLeaderOp2")
|
||||
let g:tcommentMapLeaderOp2 = 'gC'
|
||||
endif
|
||||
if !exists("g:tcommentOpModeExtra")
|
||||
let g:tcommentOpModeExtra = ''
|
||||
endif
|
||||
|
||||
" Guess the file type based on syntax names always or for some fileformat only
|
||||
if !exists("g:tcommentGuessFileType")
|
||||
let g:tcommentGuessFileType = 0
|
||||
endif
|
||||
" In php documents, the php part is usually marked as phpRegion. We thus
|
||||
" assume that the buffers default comment style isn't php but html
|
||||
if !exists("g:tcommentGuessFileType_dsl")
|
||||
let g:tcommentGuessFileType_dsl = 'xml'
|
||||
endif
|
||||
if !exists("g:tcommentGuessFileType_php")
|
||||
let g:tcommentGuessFileType_php = 'html'
|
||||
endif
|
||||
if !exists("g:tcommentGuessFileType_html")
|
||||
let g:tcommentGuessFileType_html = 1
|
||||
endif
|
||||
if !exists("g:tcommentGuessFileType_tskeleton")
|
||||
let g:tcommentGuessFileType_tskeleton = 1
|
||||
endif
|
||||
if !exists("g:tcommentGuessFileType_vim")
|
||||
let g:tcommentGuessFileType_vim = 1
|
||||
endif
|
||||
|
||||
if !exists("g:tcommentIgnoreTypes_php")
|
||||
let g:tcommentIgnoreTypes_php = 'sql'
|
||||
endif
|
||||
|
||||
if !exists('g:tcommentSyntaxMap') "{{{2
|
||||
let g:tcommentSyntaxMap = {
|
||||
\ 'vimMzSchemeRegion': 'scheme',
|
||||
\ 'vimPerlRegion': 'perl',
|
||||
\ 'vimPythonRegion': 'python',
|
||||
\ 'vimRubyRegion': 'ruby',
|
||||
\ 'vimTclRegion': 'tcl',
|
||||
\ }
|
||||
endif
|
||||
|
||||
" If you don't define these variables, TComment will use &commentstring
|
||||
" instead. We override the default values here in order to have a blank after
|
||||
" the comment marker. Block comments work only if we explicitly define the
|
||||
" markup.
|
||||
" The format for block comments is similar to normal commentstrings with the
|
||||
" exception that the format strings for blocks can contain a second line that
|
||||
" defines how "middle lines" (see :h format-comments) should be displayed.
|
||||
|
||||
" I personally find this style rather irritating but here is an alternative
|
||||
" definition that does this left-handed bar thing
|
||||
if !exists("g:tcommentBlockC")
|
||||
let g:tcommentBlockC = "/*%s */\n * "
|
||||
endif
|
||||
if !exists("g:tcommentBlockC2")
|
||||
let g:tcommentBlockC2 = "/**%s */\n * "
|
||||
endif
|
||||
if !exists("g:tcommentInlineC")
|
||||
let g:tcommentInlineC = "/* %s */"
|
||||
endif
|
||||
|
||||
if !exists("g:tcommentBlockXML")
|
||||
let g:tcommentBlockXML = "<!--%s-->\n "
|
||||
endif
|
||||
if !exists("g:tcommentInlineXML")
|
||||
let g:tcommentInlineXML = "<!-- %s -->"
|
||||
endif
|
||||
|
||||
let g:tcommentFileTypesDirty = 1
|
||||
|
||||
" Currently this function just sets a variable
|
||||
function! TCommentDefineType(name, commentstring)
|
||||
if !exists('g:tcomment_'. a:name)
|
||||
let g:tcomment_{a:name} = a:commentstring
|
||||
endif
|
||||
let g:tcommentFileTypesDirty = 1
|
||||
endf
|
||||
|
||||
function! TCommentTypeExists(name)
|
||||
return exists('g:tcomment_'. a:name)
|
||||
endf
|
||||
|
||||
call TCommentDefineType('aap', '# %s' )
|
||||
call TCommentDefineType('ada', '-- %s' )
|
||||
call TCommentDefineType('apache', '# %s' )
|
||||
call TCommentDefineType('autoit', '; %s' )
|
||||
call TCommentDefineType('asm', '; %s' )
|
||||
call TCommentDefineType('awk', '# %s' )
|
||||
call TCommentDefineType('catalog', '-- %s --' )
|
||||
call TCommentDefineType('catalog_block', "--%s--\n " )
|
||||
call TCommentDefineType('cpp', '// %s' )
|
||||
call TCommentDefineType('cpp_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('cpp_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('css', '/* %s */' )
|
||||
call TCommentDefineType('css_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('css_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('c', '/* %s */' )
|
||||
call TCommentDefineType('c_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('c_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('cfg', '# %s' )
|
||||
call TCommentDefineType('conf', '# %s' )
|
||||
call TCommentDefineType('crontab', '# %s' )
|
||||
call TCommentDefineType('desktop', '# %s' )
|
||||
call TCommentDefineType('docbk', '<!-- %s -->' )
|
||||
call TCommentDefineType('docbk_inline', g:tcommentInlineXML)
|
||||
call TCommentDefineType('docbk_block', g:tcommentBlockXML )
|
||||
call TCommentDefineType('dosbatch', 'rem %s' )
|
||||
call TCommentDefineType('dosini', '; %s' )
|
||||
call TCommentDefineType('dsl', '; %s' )
|
||||
call TCommentDefineType('dylan', '// %s' )
|
||||
call TCommentDefineType('eiffel', '-- %s' )
|
||||
call TCommentDefineType('eruby', '<%%# %s%%>' )
|
||||
call TCommentDefineType('gtkrc', '# %s' )
|
||||
call TCommentDefineType('gitcommit', '# %s' )
|
||||
call TCommentDefineType('haskell', '-- %s' )
|
||||
call TCommentDefineType('haskell_block', "{-%s-}\n " )
|
||||
call TCommentDefineType('haskell_inline', '{- %s -}' )
|
||||
call TCommentDefineType('html', '<!-- %s -->' )
|
||||
call TCommentDefineType('html_inline', g:tcommentInlineXML)
|
||||
call TCommentDefineType('html_block', g:tcommentBlockXML )
|
||||
call TCommentDefineType('io', '// %s' )
|
||||
call TCommentDefineType('javaScript', '// %s' )
|
||||
call TCommentDefineType('javaScript_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('javaScript_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('javascript', '// %s' )
|
||||
call TCommentDefineType('javascript_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('javascript_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('java', '/* %s */' )
|
||||
call TCommentDefineType('java_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('java_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('java_doc_block', g:tcommentBlockC2 )
|
||||
call TCommentDefineType('jproperties', '# %s' )
|
||||
call TCommentDefineType('lisp', '; %s' )
|
||||
call TCommentDefineType('lynx', '# %s' )
|
||||
call TCommentDefineType('m4', 'dnl %s' )
|
||||
call TCommentDefineType('mail', '> %s' )
|
||||
call TCommentDefineType('msidl', '// %s' )
|
||||
call TCommentDefineType('msidl_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('nroff', '.\\" %s' )
|
||||
call TCommentDefineType('nsis', '# %s' )
|
||||
call TCommentDefineType('objc', '/* %s */' )
|
||||
call TCommentDefineType('objc_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('objc_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('ocaml', '(* %s *)' )
|
||||
call TCommentDefineType('ocaml_inline', '(* %s *)' )
|
||||
call TCommentDefineType('ocaml_block', "(*%s*)\n " )
|
||||
call TCommentDefineType('pascal', '(* %s *)' )
|
||||
call TCommentDefineType('pascal_inline', '(* %s *)' )
|
||||
call TCommentDefineType('pascal_block', "(*%s*)\n " )
|
||||
call TCommentDefineType('perl', '# %s' )
|
||||
call TCommentDefineType('perl_block', "=cut%s=cut" )
|
||||
call TCommentDefineType('php', '// %s' )
|
||||
call TCommentDefineType('php_inline', g:tcommentInlineC )
|
||||
call TCommentDefineType('php_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('php_2_block', g:tcommentBlockC2 )
|
||||
call TCommentDefineType('po', '# %s' )
|
||||
call TCommentDefineType('prolog', '%% %s' )
|
||||
call TCommentDefineType('rc', '// %s' )
|
||||
call TCommentDefineType('readline', '# %s' )
|
||||
call TCommentDefineType('ruby', '# %s' )
|
||||
call TCommentDefineType('ruby_3', '### %s' )
|
||||
call TCommentDefineType('ruby_block', "=begin rdoc%s=end")
|
||||
call TCommentDefineType('ruby_nodoc_block', "=begin%s=end" )
|
||||
call TCommentDefineType('r', '# %s' )
|
||||
call TCommentDefineType('sbs', "' %s" )
|
||||
call TCommentDefineType('scheme', '; %s' )
|
||||
call TCommentDefineType('sed', '# %s' )
|
||||
call TCommentDefineType('sgml', '<!-- %s -->' )
|
||||
call TCommentDefineType('sgml_inline', g:tcommentInlineXML)
|
||||
call TCommentDefineType('sgml_block', g:tcommentBlockXML )
|
||||
call TCommentDefineType('sh', '# %s' )
|
||||
call TCommentDefineType('sql', '-- %s' )
|
||||
call TCommentDefineType('spec', '# %s' )
|
||||
call TCommentDefineType('sps', '* %s.' )
|
||||
call TCommentDefineType('sps_block', "* %s." )
|
||||
call TCommentDefineType('spss', '* %s.' )
|
||||
call TCommentDefineType('spss_block', "* %s." )
|
||||
call TCommentDefineType('tcl', '# %s' )
|
||||
call TCommentDefineType('tex', '%% %s' )
|
||||
call TCommentDefineType('tpl', '<!-- %s -->' )
|
||||
call TCommentDefineType('viki', '%% %s' )
|
||||
call TCommentDefineType('viki_3', '%%%%%% %s' )
|
||||
call TCommentDefineType('viki_inline', '{cmt: %s}' )
|
||||
call TCommentDefineType('vim', '" %s' )
|
||||
call TCommentDefineType('vim_3', '""" %s' )
|
||||
call TCommentDefineType('websec', '# %s' )
|
||||
call TCommentDefineType('xml', '<!-- %s -->' )
|
||||
call TCommentDefineType('xml_inline', g:tcommentInlineXML)
|
||||
call TCommentDefineType('xml_block', g:tcommentBlockXML )
|
||||
call TCommentDefineType('xs', '// %s' )
|
||||
call TCommentDefineType('xs_block', g:tcommentBlockC )
|
||||
call TCommentDefineType('xslt', '<!-- %s -->' )
|
||||
call TCommentDefineType('xslt_inline', g:tcommentInlineXML)
|
||||
call TCommentDefineType('xslt_block', g:tcommentBlockXML )
|
||||
call TCommentDefineType('yaml', '# %s' )
|
||||
|
||||
|
||||
" :line1,line2 TCommentAs commenttype
|
||||
command! -bang -complete=customlist,tcomment#FileTypes -range -nargs=+ TCommentAs
|
||||
\ call tcomment#CommentAs(<line1>, <line2>, "<bang>", <f-args>)
|
||||
|
||||
" :line1,line2 TComment ?commentBegin ?commentEnd
|
||||
command! -bang -range -nargs=* TComment keepjumps call tcomment#Comment(<line1>, <line2>, 'G', "<bang>", <f-args>)
|
||||
|
||||
" :line1,line2 TCommentRight ?commentBegin ?commentEnd
|
||||
command! -bang -range -nargs=* TCommentRight keepjumps call tcomment#Comment(<line1>, <line2>, 'R', "<bang>", <f-args>)
|
||||
|
||||
" :line1,line2 TCommentBlock ?commentBegin ?commentEnd
|
||||
command! -bang -range -nargs=* TCommentBlock keepjumps call tcomment#Comment(<line1>, <line2>, 'B', "<bang>", <f-args>)
|
||||
|
||||
" :line1,line2 TCommentInline ?commentBegin ?commentEnd
|
||||
command! -bang -range -nargs=* TCommentInline keepjumps call tcomment#Comment(<line1>, <line2>, 'I', "<bang>", <f-args>)
|
||||
|
||||
" :line1,line2 TCommentMaybeInline ?commentBegin ?commentEnd
|
||||
command! -bang -range -nargs=* TCommentMaybeInline keepjumps call tcomment#Comment(<line1>, <line2>, 'i', "<bang>", <f-args>)
|
||||
|
||||
|
||||
|
||||
if (g:tcommentMapLeader1 != '')
|
||||
exec 'noremap <silent> '. g:tcommentMapLeader1 .'<c-_> :TComment<cr>'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeader1 .'<c-_> :TCommentMaybeInline<cr>'
|
||||
exec 'inoremap <silent> '. g:tcommentMapLeader1 .'<c-_> <c-o>:TComment<cr>'
|
||||
exec 'noremap <silent> '. g:tcommentMapLeader1 .'p m`vip:TComment<cr>``'
|
||||
exec 'inoremap <silent> '. g:tcommentMapLeader1 .'p <c-o>:norm! m`vip<cr>:TComment<cr><c-o>``'
|
||||
exec 'noremap '. g:tcommentMapLeader1 .'<space> :TComment '
|
||||
exec 'inoremap '. g:tcommentMapLeader1 .'<space> <c-o>:TComment '
|
||||
exec 'inoremap <silent> '. g:tcommentMapLeader1 .'r <c-o>:TCommentRight<cr>'
|
||||
exec 'noremap <silent> '. g:tcommentMapLeader1 .'r :TCommentRight<cr>'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeader1 .'i :TCommentInline<cr>'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeader1 .'r :TCommentRight<cr>'
|
||||
exec 'noremap '. g:tcommentMapLeader1 .'b :TCommentBlock<cr>'
|
||||
exec 'inoremap '. g:tcommentMapLeader1 .'b <c-o>:TCommentBlock<cr>'
|
||||
exec 'noremap '. g:tcommentMapLeader1 .'a :TCommentAs '
|
||||
exec 'inoremap '. g:tcommentMapLeader1 .'a <c-o>:TCommentAs '
|
||||
exec 'noremap '. g:tcommentMapLeader1 .'n :TCommentAs <c-r>=&ft<cr> '
|
||||
exec 'inoremap '. g:tcommentMapLeader1 .'n <c-o>:TCommentAs <c-r>=&ft<cr> '
|
||||
exec 'noremap '. g:tcommentMapLeader1 .'s :TCommentAs <c-r>=&ft<cr>_'
|
||||
exec 'inoremap '. g:tcommentMapLeader1 .'s <c-o>:TCommentAs <c-r>=&ft<cr>_'
|
||||
endif
|
||||
if (g:tcommentMapLeader2 != '')
|
||||
exec 'noremap <silent> '. g:tcommentMapLeader2 .'_ :TComment<cr>'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeader2 .'_ :TCommentMaybeInline<cr>'
|
||||
exec 'noremap <silent> '. g:tcommentMapLeader2 .'p vip:TComment<cr>'
|
||||
exec 'noremap '. g:tcommentMapLeader2 .'<space> :TComment '
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeader2 .'i :TCommentInline<cr>'
|
||||
exec 'noremap <silent> '. g:tcommentMapLeader2 .'r :TCommentRight<cr>'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeader2 .'r :TCommentRight<cr>'
|
||||
exec 'noremap '. g:tcommentMapLeader2 .'b :TCommentBlock<cr>'
|
||||
exec 'noremap '. g:tcommentMapLeader2 .'a :TCommentAs '
|
||||
exec 'noremap '. g:tcommentMapLeader2 .'n :TCommentAs <c-r>=&ft<cr> '
|
||||
exec 'noremap '. g:tcommentMapLeader2 .'s :TCommentAs <c-r>=&ft<cr>_'
|
||||
endif
|
||||
if (g:tcommentMapLeaderOp1 != '')
|
||||
exec 'nnoremap <silent> '. g:tcommentMapLeaderOp1 .' :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#Operator<cr>g@'
|
||||
exec 'nnoremap <silent> '. g:tcommentMapLeaderOp1 .'c :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#OperatorLine<cr>g@$'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeaderOp1 .' :TCommentMaybeInline<cr>'
|
||||
endif
|
||||
if (g:tcommentMapLeaderOp2 != '')
|
||||
exec 'nnoremap <silent> '. g:tcommentMapLeaderOp2 .' :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#OperatorAnyway<cr>g@'
|
||||
exec 'nnoremap <silent> '. g:tcommentMapLeaderOp2 .'c :let w:tcommentPos = getpos(".") \| set opfunc=tcomment#OperatorLineAnyway<cr>g@$'
|
||||
exec 'vnoremap <silent> '. g:tcommentMapLeaderOp2 .' :TCommentMaybeInline<cr>'
|
||||
endif
|
||||
|
||||
finish
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
History
|
||||
|
||||
0.1
|
||||
- Initial release
|
||||
|
||||
0.2
|
||||
- Fixed uncommenting of non-aligned comments
|
||||
- improved support for block comments (with middle lines and indentation)
|
||||
- using TCommentBlock for file types that don't have block comments creates
|
||||
single line comments
|
||||
- removed the TCommentAsBlock command (TCommentAs provides its functionality)
|
||||
- removed g:tcommentSetCMS
|
||||
- the default key bindings have slightly changed
|
||||
|
||||
1.3
|
||||
- slightly improved recognition of embedded syntax
|
||||
- if no commentstring is defined in whatever way, reconstruct one from
|
||||
&comments
|
||||
- The TComment... commands now have bang variants that don't act as toggles
|
||||
but always comment out the selected text
|
||||
- fixed problem with commentstrings containing backslashes
|
||||
- comment as visual block (allows commenting text to the right of the main
|
||||
text, i.e., this command doesn't work on whole lines but on the text to the
|
||||
right of the cursor)
|
||||
- enable multimode for dsl, vim filetypes
|
||||
- added explicit support for some other file types I ran into
|
||||
|
||||
1.4
|
||||
- Fixed problem when &commentstring was invalid (e.g. lua)
|
||||
- perl_block by Kyosuke Takayama.
|
||||
- <c-_>s mapped to :TCommentAs <c-r>=&ft<cr>
|
||||
|
||||
1.5
|
||||
- "Inline" visual comments (uses the &filetype_inline style if
|
||||
available; doesn't check if the filetype actually supports this kind of
|
||||
comments); tComment can't currently deduce inline comment styles from
|
||||
&comments or &commentstring (I personally hardly ever use them); default
|
||||
map: <c-_>i or <c-_>I
|
||||
- In visual mode: if the selection spans several lines, normal mode is
|
||||
selected; if the selection covers only a part of one line, inline mode
|
||||
is selected
|
||||
- Fixed problem with lines containing ^M or ^@ characters.
|
||||
- It's no longer necessary to call TCommentCollectFileTypes() after
|
||||
defining a new filetype via TCommentDefineType()
|
||||
- Disabled single <c-_> mappings
|
||||
- Renamed TCommentVisualBlock to TCommentRight
|
||||
- FIX: Forgot 'x' in ExtractCommentsPart() (thanks to Fredrik Acosta)
|
||||
|
||||
1.6
|
||||
- Ignore sql when guessing the comment string in php files; tComment
|
||||
sometimes chooses the wrong comment string because the use of sql syntax
|
||||
is used too loosely in php files; if you want to comment embedded sql
|
||||
code you have to use TCommentAs
|
||||
- Use keepjumps in commands.
|
||||
- Map <c-_>p & <L>_p to vip:TComment<cr>
|
||||
- Made key maps configurable via g:tcommentMapLeader1 and
|
||||
g:tcommentMapLeader2
|
||||
|
||||
1.7
|
||||
- gc{motion} (see g:tcommentMapLeaderOp1) functions as a comment toggle
|
||||
operator (i.e., something like gcl... works, mostly); gC{motion} (see
|
||||
g:tcommentMapLeaderOp2) will unconditionally comment the text.
|
||||
- TCommentAs takes an optional second argument (the comment level)
|
||||
- New "n" map: TCommentAs &filetype [COUNT]
|
||||
- Defined mail comments/citations
|
||||
- g:tcommentSyntaxMap: Map syntax names to filetypes for buffers with
|
||||
mixed syntax groups that don't match the filetypeEmbeddedsyntax scheme (e.g.
|
||||
'vimRubyRegion', which should be commented as ruby syntax, not as vim
|
||||
syntax)
|
||||
- FIX: Comments in vim*Region
|
||||
- TComment: The use of the type argument has slightly changed (IG -> i,
|
||||
new: >)
|
||||
|
||||
1.8
|
||||
- Definitly require vim7
|
||||
- Split the plugin into autoload & plugin.
|
||||
- g:TCommentFileTypes is a list
|
||||
- Fixed some block comment strings
|
||||
- Removed extraneous newline in some block comments.
|
||||
- Maps for visal mode (thanks Krzysztof Goj)
|
||||
|
||||
1.9
|
||||
- Fix left offset for inline comments (via operator binding)
|
||||
|
||||
1.10
|
||||
- tcomment#Operator defines w:tcommentPos if invoked repeatedly
|
||||
- s:GuessFileType: use len(getline()) instead of col()
|
||||
|
||||
4546
vim/plugin/taglist.vim
Normal file
4546
vim/plugin/taglist.vim
Normal file
File diff suppressed because it is too large
Load Diff
191
vim/plugin/themes.vim
Normal file
191
vim/plugin/themes.vim
Normal file
@@ -0,0 +1,191 @@
|
||||
" Vim default schemes
|
||||
amenu T&hemes.D&efault.Blue :colo blue<CR>
|
||||
amenu T&hemes.D&efault.DarkBlue :colo darkblue<CR>
|
||||
amenu T&hemes.D&efault.Default :colo default<CR>
|
||||
amenu T&hemes.D&efault.Delek :colo delek<CR>
|
||||
amenu T&hemes.D&efault.Desert :colo desert<CR>
|
||||
amenu T&hemes.D&efault.ElfLord :colo elflord<CR>
|
||||
amenu T&hemes.D&efault.Evening :colo evening<CR>
|
||||
amenu T&hemes.D&efault.Koehler :colo koehler<CR>
|
||||
amenu T&hemes.D&efault.Morning :colo morning<CR>
|
||||
amenu T&hemes.D&efault.Murphy :colo murphy<CR>
|
||||
amenu T&hemes.D&efault.Pablo :colo pablo<CR>
|
||||
amenu T&hemes.D&efault.PeachPuff :colo peachpuff<CR>
|
||||
amenu T&hemes.D&efault.Ron :colo ron<CR>
|
||||
amenu T&hemes.D&efault.Shine :colo shine<CR>
|
||||
amenu T&hemes.D&efault.Torte :colo torte<CR>
|
||||
|
||||
amenu T&hemes.-s1- :
|
||||
|
||||
" Recommended Themes
|
||||
amenu T&hemes.&Recommendations.InkPot :colo inkpot<CR>
|
||||
amenu T&hemes.&Recommendations.LingoDirector :colo lingodirector<CR>
|
||||
amenu T&hemes.&Recommendations.MetaCosm :colo metacosm<CR>
|
||||
amenu T&hemes.&Recommendations.MidNight2 :colo midnight2<CR>
|
||||
amenu T&hemes.&Recommendations.PS_Warm :let psc_style='warm'<CR>:colo ps_color<CR>
|
||||
amenu T&hemes.&Recommendations.SCite :colo scite<CR>
|
||||
|
||||
amenu T&hemes.-s2- :
|
||||
|
||||
" Schemes with pure Black background.
|
||||
amenu T&hemes.Blac&k.Adrian :colo adrian<CR>
|
||||
amenu T&hemes.Blac&k.BillW :colo billw<CR>
|
||||
amenu T&hemes.Blac&k.BlackAngus :colo black_angus<CR>
|
||||
amenu T&hemes.Blac&k.BlackBeauty :colo blackbeauty<CR>
|
||||
amenu T&hemes.Blac&k.BlackSea :colo blacksea<CR>
|
||||
amenu T&hemes.Blac&k.Brookstream :colo brookstream<CR>
|
||||
amenu T&hemes.Blac&k.Candy :colo candy<CR>
|
||||
amenu T&hemes.Blac&k.Colorer :colo colorer<CR>
|
||||
amenu T&hemes.Blac&k.Dante :colo dante<CR>
|
||||
" Vim Dark Default is hidden, this can be used to activate it.
|
||||
amenu T&hemes.Blac&k.Dark_Default :let psc_style='defdark'<CR>:colo ps_color<CR>
|
||||
amenu T&hemes.Blac&k.DarkBlack :colo darkblack<CR>
|
||||
amenu T&hemes.Blac&k.DarkOcean :colo darkocean<CR>
|
||||
amenu T&hemes.Blac&k.FnaqEvan :colo fnaqevan<CR>
|
||||
amenu T&hemes.Blac&k.Golden :colo golden<CR>
|
||||
amenu T&hemes.Blac&k.Gothic :colo gothic<CR>
|
||||
amenu T&hemes.Blac&k.GreyBlue :colo greyblue<CR>
|
||||
amenu T&hemes.Blac&k.HHd.blue :colo hhdblue<CR>
|
||||
amenu T&hemes.Blac&k.HHd.cyan :colo hhdcyan<CR>
|
||||
amenu T&hemes.Blac&k.HHd.gray :colo hhdgray<CR>
|
||||
amenu T&hemes.Blac&k.HHd.green :colo hhdgreen<CR>
|
||||
amenu T&hemes.Blac&k.HHd.magenta :colo hhdmagenta<CR>
|
||||
amenu T&hemes.Blac&k.HHd.red :colo hhdred<CR>
|
||||
amenu T&hemes.Blac&k.HHd.yellow :colo hhdyellow<CR>
|
||||
amenu T&hemes.Blac&k.JHDark :colo jhdark<CR>
|
||||
amenu T&hemes.Blac&k.Less :colo less<CR>
|
||||
amenu T&hemes.Blac&k.Manxome :colo manxome<CR>
|
||||
amenu T&hemes.Blac&k.Olive :colo olive<CR>
|
||||
amenu T&hemes.Blac&k.OceanBlack :colo oceanblack<CR>
|
||||
amenu T&hemes.Blac&k.PS_Cool :let psc_style='cool'<CR>:colo ps_color<CR>
|
||||
amenu T&hemes.Blac&k.Putty :colo putty<CR>
|
||||
amenu T&hemes.Blac&k.RedBlack :colo redblack<CR>
|
||||
amenu T&hemes.Blac&k.Revolutions :colo revolutions<CR>
|
||||
amenu T&hemes.Blac&k.RelaxedGreen :colo relaxedgreen<CR>
|
||||
amenu T&hemes.Blac&k.Sean :colo sean<CR>
|
||||
amenu T&hemes.Blac&k.WintersDay :colo wintersday<CR>
|
||||
|
||||
" Dark Blue, or Deep Blue
|
||||
amenu T&hemes.&Blue.Adaryn :colo adaryn<CR>
|
||||
amenu T&hemes.&Blue.Astronaut :colo astronaut<CR>
|
||||
amenu T&hemes.&Blue.BlueGreen :colo bluegreen<CR>
|
||||
amenu T&hemes.&Blue.Blugrine :colo blugrine<CR>
|
||||
amenu T&hemes.&Blue.Borland :colo borland<CR>
|
||||
amenu T&hemes.&Blue.BorlandTurbo :colo turbo<CR>
|
||||
amenu T&hemes.&Blue.Cool :colo cool<CR>
|
||||
amenu T&hemes.&Blue.DarkDot :colo darkdot<CR>
|
||||
amenu T&hemes.&Blue.Denim :colo denim<CR>
|
||||
amenu T&hemes.&Blue.IbmEdit :colo ibmedit<CR>
|
||||
amenu T&hemes.&Blue.InkPot :colo inkpot<CR>
|
||||
amenu T&hemes.&Blue.Midnight :colo midnight<CR>
|
||||
amenu T&hemes.&Blue.Midnight2 :colo midnight2<CR>
|
||||
amenu T&hemes.&Blue.Northsky :colo northsky<CR>
|
||||
amenu T&hemes.&Blue.Sea :colo sea<CR>
|
||||
amenu T&hemes.&Blue.Transparent :colo transparent<CR>
|
||||
|
||||
" A bit lighter Blue, or greenish blue
|
||||
amenu T&hemes.&Blue.Adam :colo adam<CR>
|
||||
amenu T&hemes.&Cyan.Aqua :colo aqua<CR>
|
||||
amenu T&hemes.&Cyan.Breeze :colo breeze<CR>
|
||||
amenu T&hemes.&Cyan.Darkblue2 :colo darkblue2<CR>
|
||||
amenu T&hemes.&Cyan.DarkSlateGray :colo darkslategray<CR>
|
||||
amenu T&hemes.&Cyan.Dusk :colo dusk<CR>
|
||||
amenu T&hemes.&Cyan.Gor :colo gor<CR>
|
||||
amenu T&hemes.&Cyan.HHazure :colo hhazure<CR>
|
||||
amenu T&hemes.&Cyan.Navajo-Night :colo navajo-night<CR>
|
||||
amenu T&hemes.&Cyan.NightShimmer :colo nightshimmer<CR>
|
||||
amenu T&hemes.&Cyan.NightWish :colo nightwish<CR>
|
||||
amenu T&hemes.&Cyan.OceanDeep :colo oceandeep<CR>
|
||||
|
||||
" A traditional Greenish look...
|
||||
amenu T&hemes.&Green.Earth :colo earth<CR>
|
||||
amenu T&hemes.&Green.HHteal :colo hhteal<CR>
|
||||
amenu T&hemes.&Green.Matrix :colo matrix<CR>
|
||||
amenu T&hemes.&Green.RobinHood :colo robinhood<CR>
|
||||
|
||||
" Looks Brown or not pure Black, this is the most popular category,
|
||||
" The top-two on vim.sf.net are all here.
|
||||
amenu T&hemes.&Grey_Brown.BlackDust :colo blackdust<CR>
|
||||
amenu T&hemes.&Grey_Brown.Camo :colo camo<CR>
|
||||
amenu T&hemes.&Grey_Brown.ChocolateLiquor :colo chocolateliquor<CR>
|
||||
amenu T&hemes.&Grey_Brown.Coffee :colo coffee<CR>
|
||||
amenu T&hemes.&Grey_Brown.Desert :colo desert<CR>
|
||||
amenu T&hemes.&Grey_Brown.HHorange :colo hhorange<CR>
|
||||
amenu T&hemes.&Grey_Brown.HHspring :colo hhspring<CR>
|
||||
amenu T&hemes.&Grey_Brown.MetaCosm :colo metacosm<CR>
|
||||
amenu T&hemes.&Grey_Brown.Navajo :colo navajo<CR>
|
||||
amenu T&hemes.&Grey_Brown.Neon :colo neon<CR>
|
||||
amenu T&hemes.&Grey_Brown.UmberGreen :colo umber-green<CR>
|
||||
amenu T&hemes.&Grey_Brown.Zenburn :colo zenburn<CR>
|
||||
|
||||
amenu T&hemes.-s3- :
|
||||
|
||||
" Any scheme with Violet, Magenta, Reddish Blue, or Red
|
||||
amenu T&hemes.&Violet_Red.Aiseered :colo aiseered<CR>
|
||||
amenu T&hemes.&Violet_Red.Asu1Dark :colo asu1dark<CR>
|
||||
amenu T&hemes.&Violet_Red.Caramel :colo caramel<CR>
|
||||
amenu T&hemes.&Violet_Red.EdoSea :colo edo_sea<CR>
|
||||
amenu T&hemes.&Violet_Red.HHpink :colo hhpink<CR>
|
||||
amenu T&hemes.&Violet_Red.HHviolet :colo hhviolet<CR>
|
||||
amenu T&hemes.&Violet_Red.Lilac :colo lilac<CR>
|
||||
amenu T&hemes.&Violet_Red.Mars :colo mars<CR>
|
||||
amenu T&hemes.&Violet_Red.Night :colo night<CR>
|
||||
amenu T&hemes.&Violet_Red.Tibet :colo tibet<CR>
|
||||
amenu T&hemes.&Violet_Red.TomatoSoup :colo tomatosoup<CR>
|
||||
amenu T&hemes.&Violet_Red.Xian :colo xian<CR>
|
||||
|
||||
" Light backgrounds which are not pure white
|
||||
amenu T&hemes.&OffWhite.Autumn :colo autumn2<CR>
|
||||
amenu T&hemes.&OffWhite.Bog :colo bog<CR>
|
||||
amenu T&hemes.&OffWhite.Brown :colo brown<CR>
|
||||
amenu T&hemes.&OffWhite.ButterCream :colo buttercream<CR>
|
||||
amenu T&hemes.&OffWhite.CleanPHP :colo cleanphp<CR>
|
||||
amenu T&hemes.&OffWhite.JHLight :colo jhlight<CR>
|
||||
amenu T&hemes.&OffWhite.OceanLight :colo oceanlight<CR>
|
||||
amenu T&hemes.&OffWhite.PapayaWhip :colo papayawhip<CR>
|
||||
amenu T&hemes.&OffWhite.Python :colo python<CR>
|
||||
amenu T&hemes.&OffWhite.Sand :colo sand<CR>
|
||||
amenu T&hemes.&OffWhite.SeaShell :colo seashell<CR>
|
||||
amenu T&hemes.&OffWhite.SF :colo sf<CR>
|
||||
" Note that on a well-adjusted monitor with 6500k temperature (standard),
|
||||
" #ffffff is not pure white, pure white should be less than #e8e8e8.
|
||||
amenu T&hemes.&OffWhite.TAqua :colo taqua<CR>
|
||||
amenu T&hemes.&OffWhite.TCSoft :colo tcsoft<CR>
|
||||
|
||||
" Pure White with light background
|
||||
amenu T&hemes.&White.Automation :colo automation<CR>
|
||||
amenu T&hemes.&White.Autumn :colo autumn<CR>
|
||||
amenu T&hemes.&White.AutumnLeaf :colo autumnleaf<CR>
|
||||
amenu T&hemes.&White.BioGoo :colo biogoo<CR>
|
||||
amenu T&hemes.&White.BMichaelsen :colo bmichaelsen<CR>
|
||||
amenu T&hemes.&White.BW :colo bw<CR>
|
||||
amenu T&hemes.&White.C :colo c<CR>
|
||||
amenu T&hemes.&White.ChelaLight :colo chela_light<CR>
|
||||
amenu T&hemes.&White.Dawn :colo dawn<CR>
|
||||
amenu T&hemes.&White.Emacs :colo emacs<CR>
|
||||
amenu T&hemes.&White.FineBlue :colo fine_blue<CR>
|
||||
amenu T&hemes.&White.Fog :colo fog<CR>
|
||||
amenu T&hemes.&White.Fruit :colo fruit<CR>
|
||||
amenu T&hemes.&White.Gobo :colo gobo<CR>
|
||||
amenu T&hemes.&White.IronMan :colo ironman<CR>
|
||||
amenu T&hemes.&White.LingoDirector :colo lingodirector<CR>
|
||||
amenu T&hemes.&White.ModTCSoft :colo mod_tcsoft<CR>
|
||||
amenu T&hemes.&White.NEdit :colo nedit<CR>
|
||||
amenu T&hemes.&White.NEdit2 :colo nedit2<CR>
|
||||
amenu T&hemes.&White.Nuvola :colo nuvola<CR>
|
||||
amenu T&hemes.&White.PS_Warm :let psc_style='warm'<CR>:colo ps_color<CR>
|
||||
amenu T&hemes.&White.PrintBW :colo print_bw<CR>
|
||||
amenu T&hemes.&White.SCite :colo scite<CR>
|
||||
amenu T&hemes.&White.SimpleAndFriendly :colo simpleandfriendly<CR>
|
||||
amenu T&hemes.&White.Tolerable :colo tolerable<CR>
|
||||
amenu T&hemes.&White.VC :colo vc<CR>
|
||||
amenu T&hemes.&White.VCBC :colo vcbc<CR>
|
||||
amenu T&hemes.&White.White :colo white<CR>
|
||||
amenu T&hemes.&White.WhiteDust :colo whitedust<CR>
|
||||
amenu T&hemes.&White.Xemacs :colo xemacs<CR>
|
||||
|
||||
amenu T&hemes.-s4- :
|
||||
|
||||
amenu T&hemes.Broken.AF\ (changes\ status\ line) :colo af<CR>
|
||||
amenu T&hemes.Broken.Potts\ (changes\ font) :colo potts<CR>
|
||||
amenu T&hemes.Broken.ToothPik\ (changes\ font) :colo toothpik<CR>
|
||||
24
vim/plugin/vim-markdown-preview/kramdown/COPYING
Executable file
24
vim/plugin/vim-markdown-preview/kramdown/COPYING
Executable file
@@ -0,0 +1,24 @@
|
||||
kramdown - fast, pure-Ruby Markdown-superset converter
|
||||
Copyright (C) 2009 Thomas Leitner <t_leitner@gmx.at>
|
||||
|
||||
kramdown is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
Some test cases and the benchmark files are based on test cases from
|
||||
the MDTest test suite:
|
||||
|
||||
MDTest
|
||||
Copyright (c) 2007 Michel Fortin
|
||||
<http://www.michelf.com/>
|
||||
|
||||
34
vim/plugin/vim-markdown-preview/kramdown/compatibility.rb
Executable file
34
vim/plugin/vim-markdown-preview/kramdown/compatibility.rb
Executable file
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
# All the code in this file is backported from Ruby 1.8.7 sothat kramdown works under 1.8.5
|
||||
|
||||
if RUBY_VERSION == '1.8.5'
|
||||
require 'rexml/parsers/baseparser'
|
||||
module REXML
|
||||
module Parsers
|
||||
class BaseParser
|
||||
UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
42
vim/plugin/vim-markdown-preview/kramdown/converter.rb
Executable file
42
vim/plugin/vim-markdown-preview/kramdown/converter.rb
Executable file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
# == Converter Module
|
||||
#
|
||||
# This module contains all available converters, i.e. classes that take a document and convert the
|
||||
# document tree to a specific output format, normally a string. For example, the Html module
|
||||
# converts the document tree into HTML.
|
||||
#
|
||||
# Converters use the Base class for common functionality (like applying a template to the output)-
|
||||
# see its API documentation for how to create a converter class.
|
||||
module Converter
|
||||
|
||||
autoload :Base, 'kramdown/converter/base'
|
||||
autoload :Html, 'kramdown/converter/html'
|
||||
autoload :Latex, 'kramdown/converter/latex'
|
||||
autoload :Kramdown, 'kramdown/converter/kramdown'
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
111
vim/plugin/vim-markdown-preview/kramdown/converter/base.rb
Executable file
111
vim/plugin/vim-markdown-preview/kramdown/converter/base.rb
Executable file
@@ -0,0 +1,111 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'erb'
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Converter
|
||||
|
||||
# == Base class for converters
|
||||
#
|
||||
# This class serves as base class for all converters. It provides methods that can/should be
|
||||
# used by all converters (like #generate_id) as well as common functionality that is
|
||||
# automatically applied to the result (for example, embedding the output into a template).
|
||||
#
|
||||
# == Implementing a converter
|
||||
#
|
||||
# Implementing a new converter is rather easy: just create a new sub class from this class and
|
||||
# put it in the Kramdown::Converter module (the latter is only needed if auto-detection should
|
||||
# work properly). Then you need to implement the #convert(tree) method which takes a document
|
||||
# tree and should return the converted output.
|
||||
#
|
||||
# The document instance is automatically set as @doc in Base#initialize. Furthermore, the
|
||||
# document instance provides a hash called `conversion_infos` that is also automatically cleared
|
||||
# and can be used to store information about the conversion process.
|
||||
#
|
||||
# The actual transformation of the document tree can be done in any way. However, writing one
|
||||
# method per tree element type is a straight forward way to do it - this is how the Html and
|
||||
# Latex converters do the transformation.
|
||||
class Base
|
||||
|
||||
# Initialize the converter with the given Kramdown document +doc+.
|
||||
def initialize(doc)
|
||||
@doc = doc
|
||||
@doc.conversion_infos.clear
|
||||
end
|
||||
private_class_method(:new, :allocate)
|
||||
|
||||
# Convert the Kramdown document +doc+ to the output format implemented by a subclass.
|
||||
#
|
||||
# Initializes a new instance of the calling class and then calls the #convert method that must
|
||||
# be implemented by each subclass. If the +template+ option is specified and non-empty, the
|
||||
# result is rendered into the specified template.
|
||||
def self.convert(doc)
|
||||
result = new(doc).convert(doc.tree)
|
||||
result = apply_template(doc, result) if !doc.options[:template].empty?
|
||||
result
|
||||
end
|
||||
|
||||
# Apply the template specified in the +doc+ options, using +body+ as the body string.
|
||||
def self.apply_template(doc, body)
|
||||
erb = ERB.new(get_template(doc.options[:template]))
|
||||
obj = Object.new
|
||||
obj.instance_variable_set(:@doc, doc)
|
||||
obj.instance_variable_set(:@body, body)
|
||||
erb.result(obj.instance_eval{binding})
|
||||
end
|
||||
|
||||
# Return the template specified by +template+.
|
||||
def self.get_template(template)
|
||||
format_ext = '.' + self.name.split(/::/).last.downcase
|
||||
shipped = File.join(::Kramdown.data_dir, template + format_ext)
|
||||
if File.exist?(template)
|
||||
File.read(template)
|
||||
elsif File.exist?(template + format_ext)
|
||||
File.read(template + format_ext)
|
||||
elsif File.exist?(shipped)
|
||||
File.read(shipped)
|
||||
else
|
||||
raise "The specified template file #{template} does not exist"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Generate an unique alpha-numeric ID from the the string +str+ for use as header ID.
|
||||
def generate_id(str)
|
||||
gen_id = str.gsub(/[^a-zA-Z0-9 -]/, '').gsub(/^[^a-zA-Z]*/, '').gsub(' ', '-').downcase
|
||||
gen_id = 'section' if gen_id.length == 0
|
||||
@used_ids ||= {}
|
||||
if @used_ids.has_key?(gen_id)
|
||||
gen_id += '-' + (@used_ids[gen_id] += 1).to_s
|
||||
else
|
||||
@used_ids[gen_id] = 0
|
||||
end
|
||||
@doc.options[:auto_id_prefix] + gen_id
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
391
vim/plugin/vim-markdown-preview/kramdown/converter/html.rb
Executable file
391
vim/plugin/vim-markdown-preview/kramdown/converter/html.rb
Executable file
@@ -0,0 +1,391 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'rexml/parsers/baseparser'
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Converter
|
||||
|
||||
# Converts a Kramdown::Document to HTML.
|
||||
class Html < Base
|
||||
|
||||
include ::Kramdown::Utils::HTML
|
||||
|
||||
# DEPRECATED: use #html_attributes
|
||||
def options_for_element(el)
|
||||
warn("DEPRECATION WARNING: this method will be deprecated in the next release, use #html_attributes instead")
|
||||
html_attributes(el)
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
|
||||
# Defines the amount of indentation used when nesting HTML tags.
|
||||
INDENTATION = 2
|
||||
|
||||
begin
|
||||
require 'coderay'
|
||||
|
||||
# Highlighting via coderay is available if this constant is +true+.
|
||||
HIGHLIGHTING_AVAILABLE = true
|
||||
rescue LoadError => e
|
||||
HIGHLIGHTING_AVAILABLE = false
|
||||
end
|
||||
|
||||
# Initialize the HTML converter with the given Kramdown document +doc+.
|
||||
def initialize(doc)
|
||||
super
|
||||
@footnote_counter = @footnote_start = @doc.options[:footnote_nr]
|
||||
@footnotes = []
|
||||
@toc = []
|
||||
@toc_code = nil
|
||||
end
|
||||
|
||||
def convert(el, indent = -INDENTATION, opts = {})
|
||||
send("convert_#{el.type}", el, indent, opts)
|
||||
end
|
||||
|
||||
def inner(el, indent, opts)
|
||||
result = ''
|
||||
indent += INDENTATION
|
||||
el.children.each do |inner_el|
|
||||
result << send("convert_#{inner_el.type}", inner_el, indent, opts)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def convert_blank(el, indent, opts)
|
||||
"\n"
|
||||
end
|
||||
|
||||
def convert_text(el, indent, opts)
|
||||
escape_html(el.value, :text)
|
||||
end
|
||||
|
||||
def convert_p(el, indent, opts)
|
||||
if el.options[:transparent]
|
||||
"#{inner(el, indent, opts)}"
|
||||
else
|
||||
"#{' '*indent}<p#{html_attributes(el)}>#{inner(el, indent, opts)}</p>\n"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_codeblock(el, indent, opts)
|
||||
if el.options[:attr] && el.options[:attr]['lang'] && HIGHLIGHTING_AVAILABLE
|
||||
el = Marshal.load(Marshal.dump(el)) # so that the original is not changed
|
||||
opts = {:wrap => @doc.options[:coderay_wrap], :line_numbers => @doc.options[:coderay_line_numbers],
|
||||
:line_number_start => @doc.options[:coderay_line_number_start], :tab_width => @doc.options[:coderay_tab_width],
|
||||
:bold_every => @doc.options[:coderay_bold_every], :css => @doc.options[:coderay_css]}
|
||||
result = CodeRay.scan(el.value, el.options[:attr].delete('lang').to_sym).html(opts).chomp + "\n"
|
||||
"#{' '*indent}<div#{html_attributes(el)}>#{result}#{' '*indent}</div>\n"
|
||||
else
|
||||
result = escape_html(el.value)
|
||||
if el.options[:attr] && el.options[:attr].has_key?('class') && el.options[:attr]['class'] =~ /\bshow-whitespaces\b/
|
||||
result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m|
|
||||
suffix = ($1 ? '-l' : ($2 ? '-r' : ''))
|
||||
m.scan(/./).map do |c|
|
||||
case c
|
||||
when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>"
|
||||
when " " then "<span class=\"ws-space#{suffix}\">⋅</span>"
|
||||
end
|
||||
end.join('')
|
||||
end
|
||||
end
|
||||
"#{' '*indent}<pre#{html_attributes(el)}><code>#{result}#{result =~ /\n\Z/ ? '' : "\n"}</code></pre>\n"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_blockquote(el, indent, opts)
|
||||
"#{' '*indent}<blockquote#{html_attributes(el)}>\n#{inner(el, indent, opts)}#{' '*indent}</blockquote>\n"
|
||||
end
|
||||
|
||||
def convert_header(el, indent, opts)
|
||||
el = Marshal.load(Marshal.dump(el)) # so that the original is not changed
|
||||
if @doc.options[:auto_ids] && !(el.options[:attr] && el.options[:attr]['id'])
|
||||
(el.options[:attr] ||= {})['id'] = generate_id(el.options[:raw_text])
|
||||
end
|
||||
@toc << [el.options[:level], el.options[:attr]['id'], el.children] if el.options[:attr] && el.options[:attr]['id'] && within_toc_depth?(el)
|
||||
"#{' '*indent}<h#{el.options[:level]}#{html_attributes(el)}>#{inner(el, indent, opts)}</h#{el.options[:level]}>\n"
|
||||
end
|
||||
|
||||
def within_toc_depth?(el)
|
||||
@doc.options[:toc_depth] <= 0 || el.options[:level] <= @doc.options[:toc_depth]
|
||||
end
|
||||
|
||||
def convert_hr(el, indent, opts)
|
||||
"#{' '*indent}<hr />\n"
|
||||
end
|
||||
|
||||
def convert_ul(el, indent, opts)
|
||||
if !@toc_code && (el.options[:ial][:refs].include?('toc') rescue nil) && (el.type == :ul || el.type == :ol)
|
||||
@toc_code = [el.type, el.options[:attr], (0..128).to_a.map{|a| rand(36).to_s(36)}.join]
|
||||
@toc_code.last
|
||||
else
|
||||
"#{' '*indent}<#{el.type}#{html_attributes(el)}>\n#{inner(el, indent, opts)}#{' '*indent}</#{el.type}>\n"
|
||||
end
|
||||
end
|
||||
alias :convert_ol :convert_ul
|
||||
alias :convert_dl :convert_ul
|
||||
|
||||
def convert_li(el, indent, opts)
|
||||
output = ' '*indent << "<#{el.type}" << html_attributes(el) << ">"
|
||||
res = inner(el, indent, opts)
|
||||
if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent])
|
||||
output << res << (res =~ /\n\Z/ ? ' '*indent : '')
|
||||
else
|
||||
output << "\n" << res << ' '*indent
|
||||
end
|
||||
output << "</#{el.type}>\n"
|
||||
end
|
||||
alias :convert_dd :convert_li
|
||||
|
||||
def convert_dt(el, indent, opts)
|
||||
"#{' '*indent}<dt#{html_attributes(el)}>#{inner(el, indent, opts)}</dt>\n"
|
||||
end
|
||||
|
||||
HTML_TAGS_WITH_BODY=['div', 'script']
|
||||
|
||||
def convert_html_element(el, indent, opts)
|
||||
res = inner(el, indent, opts)
|
||||
if el.options[:category] == :span
|
||||
"<#{el.value}#{html_attributes(el)}" << (!res.empty? ? ">#{res}</#{el.value}>" : " />")
|
||||
else
|
||||
output = ''
|
||||
output << ' '*indent if !el.options[:parent_is_raw]
|
||||
output << "<#{el.value}#{html_attributes(el)}"
|
||||
if !res.empty? && el.options[:parse_type] != :block
|
||||
output << ">#{res}</#{el.value}>"
|
||||
elsif !res.empty?
|
||||
output << ">\n#{res}" << ' '*indent << "</#{el.value}>"
|
||||
elsif HTML_TAGS_WITH_BODY.include?(el.value)
|
||||
output << "></#{el.value}>"
|
||||
else
|
||||
output << " />"
|
||||
end
|
||||
output << "\n" if el.options[:outer_element] || !el.options[:parent_is_raw]
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
def convert_xml_comment(el, indent, opts)
|
||||
if el.options[:category] == :block && !el.options[:parent_is_raw]
|
||||
' '*indent + el.value + "\n"
|
||||
else
|
||||
el.value
|
||||
end
|
||||
end
|
||||
alias :convert_xml_pi :convert_xml_comment
|
||||
alias :convert_html_doctype :convert_xml_comment
|
||||
|
||||
def convert_table(el, indent, opts)
|
||||
if el.options[:alignment].all? {|a| a == :default}
|
||||
alignment = ''
|
||||
else
|
||||
alignment = el.options[:alignment].map do |a|
|
||||
"#{' '*(indent + INDENTATION)}" + (a == :default ? "<col />" : "<col align=\"#{a}\" />") + "\n"
|
||||
end.join('')
|
||||
end
|
||||
"#{' '*indent}<table#{html_attributes(el)}>\n#{alignment}#{inner(el, indent, opts)}#{' '*indent}</table>\n"
|
||||
end
|
||||
|
||||
def convert_thead(el, indent, opts)
|
||||
"#{' '*indent}<#{el.type}#{html_attributes(el)}>\n#{inner(el, indent, opts)}#{' '*indent}</#{el.type}>\n"
|
||||
end
|
||||
alias :convert_tbody :convert_thead
|
||||
alias :convert_tfoot :convert_thead
|
||||
alias :convert_tr :convert_thead
|
||||
|
||||
def convert_td(el, indent, opts)
|
||||
res = inner(el, indent, opts)
|
||||
"#{' '*indent}<#{el.type}#{html_attributes(el)}>#{res.empty? ? " " : res}</#{el.type}>\n"
|
||||
end
|
||||
alias :convert_th :convert_td
|
||||
|
||||
def convert_comment(el, indent, opts)
|
||||
if el.options[:category] == :block
|
||||
"#{' '*indent}<!-- #{el.value} -->\n"
|
||||
else
|
||||
"<!-- #{el.value} -->"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_br(el, indent, opts)
|
||||
"<br />"
|
||||
end
|
||||
|
||||
def convert_a(el, indent, opts)
|
||||
do_obfuscation = el.options[:attr]['href'] =~ /^mailto:/
|
||||
if do_obfuscation
|
||||
el = Marshal.load(Marshal.dump(el)) # so that the original is not changed
|
||||
href = obfuscate(el.options[:attr]['href'].sub(/^mailto:/, ''))
|
||||
mailto = obfuscate('mailto')
|
||||
el.options[:attr]['href'] = "#{mailto}:#{href}"
|
||||
end
|
||||
res = inner(el, indent, opts)
|
||||
res = obfuscate(res) if do_obfuscation
|
||||
"<a#{html_attributes(el)}>#{res}</a>"
|
||||
end
|
||||
|
||||
def convert_img(el, indent, opts)
|
||||
"<img#{html_attributes(el)} />"
|
||||
end
|
||||
|
||||
def convert_codespan(el, indent, opts)
|
||||
"<code#{html_attributes(el)}>#{escape_html(el.value)}</code>"
|
||||
end
|
||||
|
||||
def convert_footnote(el, indent, opts)
|
||||
number = @footnote_counter
|
||||
@footnote_counter += 1
|
||||
@footnotes << [el.options[:name], @doc.parse_infos[:footnotes][el.options[:name]]]
|
||||
"<sup id=\"fnref:#{el.options[:name]}\"><a href=\"#fn:#{el.options[:name]}\" rel=\"footnote\">#{number}</a></sup>"
|
||||
end
|
||||
|
||||
def convert_raw(el, indent, opts)
|
||||
el.value + (el.options[:category] == :block ? "\n" : '')
|
||||
end
|
||||
|
||||
def convert_em(el, indent, opts)
|
||||
"<#{el.type}#{html_attributes(el)}>#{inner(el, indent, opts)}</#{el.type}>"
|
||||
end
|
||||
alias :convert_strong :convert_em
|
||||
|
||||
def convert_entity(el, indent, opts)
|
||||
entity_to_str(el.value)
|
||||
end
|
||||
|
||||
TYPOGRAPHIC_SYMS = {
|
||||
:mdash => [::Kramdown::Utils::Entities.entity('mdash')],
|
||||
:ndash => [::Kramdown::Utils::Entities.entity('ndash')],
|
||||
:hellip => [::Kramdown::Utils::Entities.entity('hellip')],
|
||||
:laquo_space => [::Kramdown::Utils::Entities.entity('laquo'), ::Kramdown::Utils::Entities.entity('nbsp')],
|
||||
:raquo_space => [::Kramdown::Utils::Entities.entity('nbsp'), ::Kramdown::Utils::Entities.entity('raquo')],
|
||||
:laquo => [::Kramdown::Utils::Entities.entity('laquo')],
|
||||
:raquo => [::Kramdown::Utils::Entities.entity('raquo')]
|
||||
}
|
||||
def convert_typographic_sym(el, indent, opts)
|
||||
TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('')
|
||||
end
|
||||
|
||||
def convert_smart_quote(el, indent, opts)
|
||||
entity_to_str(::Kramdown::Utils::Entities.entity(el.value.to_s))
|
||||
end
|
||||
|
||||
def convert_math(el, indent, opts)
|
||||
el = Marshal.load(Marshal.dump(el)) # so that the original is not changed
|
||||
el.options[:attr] ||= {}
|
||||
el.options[:attr]['class'] ||= ''
|
||||
el.options[:attr]['class'] += (el.options[:attr]['class'].empty? ? '' : ' ') + 'math'
|
||||
type = 'span'
|
||||
type = 'div' if el.options[:category] == :block
|
||||
"<#{type}#{html_attributes(el)}>#{escape_html(el.value)}</#{type}>#{type == 'div' ? "\n" : ''}"
|
||||
end
|
||||
|
||||
def convert_abbreviation(el, indent, opts)
|
||||
title = @doc.parse_infos[:abbrev_defs][el.value]
|
||||
title = nil if title.empty?
|
||||
"<abbr#{title ? " title=\"#{title}\"" : ''}>#{el.value}</abbr>"
|
||||
end
|
||||
|
||||
def convert_root(el, indent, opts)
|
||||
result = inner(el, indent, opts)
|
||||
result << footnote_content
|
||||
if @toc_code
|
||||
toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {})
|
||||
text = if toc_tree.children.size > 0
|
||||
convert(toc_tree, 0)
|
||||
else
|
||||
''
|
||||
end
|
||||
result.sub!(/#{@toc_code.last}/, text)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def generate_toc_tree(toc, type, attr)
|
||||
sections = Element.new(type, nil, {:attr => {'id' => 'markdown-toc'}.merge(attr)})
|
||||
stack = []
|
||||
toc.each do |level, id, children|
|
||||
li = Element.new(:li, nil, {:level => level})
|
||||
li.children << Element.new(:p, nil, {:transparent => true})
|
||||
a = Element.new(:a, nil, {:attr => {:href => "##{id}"}})
|
||||
a.children += children
|
||||
li.children.last.children << a
|
||||
li.children << Element.new(type)
|
||||
|
||||
success = false
|
||||
while !success
|
||||
if stack.empty?
|
||||
sections.children << li
|
||||
stack << li
|
||||
success = true
|
||||
elsif stack.last.options[:level] < li.options[:level]
|
||||
stack.last.children.last.children << li
|
||||
stack << li
|
||||
success = true
|
||||
else
|
||||
item = stack.pop
|
||||
item.children.pop unless item.children.last.children.size > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
while !stack.empty?
|
||||
item = stack.pop
|
||||
item.children.pop unless item.children.last.children.size > 0
|
||||
end
|
||||
sections
|
||||
end
|
||||
|
||||
# Helper method for obfuscating the +text+ by using HTML entities.
|
||||
def obfuscate(text)
|
||||
result = ""
|
||||
text.each_byte do |b|
|
||||
result += (b > 128 ? b.chr : "&#%03d;" % b)
|
||||
end
|
||||
result.force_encoding(text.encoding) if RUBY_VERSION >= '1.9'
|
||||
result
|
||||
end
|
||||
|
||||
# Return a HTML list with the footnote content for the used footnotes.
|
||||
def footnote_content
|
||||
ol = Element.new(:ol)
|
||||
ol.options[:attr] = {'start' => @footnote_start} if @footnote_start != 1
|
||||
@footnotes.each do |name, data|
|
||||
li = Element.new(:li, nil, {:attr => {:id => "fn:#{name}"}, :first_is_block => true})
|
||||
li.children = Marshal.load(Marshal.dump(data[:content].children)) #TODO: probably remove this!!!!
|
||||
ol.children << li
|
||||
|
||||
ref = Element.new(:raw, "<a href=\"#fnref:#{name}\" rev=\"footnote\">↩</a>")
|
||||
if li.children.last.type == :p
|
||||
para = li.children.last
|
||||
else
|
||||
li.children << (para = Element.new(:p))
|
||||
end
|
||||
para.children << ref
|
||||
end
|
||||
(ol.children.empty? ? '' : "<div class=\"footnotes\">\n#{convert(ol, 2)}</div>\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
398
vim/plugin/vim-markdown-preview/kramdown/converter/kramdown.rb
Executable file
398
vim/plugin/vim-markdown-preview/kramdown/converter/kramdown.rb
Executable file
@@ -0,0 +1,398 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'rexml/parsers/baseparser'
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Converter
|
||||
|
||||
# Converts a Kramdown::Document to the kramdown format.
|
||||
class Kramdown < Base
|
||||
|
||||
# :stopdoc:
|
||||
|
||||
include ::Kramdown::Utils::HTML
|
||||
|
||||
def initialize(doc)
|
||||
super
|
||||
@linkrefs = []
|
||||
@footnotes = []
|
||||
@abbrevs = []
|
||||
@stack = []
|
||||
end
|
||||
|
||||
def convert(el, opts = {})
|
||||
res = send("convert_#{el.type}", el, opts)
|
||||
if el.type != :html_element && el.type != :li && el.type != :dd && (ial = ial_for_element(el))
|
||||
res << ial
|
||||
res << "\n\n" if el.options[:category] == :block
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def inner(el, opts = {})
|
||||
@stack.push([el, opts])
|
||||
result = ''
|
||||
el.children.each_with_index do |inner_el, index|
|
||||
options = opts.dup
|
||||
#p [index, inner_el]
|
||||
options[:index] = index
|
||||
options[:prev] = (index == 0 ? nil : el.children[index-1])
|
||||
options[:next] = (index == el.children.length - 1 ? nil : el.children[index+1])
|
||||
result << convert(inner_el, options)
|
||||
end
|
||||
@stack.pop
|
||||
result
|
||||
end
|
||||
|
||||
def convert_blank(el, opts)
|
||||
"\n"
|
||||
end
|
||||
|
||||
ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]\{\}"'])|^[ ]{0,3}(:)/
|
||||
|
||||
def convert_text(el, opts)
|
||||
if opts[:raw_text]
|
||||
el.value
|
||||
else
|
||||
nl = (el.value =~ /\n$/)
|
||||
el.value.gsub(/\s+/, ' ').gsub(ESCAPED_CHAR_RE) { "\\#{$1 || $2}" } + (nl ? "\n" : '')
|
||||
end
|
||||
end
|
||||
|
||||
def convert_p(el, opts)
|
||||
res = inner(el, opts).strip.gsub(/\A(?:([#|])|(\d+)\.|([+-]\s))/) do
|
||||
$1 || $3 ? "\\#{$1 || $3}" : "#{$2}\\."
|
||||
end + "\n"
|
||||
if opts[:next] && opts[:next].type == :p && !ial_for_element(el)
|
||||
res += "\n"
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
CODEBLOCK_PREV_EL = [:ul, :ol, :dl, :codeblock]
|
||||
|
||||
def convert_codeblock(el, opts)
|
||||
res = ''
|
||||
res << "^\n" if opts[:prev] && ((CODEBLOCK_PREV_EL.include?(opts[:prev].type) && !ial_for_element(opts[:prev])) ||
|
||||
(opts[:prev].type == :blank &&
|
||||
opts[:index]-2 >= 0 &&
|
||||
(tmp = @stack.last.first.children[opts[:index]-2]) &&
|
||||
CODEBLOCK_PREV_EL.include?(tmp.type) && !ial_for_element(tmp)))
|
||||
res << el.value.split(/\n/).map {|l| l.empty? ? " " : " #{l}"}.join("\n") + "\n"
|
||||
end
|
||||
|
||||
def convert_blockquote(el, opts)
|
||||
res = ''
|
||||
res << "\n" if opts[:prev] && opts[:prev].type == :blockquote
|
||||
res << inner(el, opts).chomp.split(/\n/).map {|l| "> #{l}"}.join("\n") << "\n"
|
||||
end
|
||||
|
||||
def convert_header(el, opts)
|
||||
res = ''
|
||||
res << "\n" if opts[:prev] && opts[:prev].type != :blank
|
||||
res << "#{'#' * el.options[:level]} #{inner(el, opts)}"
|
||||
res << " {##{el.options[:attr]['id']}}" if el.options[:attr] && el.options[:attr]['id']
|
||||
res << "\n" if opts[:next] && opts[:next].type != :blank
|
||||
res << "\n"
|
||||
end
|
||||
|
||||
def convert_hr(el, opts)
|
||||
"* * *\n"
|
||||
end
|
||||
|
||||
def convert_ul(el, opts)
|
||||
res = ''
|
||||
res << "\n" if opts[:prev] && (opts[:prev].type == :p && !opts[:prev].options[:transparent])
|
||||
res << "^\n" if opts[:prev] && ((opts[:prev].type == el.type && !ial_for_element(opts[:prev])) ||
|
||||
(opts[:prev].type == :blank && opts[:index]-2 >= 0 &&
|
||||
(tmp = @stack.last.first.children[opts[:index]-2]) &&
|
||||
tmp.type == el.type && !ial_for_element(tmp)))
|
||||
res + inner(el, opts).sub(/\n+\Z/, "\n")
|
||||
end
|
||||
alias :convert_ol :convert_ul
|
||||
alias :convert_dl :convert_ul
|
||||
|
||||
def convert_li(el, opts)
|
||||
sym, width = if @stack.last.first.type == :ul
|
||||
['* ', el.children.first.type == :codeblock ? 4 : 2]
|
||||
else
|
||||
["#{opts[:index] + 1}.".ljust(4), 4]
|
||||
end
|
||||
if ial = ial_for_element(el)
|
||||
sym += ial + " "
|
||||
end
|
||||
|
||||
first, *last = inner(el, opts).chomp.split(/\n/)
|
||||
last = last.map {|l| " "*width + l}.join("\n")
|
||||
last = last.empty? ? "\n" : "\n#{last}\n"
|
||||
if el.children.first.type == :p && !el.children.first.options[:transparent]
|
||||
res = "#{sym}#{first}\n#{last}"
|
||||
res << "^\n" if el.children.size == 1 && @stack.last.first.children.last == el &&
|
||||
(@stack.last.first.children.any? {|c| c.children.first.type != :p} || @stack.last.first.children.size == 1)
|
||||
res
|
||||
elsif el.children.first.type == :codeblock
|
||||
"#{sym}\n #{first}#{last}"
|
||||
else
|
||||
"#{sym}#{first}#{last}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_dd(el, opts)
|
||||
sym, width = ": ", (el.children.first.type == :codeblock ? 4 : 2)
|
||||
if ial = ial_for_element(el)
|
||||
sym += ial + " "
|
||||
end
|
||||
|
||||
first, *last = inner(el, opts).chomp.split(/\n/)
|
||||
last = last.map {|l| " "*width + l}.join("\n")
|
||||
text = first + (last.empty? ? '' : "\n" + last)
|
||||
if el.children.first.type == :p && !el.children.first.options[:transparent]
|
||||
"\n#{sym}#{text}\n"
|
||||
elsif el.children.first.type == :codeblock
|
||||
"#{sym}\n #{text}\n"
|
||||
else
|
||||
"#{sym}#{text}\n"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_dt(el, opts)
|
||||
res = ''
|
||||
res << inner(el, opts) << "\n"
|
||||
end
|
||||
|
||||
HTML_TAGS_WITH_BODY=['div', 'script']
|
||||
|
||||
def convert_html_element(el, opts)
|
||||
markdown_attr = el.options[:category] == :block && el.children.any? do |c|
|
||||
c.type != :html_element && (c.type != :p || !c.options[:transparent]) && c.options[:category] == :block
|
||||
end
|
||||
opts[:force_raw_text] = true if %w{script pre code}.include?(el.value)
|
||||
opts[:raw_text] = opts[:force_raw_text] || opts[:block_raw_text] || (el.options[:category] != :span && !markdown_attr)
|
||||
opts[:block_raw_text] = true if el.options[:category] == :block && opts[:raw_text]
|
||||
res = inner(el, opts)
|
||||
if el.options[:category] == :span
|
||||
"<#{el.value}#{html_attributes(el)}" << (!res.empty? ? ">#{res}</#{el.value}>" : " />")
|
||||
else
|
||||
output = ''
|
||||
output << "<#{el.value}#{html_attributes(el)}"
|
||||
output << " markdown=\"1\"" if markdown_attr
|
||||
if !res.empty? && el.options[:parse_type] != :block
|
||||
output << ">#{res}</#{el.value}>"
|
||||
elsif !res.empty?
|
||||
output << ">\n#{res}" << "</#{el.value}>"
|
||||
elsif HTML_TAGS_WITH_BODY.include?(el.value)
|
||||
output << "></#{el.value}>"
|
||||
else
|
||||
output << " />"
|
||||
end
|
||||
output << "\n" if el.options[:outer_element] || !el.options[:parent_is_raw]
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
def convert_xml_comment(el, opts)
|
||||
if el.options[:category] == :block && !el.options[:parent_is_raw]
|
||||
el.value + "\n"
|
||||
else
|
||||
el.value
|
||||
end
|
||||
end
|
||||
alias :convert_xml_pi :convert_xml_comment
|
||||
alias :convert_html_doctype :convert_xml_comment
|
||||
|
||||
def convert_table(el, opts)
|
||||
opts[:alignment] = el.options[:alignment]
|
||||
inner(el, opts)
|
||||
end
|
||||
|
||||
def convert_thead(el, opts)
|
||||
rows = inner(el, opts)
|
||||
if opts[:alignment].all? {|a| a == :default}
|
||||
"#{rows}|" + "-"*10 + "\n"
|
||||
else
|
||||
"#{rows}| " + opts[:alignment].map do |a|
|
||||
case a
|
||||
when :left then ":-"
|
||||
when :right then "-:"
|
||||
when :center then ":-:"
|
||||
when :default then "-"
|
||||
end
|
||||
end.join(' ') + "\n"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_tbody(el, opts)
|
||||
res = ''
|
||||
res << inner(el, opts)
|
||||
res << '|' << '-'*10 << "\n" if opts[:next] && opts[:next].type == :tbody
|
||||
res
|
||||
end
|
||||
|
||||
def convert_tfoot(el, opts)
|
||||
"|" + "="*10 + "\n#{inner(el, opts)}"
|
||||
end
|
||||
|
||||
def convert_tr(el, opts)
|
||||
"| " + el.children.map {|c| convert(c, opts)}.join(" | ") + " |\n"
|
||||
end
|
||||
|
||||
def convert_td(el, opts)
|
||||
inner(el, opts).gsub(/\|/, '\\|')
|
||||
end
|
||||
alias :convert_th :convert_td
|
||||
|
||||
def convert_comment(el, opts)
|
||||
if el.options[:category] == :block
|
||||
"{::comment}\n#{el.value}\n{:/}\n"
|
||||
else
|
||||
"{::comment}#{el.value}{:/}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_br(el, opts)
|
||||
" \n"
|
||||
end
|
||||
|
||||
def convert_a(el, opts)
|
||||
if el.options[:attr]['href'].empty?
|
||||
"[#{inner(el, opts)}]()"
|
||||
else
|
||||
@linkrefs << el
|
||||
"[#{inner(el, opts)}][#{@linkrefs.size}]"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_img(el, opts)
|
||||
title = (el.options[:attr]['title'] ? ' "' + el.options[:attr]['title'].gsub(/"/, """) + '"' : '')
|
||||
"![#{el.options[:attr]['alt']}](<#{el.options[:attr]['src']}>#{title})"
|
||||
end
|
||||
|
||||
def convert_codespan(el, opts)
|
||||
delim = (el.value.scan(/`+/).max || '') + '`'
|
||||
"#{delim}#{' ' if delim.size > 1}#{el.value}#{' ' if delim.size > 1}#{delim}"
|
||||
end
|
||||
|
||||
def convert_footnote(el, opts)
|
||||
@footnotes << [el.options[:name], @doc.parse_infos[:footnotes][el.options[:name]]]
|
||||
"[^#{el.options[:name]}]"
|
||||
end
|
||||
|
||||
def convert_raw(el, opts)
|
||||
if @stack.last.first.type == :html_element
|
||||
el.value
|
||||
elsif el.options[:category] == :block
|
||||
"{::nomarkdown}\n#{el.value}\n{:/}\n"
|
||||
else
|
||||
"{::nomarkdown}#{el.value}{:/}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_em(el, opts)
|
||||
"*#{inner(el, opts)}*"
|
||||
end
|
||||
|
||||
def convert_strong(el, opts)
|
||||
"**#{inner(el, opts)}**"
|
||||
end
|
||||
|
||||
def convert_entity(el, opts)
|
||||
entity_to_str(el.value)
|
||||
end
|
||||
|
||||
TYPOGRAPHIC_SYMS = {
|
||||
:mdash => '---', :ndash => '--', :hellip => '...',
|
||||
:laquo_space => '<< ', :raquo_space => ' >>',
|
||||
:laquo => '<<', :raquo => '>>'
|
||||
}
|
||||
def convert_typographic_sym(el, opts)
|
||||
TYPOGRAPHIC_SYMS[el.value]
|
||||
end
|
||||
|
||||
def convert_smart_quote(el, opts)
|
||||
el.value.to_s =~ /[rl]dquo/ ? "\"" : "'"
|
||||
end
|
||||
|
||||
def convert_math(el, opts)
|
||||
(@stack.last.first.type == :p && opts[:prev].nil? ? "\\" : '') + "$$#{el.value}$$" + (el.options[:category] == :block ? "\n" : '')
|
||||
end
|
||||
|
||||
def convert_abbreviation(el, opts)
|
||||
el.value
|
||||
end
|
||||
|
||||
def convert_root(el, opts)
|
||||
res = inner(el, opts)
|
||||
res << create_link_defs
|
||||
res << create_footnote_defs
|
||||
res << create_abbrev_defs
|
||||
res
|
||||
end
|
||||
|
||||
def create_link_defs
|
||||
res = ''
|
||||
res << "\n\n" if @linkrefs.size > 0
|
||||
@linkrefs.each_with_index do |el, i|
|
||||
link = (el.type == :a ? el.options[:attr]['href'] : el.options[:attr]['src'])
|
||||
link = "<#{link}>" if link =~ / /
|
||||
title = el.options[:attr]['title']
|
||||
res << "[#{i+1}]: #{link} #{title ? '"' + title.gsub(/"/, """) + '"' : ''}\n"
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def create_footnote_defs
|
||||
res = ''
|
||||
res = "\n" if @footnotes.size > 0
|
||||
@footnotes.each do |name, data|
|
||||
res << "\n[^#{name}]:\n"
|
||||
res << inner(data[:content]).chomp.split(/\n/).map {|l| " #{l}"}.join("\n")
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def create_abbrev_defs
|
||||
return '' unless @doc.parse_infos[:abbrev_defs]
|
||||
res = ''
|
||||
@doc.parse_infos[:abbrev_defs].each do |name, text|
|
||||
res << "*[#{name}]: #{text}\n"
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
# Return the IAL containing the attributes of the element +el+.
|
||||
def ial_for_element(el)
|
||||
res = (el.options[:attr] || {}).map do |k,v|
|
||||
next if [:img, :a].include?(el.type) && ['href', 'src', 'alt', 'title'].include?(k)
|
||||
next if el.type == :header && k == 'id'
|
||||
v.nil? ? '' : " #{k}=\"#{v.to_s}\""
|
||||
end.compact.sort.join('')
|
||||
res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
||||
(el.options[:ial][:refs].include?('toc') rescue nil)
|
||||
res.strip.empty? ? nil : "{:#{res}}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
553
vim/plugin/vim-markdown-preview/kramdown/converter/latex.rb
Executable file
553
vim/plugin/vim-markdown-preview/kramdown/converter/latex.rb
Executable file
@@ -0,0 +1,553 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'set'
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Converter
|
||||
|
||||
# Converts a Kramdown::Document to LaTeX. This converter uses ideas from other Markdown-to-LaTeX
|
||||
# converters like Pandoc and Maruku.
|
||||
class Latex < Base
|
||||
|
||||
# :stopdoc:
|
||||
|
||||
# Initialize the LaTeX converter with the given Kramdown document +doc+.
|
||||
def initialize(doc)
|
||||
super
|
||||
#TODO: set the footnote counter at the beginning of the document
|
||||
@doc.options[:footnote_nr]
|
||||
@doc.conversion_infos[:packages] = Set.new
|
||||
end
|
||||
|
||||
def convert(el, opts = {})
|
||||
send("convert_#{el.type}", el, opts)
|
||||
end
|
||||
|
||||
def inner(el, opts)
|
||||
result = ''
|
||||
el.children.each do |inner_el|
|
||||
result << send("convert_#{inner_el.type}", inner_el, opts)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def convert_root(el, opts)
|
||||
inner(el, opts)
|
||||
end
|
||||
|
||||
def convert_blank(el, opts)
|
||||
""
|
||||
end
|
||||
|
||||
def convert_text(el, opts)
|
||||
escape(el.value)
|
||||
end
|
||||
|
||||
def convert_p(el, opts)
|
||||
"#{inner(el, opts)}\n\n"
|
||||
end
|
||||
|
||||
def convert_codeblock(el, opts)
|
||||
show_whitespace = el.options[:attr] && el.options[:attr]['class'].to_s =~ /\bshow-whitespaces\b/
|
||||
lang = el.options[:attr] && el.options[:attr]['lang']
|
||||
if show_whitespace || lang
|
||||
result = "\\lstset{showspaces=%s,showtabs=%s}\n" % (show_whitespace ? ['true', 'true'] : ['false', 'false'])
|
||||
result += "\\lstset{language=#{lang}}\n" if lang
|
||||
result += "\\lstset{basicstyle=\\ttfamily\\footnotesize}\\lstset{columns=fixed,frame=tlbr}\n"
|
||||
"#{result}\\begin{lstlisting}#{attribute_list(el)}\n#{el.value}\n\\end{lstlisting}\n"
|
||||
else
|
||||
"\\begin{verbatim}#{el.value}\\end{verbatim}\n"
|
||||
end
|
||||
end
|
||||
|
||||
def latex_environment(type, el, text)
|
||||
"\\begin{#{type}}#{attribute_list(el)}\n#{text}\n\\end{#{type}}\n"
|
||||
end
|
||||
|
||||
def convert_blockquote(el, opts)
|
||||
latex_environment('quote', el, inner(el, opts))
|
||||
end
|
||||
|
||||
HEADER_TYPES = {
|
||||
1 => 'section',
|
||||
2 => 'subsection',
|
||||
3 => 'subsubsection',
|
||||
4 => 'paragraph',
|
||||
5 => 'subparagraph',
|
||||
6 => 'subparagraph'
|
||||
}
|
||||
def convert_header(el, opts)
|
||||
type = HEADER_TYPES[el.options[:level]]
|
||||
if ((el.options[:attr] && (id = el.options[:attr]['id'])) ||
|
||||
(@doc.options[:auto_ids] && (id = generate_id(el.options[:raw_text])))) &&
|
||||
(@doc.options[:toc_depth] <= 0 || el.options[:level] <= @doc.options[:toc_depth])
|
||||
"\\hypertarget{#{id}}{}\\#{type}{#{inner(el, opts)}}\\label{#{id}}\n\n"
|
||||
else
|
||||
"\\#{type}*{#{inner(el, opts)}}\n\n"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_hr(el, opts)
|
||||
"\\begin{center}#{attribute_list(el)}\n\\rule{3in}{0.4pt}\n\\end{center}\n"
|
||||
end
|
||||
|
||||
def convert_ul(el, opts)
|
||||
if !@doc.conversion_infos[:has_toc] && (el.options[:ial][:refs].include?('toc') rescue nil)
|
||||
@doc.conversion_infos[:has_toc] = true
|
||||
'\tableofcontents'
|
||||
else
|
||||
latex_environment(el.type == :ul ? 'itemize' : 'enumerate', el, inner(el, opts))
|
||||
end
|
||||
end
|
||||
alias :convert_ol :convert_ul
|
||||
|
||||
def convert_dl(el, opts)
|
||||
latex_environment('description', el, inner(el, opts))
|
||||
end
|
||||
|
||||
def convert_li(el, opts)
|
||||
"\\item #{inner(el, opts).sub(/\n+\Z/, '')}\n"
|
||||
end
|
||||
|
||||
def convert_dt(el, opts)
|
||||
"\\item[#{inner(el, opts)}] "
|
||||
end
|
||||
|
||||
def convert_dd(el, opts)
|
||||
"#{inner(el, opts)}\n\n"
|
||||
end
|
||||
|
||||
def convert_html_element(el, opts)
|
||||
if el.value == 'i'
|
||||
"\\emph{#{inner(el, opts)}}"
|
||||
elsif el.value == 'b'
|
||||
"\\emph{#{inner(el, opts)}}"
|
||||
else
|
||||
@doc.warnings << "Can't convert HTML element"
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
def convert_xml_comment(el, opts)
|
||||
el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n"
|
||||
end
|
||||
|
||||
def convert_xml_pi(el, opts)
|
||||
@doc.warnings << "Can't convert XML PI/HTML document type"
|
||||
''
|
||||
end
|
||||
alias :convert_html_doctype :convert_xml_pi
|
||||
|
||||
TABLE_ALIGNMENT_CHAR = {:default => 'l', :left => 'l', :center => 'c', :right => 'r'}
|
||||
|
||||
def convert_table(el, opts)
|
||||
align = el.options[:alignment].map {|a| TABLE_ALIGNMENT_CHAR[a]}.join('|')
|
||||
"\\begin{tabular}{|#{align}|}#{attribute_list(el)}\n\\hline\n#{inner(el, opts)}\\hline\n\\end{tabular}\n\n"
|
||||
end
|
||||
|
||||
def convert_thead(el, opts)
|
||||
"#{inner(el, opts)}\\hline\n"
|
||||
end
|
||||
|
||||
def convert_tbody(el, opts)
|
||||
inner(el, opts)
|
||||
end
|
||||
|
||||
def convert_tfoot(el, opts)
|
||||
"\\hline \\hline \n#{inner(el, opts)}"
|
||||
end
|
||||
|
||||
def convert_tr(el, opts)
|
||||
el.children.map {|c| send("convert_#{c.type}", c, opts)}.join(' & ') + "\\\\\n"
|
||||
end
|
||||
|
||||
def convert_td(el, opts)
|
||||
inner(el, opts)
|
||||
end
|
||||
alias :convert_th :convert_td
|
||||
|
||||
def convert_comment(el, opts)
|
||||
el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n"
|
||||
end
|
||||
|
||||
def convert_br(el, opts)
|
||||
"\\newline\n"
|
||||
end
|
||||
|
||||
def convert_a(el, opts)
|
||||
url = el.options[:attr]['href']
|
||||
if url =~ /^#/
|
||||
"\\hyperlink{#{url[1..-1]}}{#{inner(el, opts)}}"
|
||||
else
|
||||
"\\href{#{url}}{#{inner(el, opts)}}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_img(el, opts)
|
||||
if el.options[:attr]['src'] =~ /^(https?|ftps?):\/\//
|
||||
@doc.warnings << "Cannot include non-local image"
|
||||
''
|
||||
elsif !el.options[:attr]['src'].empty?
|
||||
@doc.conversion_infos[:packages] << 'graphicx'
|
||||
"\\includegraphics{#{el.options[:attr]['src']}}"
|
||||
else
|
||||
@doc.warnings << "Cannot include image with empty path"
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
def convert_codespan(el, opts)
|
||||
"{\\tt #{escape(el.value)}}"
|
||||
end
|
||||
|
||||
def convert_footnote(el, opts)
|
||||
@doc.conversion_infos[:packages] << 'fancyvrb'
|
||||
"\\footnote{#{inner(@doc.parse_infos[:footnotes][el.options[:name]][:content], opts)}}"
|
||||
end
|
||||
|
||||
def convert_raw(el, opts)
|
||||
escape(el.value)
|
||||
end
|
||||
|
||||
def convert_em(el, opts)
|
||||
"\\emph{#{inner(el, opts)}}"
|
||||
end
|
||||
|
||||
def convert_strong(el, opts)
|
||||
"\\textbf{#{inner(el, opts)}}"
|
||||
end
|
||||
|
||||
# Inspired by Maruku: entity conversion table based on the one from htmltolatex
|
||||
# (http://sourceforge.net/projects/htmltolatex/), with some small adjustments/additions
|
||||
ENTITY_CONV_TABLE = {
|
||||
913 => ['$A$'],
|
||||
914 => ['$B$'],
|
||||
915 => ['$\Gamma$'],
|
||||
916 => ['$\Delta$'],
|
||||
917 => ['$E$'],
|
||||
918 => ['$Z$'],
|
||||
919 => ['$H$'],
|
||||
920 => ['$\Theta$'],
|
||||
921 => ['$I$'],
|
||||
922 => ['$K$'],
|
||||
923 => ['$\Lambda$'],
|
||||
924 => ['$M$'],
|
||||
925 => ['$N$'],
|
||||
926 => ['$\Xi$'],
|
||||
927 => ['$O$'],
|
||||
928 => ['$\Pi$'],
|
||||
929 => ['$P$'],
|
||||
931 => ['$\Sigma$'],
|
||||
932 => ['$T$'],
|
||||
933 => ['$Y$'],
|
||||
934 => ['$\Phi$'],
|
||||
935 => ['$X$'],
|
||||
936 => ['$\Psi$'],
|
||||
937 => ['$\Omega$'],
|
||||
945 => ['$\alpha$'],
|
||||
946 => ['$\beta$'],
|
||||
947 => ['$\gamma$'],
|
||||
948 => ['$\delta$'],
|
||||
949 => ['$\epsilon$'],
|
||||
950 => ['$\zeta$'],
|
||||
951 => ['$\eta$'],
|
||||
952 => ['$\theta$'],
|
||||
953 => ['$\iota$'],
|
||||
954 => ['$\kappa$'],
|
||||
955 => ['$\lambda$'],
|
||||
956 => ['$\mu$'],
|
||||
957 => ['$\nu$'],
|
||||
958 => ['$\xi$'],
|
||||
959 => ['$o$'],
|
||||
960 => ['$\pi$'],
|
||||
961 => ['$\rho$'],
|
||||
963 => ['$\sigma$'],
|
||||
964 => ['$\tau$'],
|
||||
965 => ['$\upsilon$'],
|
||||
966 => ['$\phi$'],
|
||||
967 => ['$\chi$'],
|
||||
968 => ['$\psi$'],
|
||||
969 => ['$\omega$'],
|
||||
962 => ['$\varsigma$'],
|
||||
977 => ['$\vartheta$'],
|
||||
982 => ['$\varpi$'],
|
||||
8230 => ['\ldots'],
|
||||
8242 => ['$\prime$'],
|
||||
8254 => ['-'],
|
||||
8260 => ['/'],
|
||||
8472 => ['$\wp$'],
|
||||
8465 => ['$\Im$'],
|
||||
8476 => ['$\Re$'],
|
||||
8501 => ['$\aleph$'],
|
||||
8226 => ['$\bullet$'],
|
||||
8482 => ['$^{\rm TM}$'],
|
||||
8592 => ['$\leftarrow$'],
|
||||
8594 => ['$\rightarrow$'],
|
||||
8593 => ['$\uparrow$'],
|
||||
8595 => ['$\downarrow$'],
|
||||
8596 => ['$\leftrightarrow$'],
|
||||
8629 => ['$\hookleftarrow$'],
|
||||
8657 => ['$\Uparrow$'],
|
||||
8659 => ['$\Downarrow$'],
|
||||
8656 => ['$\Leftarrow$'],
|
||||
8658 => ['$\Rightarrow$'],
|
||||
8660 => ['$\Leftrightarrow$'],
|
||||
8704 => ['$\forall$'],
|
||||
8706 => ['$\partial$'],
|
||||
8707 => ['$\exists$'],
|
||||
8709 => ['$\emptyset$'],
|
||||
8711 => ['$\nabla$'],
|
||||
8712 => ['$\in$'],
|
||||
8715 => ['$\ni$'],
|
||||
8713 => ['$\notin$'],
|
||||
8721 => ['$\sum$'],
|
||||
8719 => ['$\prod$'],
|
||||
8722 => ['$-$'],
|
||||
8727 => ['$\ast$'],
|
||||
8730 => ['$\surd$'],
|
||||
8733 => ['$\propto$'],
|
||||
8734 => ['$\infty$'],
|
||||
8736 => ['$\angle$'],
|
||||
8743 => ['$\wedge$'],
|
||||
8744 => ['$\vee$'],
|
||||
8745 => ['$\cup$'],
|
||||
8746 => ['$\cap$'],
|
||||
8747 => ['$\int$'],
|
||||
8756 => ['$\therefore$', 'amssymb'],
|
||||
8764 => ['$\sim$'],
|
||||
8776 => ['$\approx$'],
|
||||
8773 => ['$\cong$'],
|
||||
8800 => ['$\neq$'],
|
||||
8801 => ['$\equiv$'],
|
||||
8804 => ['$\leq$'],
|
||||
8805 => ['$\geq$'],
|
||||
8834 => ['$\subset$'],
|
||||
8835 => ['$\supset$'],
|
||||
8838 => ['$\subseteq$'],
|
||||
8839 => ['$\supseteq$'],
|
||||
8836 => ['$\nsubset$', 'amssymb'],
|
||||
8853 => ['$\oplus$'],
|
||||
8855 => ['$\otimes$'],
|
||||
8869 => ['$\perp$'],
|
||||
8901 => ['$\cdot$'],
|
||||
8968 => ['$\rceil$'],
|
||||
8969 => ['$\lceil$'],
|
||||
8970 => ['$\lfloor$'],
|
||||
8971 => ['$\rfloor$'],
|
||||
9001 => ['$\rangle$'],
|
||||
9002 => ['$\langle$'],
|
||||
9674 => ['$\lozenge$', 'amssymb'],
|
||||
9824 => ['$\spadesuit$'],
|
||||
9827 => ['$\clubsuit$'],
|
||||
9829 => ['$\heartsuit$'],
|
||||
9830 => ['$\diamondsuit$'],
|
||||
38 => ['\&'],
|
||||
34 => ['"'],
|
||||
39 => ['\''],
|
||||
169 => ['\copyright'],
|
||||
60 => ['\textless{}'],
|
||||
62 => ['\textgreater{}'],
|
||||
338 => ['\OE'],
|
||||
339 => ['\oe'],
|
||||
352 => ['\v{S}'],
|
||||
353 => ['\v{s}'],
|
||||
376 => ['\"Y'],
|
||||
710 => ['\textasciicircum'],
|
||||
732 => ['\textasciitilde'],
|
||||
8211 => ['--'],
|
||||
8212 => ['---'],
|
||||
8216 => ['`'],
|
||||
8217 => ['\''],
|
||||
8220 => ['``'],
|
||||
8221 => ['\'\''],
|
||||
8224 => ['\dag'],
|
||||
8225 => ['\ddag'],
|
||||
8240 => ['\permil', 'wasysym'],
|
||||
8364 => ['\euro', 'eurosym'],
|
||||
8249 => ['\guilsinglleft'],
|
||||
8250 => ['\guilsinglright'],
|
||||
8218 => ['\quotesinglbase', 'mathcomp'],
|
||||
8222 => ['\quotedblbase', 'mathcomp'],
|
||||
402 => ['\textflorin', 'mathcomp'],
|
||||
381 => ['\v{Z}'],
|
||||
382 => ['\v{z}'],
|
||||
160 => ['\nolinebreak'],
|
||||
161 => ['\textexclamdown'],
|
||||
163 => ['\pounds'],
|
||||
164 => ['\currency', 'wasysym'],
|
||||
165 => ['\textyen', 'textcomp'],
|
||||
166 => ['\brokenvert', 'wasysym'],
|
||||
167 => ['\S'],
|
||||
171 => ['\guillemotleft'],
|
||||
187 => ['\guillemotright'],
|
||||
174 => ['\textregistered'],
|
||||
170 => ['\textordfeminine'],
|
||||
172 => ['$\neg$'],
|
||||
176 => ['$\degree$', 'mathabx'],
|
||||
177 => ['$\pm$'],
|
||||
180 => ['\''],
|
||||
181 => ['$\mu$'],
|
||||
182 => ['\P'],
|
||||
183 => ['$\cdot$'],
|
||||
186 => ['\textordmasculine'],
|
||||
162 => ['\cent', 'wasysym'],
|
||||
185 => ['$^1$'],
|
||||
178 => ['$^2$'],
|
||||
179 => ['$^3$'],
|
||||
189 => ['$\frac{1}{2}$'],
|
||||
188 => ['$\frac{1}{4}$'],
|
||||
190 => ['$\frac{3}{4}'],
|
||||
192 => ['\`A'],
|
||||
193 => ['\\\'A'],
|
||||
194 => ['\^A'],
|
||||
195 => ['\~A'],
|
||||
196 => ['\"A'],
|
||||
197 => ['\AA'],
|
||||
198 => ['\AE'],
|
||||
199 => ['\cC'],
|
||||
200 => ['\`E'],
|
||||
201 => ['\\\'E'],
|
||||
202 => ['\^E'],
|
||||
203 => ['\"E'],
|
||||
204 => ['\`I'],
|
||||
205 => ['\\\'I'],
|
||||
206 => ['\^I'],
|
||||
207 => ['\"I'],
|
||||
208 => ['$\eth$', 'amssymb'],
|
||||
209 => ['\~N'],
|
||||
210 => ['\`O'],
|
||||
211 => ['\\\'O'],
|
||||
212 => ['\^O'],
|
||||
213 => ['\~O'],
|
||||
214 => ['\"O'],
|
||||
215 => ['$\times$'],
|
||||
216 => ['\O'],
|
||||
217 => ['\`U'],
|
||||
218 => ['\\\'U'],
|
||||
219 => ['\^U'],
|
||||
220 => ['\"U'],
|
||||
221 => ['\\\'Y'],
|
||||
222 => ['\Thorn', 'wasysym'],
|
||||
223 => ['\ss'],
|
||||
224 => ['\`a'],
|
||||
225 => ['\\\'a'],
|
||||
226 => ['\^a'],
|
||||
227 => ['\~a'],
|
||||
228 => ['\"a'],
|
||||
229 => ['\aa'],
|
||||
230 => ['\ae'],
|
||||
231 => ['\cc'],
|
||||
232 => ['\`e'],
|
||||
233 => ['\\\'e'],
|
||||
234 => ['\^e'],
|
||||
235 => ['\"e'],
|
||||
236 => ['\`i'],
|
||||
237 => ['\\\'i'],
|
||||
238 => ['\^i'],
|
||||
239 => ['\"i'],
|
||||
240 => ['$\eth$'],
|
||||
241 => ['\~n'],
|
||||
242 => ['\`o'],
|
||||
243 => ['\\\'o'],
|
||||
244 => ['\^o'],
|
||||
245 => ['\~o'],
|
||||
246 => ['\"o'],
|
||||
247 => ['$\divide$'],
|
||||
248 => ['\o'],
|
||||
249 => ['\`u'],
|
||||
250 => ['\\\'u'],
|
||||
251 => ['\^u'],
|
||||
252 => ['\"u'],
|
||||
253 => ['\\\'y'],
|
||||
254 => ['\thorn', 'wasysym'],
|
||||
255 => ['\"y'],
|
||||
}
|
||||
ENTITY_CONV_TABLE.each {|k,v| ENTITY_CONV_TABLE[k] = v.unshift(v.shift + '{}')}
|
||||
|
||||
def convert_entity(el, opts)
|
||||
text, package = ENTITY_CONV_TABLE[el.value.code_point]
|
||||
if text
|
||||
@doc.conversion_infos[:packages] << package if package
|
||||
text
|
||||
else
|
||||
@doc.warnings << "Couldn't find entity in substitution table!"
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
TYPOGRAPHIC_SYMS = {
|
||||
:mdash => '---', :ndash => '--', :hellip => '\ldots{}',
|
||||
:laquo_space => '\guillemotleft{}~', :raquo_space => '~\guillemotright{}',
|
||||
:laquo => '\guillemotleft{}', :raquo => '\guillemotright{}'
|
||||
}
|
||||
def convert_typographic_sym(el, opts)
|
||||
TYPOGRAPHIC_SYMS[el.value]
|
||||
end
|
||||
|
||||
SMART_QUOTE_SYMS = {:lsquo => '`', :rsquo => '\'', :ldquo => '``', :rdquo => '\'\''}
|
||||
def convert_smart_quote(el, opts)
|
||||
SMART_QUOTE_SYMS[el.value]
|
||||
end
|
||||
|
||||
def convert_math(el, opts)
|
||||
@doc.conversion_infos[:packages] += %w[amssymb amsmath amsthm amsfonts]
|
||||
if el.options[:category] == :block
|
||||
if el.value =~ /\A\s*\\begin\{/
|
||||
el.value
|
||||
else
|
||||
latex_environment('displaymath', el, el.value)
|
||||
end
|
||||
else
|
||||
"$#{el.value}$"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_abbreviation(el, opts)
|
||||
el.value
|
||||
end
|
||||
|
||||
ESCAPE_MAP = {
|
||||
"^" => "\\^{}",
|
||||
"\\" => "\\textbackslash{}",
|
||||
"~" => "\\ensuremath{\\sim}",
|
||||
"|" => "\\textbar{}",
|
||||
"<" => "\\textless{}",
|
||||
">" => "\\textgreater{}"
|
||||
}.merge(Hash[*("{}$%&_#".scan(/./).map {|c| [c, "\\#{c}"]}.flatten)])
|
||||
ESCAPE_RE = Regexp.union(*ESCAPE_MAP.collect {|k,v| k})
|
||||
|
||||
def escape(str)
|
||||
str.gsub(ESCAPE_RE) {|m| ESCAPE_MAP[m]}
|
||||
end
|
||||
|
||||
def attribute_list(el)
|
||||
attrs = (el.options[:attr] || {}).map {|k,v| v.nil? ? '' : " #{k}=\"#{v.to_s}\""}.compact.sort.join('')
|
||||
attrs = " % #{attrs}" if !attrs.empty?
|
||||
attrs
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
166
vim/plugin/vim-markdown-preview/kramdown/document.rb
Executable file
166
vim/plugin/vim-markdown-preview/kramdown/document.rb
Executable file
@@ -0,0 +1,166 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/compatibility'
|
||||
|
||||
require 'kramdown/version'
|
||||
require 'kramdown/error'
|
||||
require 'kramdown/parser'
|
||||
require 'kramdown/converter'
|
||||
require 'kramdown/options'
|
||||
require 'kramdown/utils'
|
||||
|
||||
module Kramdown
|
||||
|
||||
# Return the data directory for kramdown.
|
||||
def self.data_dir
|
||||
unless defined?(@@data_dir)
|
||||
require 'rbconfig'
|
||||
@@data_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'kramdown'))
|
||||
@@data_dir = File.expand_path(File.join(Config::CONFIG["datadir"], "kramdown")) if !File.exists?(@@data_dir)
|
||||
raise "kramdown data directory not found! This is a bug, please report it!" unless File.directory?(@@data_dir)
|
||||
end
|
||||
@@data_dir
|
||||
end
|
||||
|
||||
|
||||
# The main interface to kramdown.
|
||||
#
|
||||
# This class provides a one-stop-shop for using kramdown to convert text into various output
|
||||
# formats. Use it like this:
|
||||
#
|
||||
# require 'kramdown'
|
||||
# doc = Kramdown::Document.new('This *is* some kramdown text')
|
||||
# puts doc.to_html
|
||||
#
|
||||
# The #to_html method is a shortcut for using the Converter::Html class.
|
||||
#
|
||||
# The second argument to the #new method is an options hash for customizing the behaviour of the
|
||||
# used parser and the converter. See Document#new for more information!
|
||||
class Document
|
||||
|
||||
# The element tree of the document. It is immediately available after the #new method has been
|
||||
# called.
|
||||
attr_accessor :tree
|
||||
|
||||
# The options hash which holds the options for parsing/converting the Kramdown document. It is
|
||||
# possible that these values get changed during the parsing phase.
|
||||
attr_reader :options
|
||||
|
||||
# An array of warning messages. It is filled with warnings during the parsing phase (i.e. in
|
||||
# #new) and the conversion phase.
|
||||
attr_reader :warnings
|
||||
|
||||
# Holds needed parse information which is dependent on the used parser, like ALDs, link
|
||||
# definitions and so on. This information may be used by converters afterwards.
|
||||
attr_reader :parse_infos
|
||||
|
||||
# Holds conversion information which is dependent on the used converter. A converter clears this
|
||||
# variable before doing the conversion.
|
||||
attr_reader :conversion_infos
|
||||
|
||||
|
||||
# Create a new Kramdown document from the string +source+ and use the provided +options+. The
|
||||
# options that can be used are defined in the Options module.
|
||||
#
|
||||
# The special options key <tt>:input</tt> can be used to select the parser that should parse the
|
||||
# +source+. It has to be the name of a class in the Kramdown::Parser module. For example, to
|
||||
# select the kramdown parser, one would set the <tt>:input</tt> key to +Kramdown+. If this key
|
||||
# is not set, it defaults to +Kramdown+.
|
||||
#
|
||||
# The +source+ is immediately parsed by the selected parser so that the document tree is
|
||||
# immediately available and the output can be generated.
|
||||
def initialize(source, options = {})
|
||||
@options = Options.merge(options)
|
||||
@warnings = []
|
||||
@parse_infos = {}
|
||||
@parse_infos[:encoding] = source.encoding if RUBY_VERSION >= '1.9'
|
||||
@conversion_infos = {}
|
||||
parser = (options[:input] || 'kramdown').to_s
|
||||
parser = parser[0..0].upcase + parser[1..-1]
|
||||
if Parser.const_defined?(parser)
|
||||
@tree = Parser.const_get(parser).parse(source, self)
|
||||
else
|
||||
raise Kramdown::Error.new("kramdown has no parser to handle the specified input format: #{options[:input]}")
|
||||
end
|
||||
end
|
||||
|
||||
# Check if a method is invoked that begins with +to_+ and if so, try to instantiate a converter
|
||||
# class (i.e. a class in the Kramdown::Converter module) and use it for converting the document.
|
||||
#
|
||||
# For example, +to_html+ would instantiate the Kramdown::Converter::Html class.
|
||||
def method_missing(id, *attr, &block)
|
||||
if id.to_s =~ /^to_(\w+)$/
|
||||
Converter.const_get($1[0..0].upcase + $1[1..-1]).convert(self)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def inspect #:nodoc:
|
||||
"<KD:Document: options=#{@options.inspect} tree=#{@tree.inspect} warnings=#{@warnings.inspect}>"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Represents all elements in the parse tree.
|
||||
#
|
||||
# kramdown only uses this one class for representing all available elements in a parse tree
|
||||
# (paragraphs, headers, emphasis, ...). The type of element can be set via the #type accessor.
|
||||
class Element
|
||||
|
||||
# A symbol representing the element type. For example, <tt>:p</tt> or <tt>:blockquote</tt>.
|
||||
attr_accessor :type
|
||||
|
||||
# The value of the element. The interpretation of this field depends on the type of the element.
|
||||
# Many elements don't use this field.
|
||||
attr_accessor :value
|
||||
|
||||
# The options hash for the element. It is used for storing arbitray options as well as the
|
||||
# following special contents:
|
||||
#
|
||||
# - *Attributes* of the element under the <tt>:attr</tt> key
|
||||
# - Category of the element, either <tt>:block</tt> or <tt>:span</tt>, under the
|
||||
# <tt>:category</tt> key. If this key is absent, it can be assumed that the element is in the
|
||||
# <tt>:span</tt> category.
|
||||
attr_accessor :options
|
||||
|
||||
# The child elements of this element.
|
||||
attr_accessor :children
|
||||
|
||||
|
||||
# Create a new Element object of type +type+. The optional parameters +value+ and +options+ can
|
||||
# also be set in this constructor for convenience.
|
||||
def initialize(type, value = nil, options = {})
|
||||
@type, @value, @options = type, value, options
|
||||
@children = []
|
||||
end
|
||||
|
||||
def inspect #:nodoc:
|
||||
"<kd:#{@type}#{@value.nil? ? '' : ' ' + @value.inspect}#{options.empty? ? '' : ' ' + @options.inspect}#{@children.empty? ? '' : ' ' + @children.inspect}>"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
27
vim/plugin/vim-markdown-preview/kramdown/error.rb
Executable file
27
vim/plugin/vim-markdown-preview/kramdown/error.rb
Executable file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
class Error < RuntimeError; end
|
||||
|
||||
end
|
||||
23
vim/plugin/vim-markdown-preview/kramdown/kramdown.rb
Executable file
23
vim/plugin/vim-markdown-preview/kramdown/kramdown.rb
Executable file
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/document'
|
||||
283
vim/plugin/vim-markdown-preview/kramdown/options.rb
Executable file
283
vim/plugin/vim-markdown-preview/kramdown/options.rb
Executable file
@@ -0,0 +1,283 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
# This module defines all options that are used by parsers and/or converters as well as providing
|
||||
# methods to deal with the options.
|
||||
module Options
|
||||
|
||||
# Helper class introducing a boolean type for specifying boolean values (+true+ and +false+) as
|
||||
# option types.
|
||||
class Boolean
|
||||
|
||||
# Return +true+ if +other+ is either +true+ or +false+
|
||||
def self.===(other)
|
||||
FalseClass === other || TrueClass === other
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# ----------------------------
|
||||
# :section: Option definitions
|
||||
#
|
||||
# This sections informs describes the methods that can be used on the Options module.
|
||||
# ----------------------------
|
||||
|
||||
# Contains the definition of an option.
|
||||
Definition = Struct.new(:name, :type, :default, :desc)
|
||||
|
||||
# Allowed option types.
|
||||
ALLOWED_TYPES = [String, Integer, Float, Symbol, Boolean, Array, Object]
|
||||
|
||||
@options = {}
|
||||
|
||||
# Define a new option called +name+ (a Symbol) with the given +type+ (String, Integer, Float,
|
||||
# Symbol, Boolean, Array, Object), default value +default+ and the description +desc+.
|
||||
#
|
||||
# The type 'Object' should only be used if none of the other types suffices because such an
|
||||
# option will be opaque and cannot be used, for example, by CLI command!
|
||||
def self.define(name, type, default, desc)
|
||||
raise ArgumentError, "Option name #{name} is already used" if @options.has_key?(name)
|
||||
raise ArgumentError, "Invalid option type #{type} specified" if !ALLOWED_TYPES.include?(type)
|
||||
raise ArgumentError, "Invalid type for default value" if !(type === default) && !default.nil?
|
||||
@options[name] = Definition.new(name, type, default, desc)
|
||||
end
|
||||
|
||||
# Return all option definitions.
|
||||
def self.definitions
|
||||
@options
|
||||
end
|
||||
|
||||
# Return +true+ if an option called +name+ is defined.
|
||||
def self.defined?(name)
|
||||
@options.has_key?(name)
|
||||
end
|
||||
|
||||
# Return a Hash with the default values for all options.
|
||||
def self.defaults
|
||||
temp = {}
|
||||
@options.each {|n, o| temp[o.name] = o.default}
|
||||
temp
|
||||
end
|
||||
|
||||
# Merge the #defaults Hash with the *parsed* options from the given Hash, i.e. only valid option
|
||||
# names are considered and their value is run through the #parse method.
|
||||
def self.merge(hash)
|
||||
temp = defaults
|
||||
hash.each do |k,v|
|
||||
next unless @options.has_key?(k)
|
||||
temp[k] = parse(k, v)
|
||||
end
|
||||
temp
|
||||
end
|
||||
|
||||
# Parse the given value +data+ as if it was a value for the option +name+ and return the parsed
|
||||
# value with the correct type.
|
||||
#
|
||||
# If +data+ already has the correct type, it is just returned. Otherwise it is converted to a
|
||||
# String and then to the correct type.
|
||||
def self.parse(name, data)
|
||||
raise ArgumentError, "No option named #{name} defined" if !@options.has_key?(name)
|
||||
return data if @options[name].type === data
|
||||
data = data.to_s
|
||||
if @options[name].type == String
|
||||
data
|
||||
elsif @options[name].type == Integer
|
||||
Integer(data)
|
||||
elsif @options[name].type == Float
|
||||
Float(data)
|
||||
elsif @options[name].type == Symbol
|
||||
(data.strip.empty? ? nil : data.to_sym)
|
||||
elsif @options[name].type == Boolean
|
||||
data.downcase.strip != 'false' && !data.empty?
|
||||
elsif @options[name].type == Array
|
||||
data.split(/\s+/)
|
||||
end
|
||||
end
|
||||
|
||||
# ----------------------------
|
||||
# :section: Option Definitions
|
||||
#
|
||||
# This sections contains all option definitions that are used by the included
|
||||
# parsers/converters.
|
||||
# ----------------------------
|
||||
|
||||
define(:template, String, '', <<EOF)
|
||||
The name of an ERB template file that should be used to wrap the output
|
||||
|
||||
This is used to wrap the output in an environment so that the output can
|
||||
be used as a stand-alone document. For example, an HTML template would
|
||||
provide the needed header and body tags so that the whole output is a
|
||||
valid HTML file. If no template is specified, the output will be just
|
||||
the converted text.
|
||||
|
||||
When resolving the template file, the given template name is used first.
|
||||
If such a file is not found, the converter extension is appended. If the
|
||||
file still cannot be found, the templates name is interpreted as a
|
||||
template name that is provided by kramdown (without the converter
|
||||
extension).
|
||||
|
||||
kramdown provides a default template named 'default' for each converter.
|
||||
|
||||
Default: ''
|
||||
Used by: all converters
|
||||
EOF
|
||||
|
||||
define(:auto_ids, Boolean, true, <<EOF)
|
||||
Use automatic header ID generation
|
||||
|
||||
If this option is `true`, ID values for all headers are automatically
|
||||
generated if no ID is explicitly specified.
|
||||
|
||||
Default: true
|
||||
Used by: HTML/Latex converter
|
||||
EOF
|
||||
|
||||
define(:auto_id_prefix, String, '', <<EOF)
|
||||
Prefix used for automatically generated heaer IDs
|
||||
|
||||
This option can be used to set a prefix for the automatically generated
|
||||
header IDs so that there is no conflict when rendering multiple kramdown
|
||||
documents into one output file separately. The prefix should only
|
||||
contain characters that are valid in an ID!
|
||||
|
||||
Default: ''
|
||||
Used by: HTML/Latex converter
|
||||
EOF
|
||||
|
||||
define(:parse_block_html, Boolean, false, <<EOF)
|
||||
Process kramdown syntax in block HTML tags
|
||||
|
||||
If this option is `true`, the kramdown parser processes the content of
|
||||
block HTML tags as text containing block level elements. Since this is
|
||||
not wanted normally, the default is `false`. It is normally better to
|
||||
selectively enable kramdown processing via the markdown attribute.
|
||||
|
||||
Default: false
|
||||
Used by: kramdown parser
|
||||
EOF
|
||||
|
||||
define(:parse_span_html, Boolean, true, <<EOF)
|
||||
Process kramdown syntax in span HTML tags
|
||||
|
||||
If this option is `true`, the kramdown parser processes the content of
|
||||
span HTML tags as text containing span level elements.
|
||||
|
||||
Default: true
|
||||
Used by: kramdown parser
|
||||
EOF
|
||||
|
||||
define(:html_to_native, Boolean, false, <<EOF)
|
||||
Convert HTML elements to native elements
|
||||
|
||||
If this option is `true`, the parser converts HTML elements to native
|
||||
elements. For example, when parsing `<em>hallo</em>` the emphasis tag
|
||||
would normally be converted to an `:html` element with tag type `:em`.
|
||||
If `html_to_native` is `true`, then the emphasis would be converted to a
|
||||
native `:em` element.
|
||||
|
||||
This is useful for converters that cannot deal with HTML elements.
|
||||
|
||||
Default: false
|
||||
Used by: kramdown parser
|
||||
EOF
|
||||
|
||||
define(:footnote_nr, Integer, 1, <<EOF)
|
||||
The number of the first footnote
|
||||
|
||||
This option can be used to specify the number that is used for the first
|
||||
footnote.
|
||||
|
||||
Default: 1
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:coderay_wrap, Symbol, :div, <<EOF)
|
||||
Defines how the highlighted code should be wrapped
|
||||
|
||||
The possible values are :span, :div or nil.
|
||||
|
||||
Default: :div
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:coderay_line_numbers, Symbol, :inline, <<EOF)
|
||||
Defines how and if line numbers should be shown
|
||||
|
||||
The possible values are :table, :inline, :list or nil. If this option is
|
||||
nil, no line numbers are shown.
|
||||
|
||||
Default: :inline
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:coderay_line_number_start, Integer, 1, <<EOF)
|
||||
The start value for the line numbers
|
||||
|
||||
Default: 1
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:coderay_tab_width, Integer, 8, <<EOF)
|
||||
The tab width used in highlighted code
|
||||
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:coderay_bold_every, Integer, 10, <<EOF)
|
||||
Defines how often a line number should be made bold
|
||||
|
||||
Default: 10
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:coderay_css, Symbol, :style, <<EOF)
|
||||
Defines how the highlighted code gets styled
|
||||
|
||||
Possible values are :class (CSS classes are applied to the code
|
||||
elements, one must supply the needed CSS file) or :style (default CSS
|
||||
styles are directly applied to the code elements).
|
||||
|
||||
Default: style
|
||||
Used by: HTML converter
|
||||
EOF
|
||||
|
||||
define(:numeric_entities, Boolean, false, <<EOF)
|
||||
Defines whether entities are output using names or numeric values
|
||||
|
||||
Default: false
|
||||
Used by: HTML converter, kramdown converter
|
||||
EOF
|
||||
|
||||
define(:toc_depth, Integer, 0, <<EOF)
|
||||
Defines the maximum level of headers which will be used to generate the table of
|
||||
contents. For instance, with a value of 2, toc entries will be generated for h1
|
||||
and h2 headers but not for h3, h4, etc. A value of 0 uses all header levels.
|
||||
|
||||
Default: 0
|
||||
Used by: HTML/Latex converter
|
||||
EOF
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
39
vim/plugin/vim-markdown-preview/kramdown/parser.rb
Executable file
39
vim/plugin/vim-markdown-preview/kramdown/parser.rb
Executable file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
# == Parser Module
|
||||
#
|
||||
# This module contains all available parsers. Currently, there two parsers:
|
||||
#
|
||||
# * Kramdown for parsing documents in kramdown format
|
||||
# * Html for parsing HTML documents
|
||||
module Parser
|
||||
|
||||
autoload :Base, 'kramdown/parser/base'
|
||||
autoload :Kramdown, 'kramdown/parser/kramdown'
|
||||
autoload :Html, 'kramdown/parser/html'
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
94
vim/plugin/vim-markdown-preview/kramdown/parser/base.rb
Executable file
94
vim/plugin/vim-markdown-preview/kramdown/parser/base.rb
Executable file
@@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Parser
|
||||
|
||||
# == Base class for parsers
|
||||
#
|
||||
# This class serves as base class for parsers. It provides common methods that can/should be
|
||||
# used by all parsers, especially by those using StringScanner for parsing.
|
||||
#
|
||||
class Base
|
||||
|
||||
# Initialize the parser with the given Kramdown document +doc+.
|
||||
def initialize(doc)
|
||||
@doc = doc
|
||||
@text_type = :text
|
||||
end
|
||||
private_class_method(:new, :allocate)
|
||||
|
||||
# Parse the +source+ string into an element tree, using the information provided by the
|
||||
# Kramdown document +doc+.
|
||||
#
|
||||
# Initializes a new instance of the calling class and then calls the #parse method that must
|
||||
# be implemented by each subclass.
|
||||
def self.parse(source, doc)
|
||||
new(doc).parse(source)
|
||||
end
|
||||
|
||||
|
||||
# Add the given warning +text+ to the warning array of the Kramdown document.
|
||||
def warning(text)
|
||||
@doc.warnings << text
|
||||
#TODO: add position information
|
||||
end
|
||||
|
||||
# Modify the string +source+ to be usable by the parser.
|
||||
def adapt_source(source)
|
||||
source.gsub(/\r\n?/, "\n").chomp + "\n"
|
||||
end
|
||||
|
||||
# This helper method adds the given +text+ either to the last element in the +tree+ if it is a
|
||||
# +type+ element or creates a new text element with the given +type+.
|
||||
def add_text(text, tree = @tree, type = @text_type)
|
||||
if tree.children.last && tree.children.last.type == type
|
||||
tree.children.last.value << text
|
||||
elsif !text.empty?
|
||||
tree.children << Element.new(type, text)
|
||||
end
|
||||
end
|
||||
|
||||
# Extract the part of the StringScanner +srcscan+ backed string specified by the +range+. This
|
||||
# method also works correctly under Ruby 1.9.
|
||||
def extract_string(range, strscan)
|
||||
result = nil
|
||||
if RUBY_VERSION >= '1.9'
|
||||
begin
|
||||
enc = strscan.string.encoding
|
||||
strscan.string.force_encoding('ASCII-8BIT')
|
||||
result = strscan.string[range].force_encoding(enc)
|
||||
ensure
|
||||
strscan.string.force_encoding(enc)
|
||||
end
|
||||
else
|
||||
result = strscan.string[range]
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
482
vim/plugin/vim-markdown-preview/kramdown/parser/html.rb
Executable file
482
vim/plugin/vim-markdown-preview/kramdown/parser/html.rb
Executable file
@@ -0,0 +1,482 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'rexml/parsers/baseparser'
|
||||
require 'strscan'
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Parser
|
||||
|
||||
# Used for parsing a HTML document.
|
||||
class Html < Base
|
||||
|
||||
# Contains all constants that are used when parsing.
|
||||
module Constants
|
||||
#:stopdoc:
|
||||
# The following regexps are based on the ones used by REXML, with some slight modifications.
|
||||
HTML_DOCTYPE_RE = /<!DOCTYPE.*?>/m
|
||||
HTML_COMMENT_RE = /<!--(.*?)-->/m
|
||||
HTML_INSTRUCTION_RE = /<\?(.*?)\?>/m
|
||||
HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})\s*=\s*(["'])(.*?)\2/m
|
||||
HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}\s*=\s*(["']).*?\3)*)\s*(\/)?>/m
|
||||
HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::NAME_STR})\s*>/m
|
||||
HTML_ENTITY_RE = /&([\w:][\-\w\d\.:]*);|&#(\d+);|&\#x([0-9a-fA-F]+);/
|
||||
|
||||
|
||||
HTML_PARSE_AS_BLOCK = %w{applet button blockquote colgroup dd div dl fieldset form iframe li
|
||||
map noscript object ol table tbody thead tfoot tr td ul}
|
||||
HTML_PARSE_AS_SPAN = %w{a abbr acronym address b bdo big cite caption del dfn dt em
|
||||
h1 h2 h3 h4 h5 h6 i ins kbd label legend optgroup p q rb rbc
|
||||
rp rt rtc ruby samp select small span strong sub sup th tt var}
|
||||
HTML_PARSE_AS_RAW = %w{script math option textarea pre code}
|
||||
|
||||
HTML_PARSE_AS = Hash.new {|h,k| h[k] = :raw}
|
||||
HTML_PARSE_AS_BLOCK.each {|i| HTML_PARSE_AS[i] = :block}
|
||||
HTML_PARSE_AS_SPAN.each {|i| HTML_PARSE_AS[i] = :span}
|
||||
HTML_PARSE_AS_RAW.each {|i| HTML_PARSE_AS[i] = :raw}
|
||||
|
||||
# Some HTML elements like script belong to both categories (i.e. are valid in block and
|
||||
# span HTML) and don't appear therefore!
|
||||
HTML_SPAN_ELEMENTS = %w{a abbr acronym b big bdo br button cite code del dfn em i img input
|
||||
ins kbd label option q rb rbc rp rt rtc ruby samp select small span
|
||||
strong sub sup textarea tt var}
|
||||
HTML_BLOCK_ELEMENTS = %w{address article aside applet body button blockquote caption col colgroup dd div dl dt fieldset
|
||||
figcaption footer form h1 h2 h3 h4 h5 h6 header hgroup hr html head iframe legend listing menu
|
||||
li map nav ol optgroup p pre section summary table tbody td th thead tfoot tr ul}
|
||||
HTML_ELEMENTS_WITHOUT_BODY = %w{area base br col command embed hr img input keygen link meta param source track wbr}
|
||||
end
|
||||
|
||||
|
||||
# Contains the parsing methods. This module can be mixed into any parser to get HTML parsing
|
||||
# functionality. The only thing that must be provided by the class are instance variable
|
||||
# <tt>@stack</tt> for storing needed state and <tt>@src</tt> (instance of StringScanner) for
|
||||
# the actual parsing.
|
||||
module Parser
|
||||
|
||||
include Constants
|
||||
|
||||
# Process the HTML start tag that has already be scanned/checked. Does the common processing
|
||||
# steps and then yields to the caller for further processing.
|
||||
def handle_html_start_tag
|
||||
name = @src[1]
|
||||
closed = !@src[4].nil?
|
||||
attrs = {}
|
||||
@src[2].scan(HTML_ATTRIBUTE_RE).each {|attr,sep,val| attrs[attr] = val}
|
||||
|
||||
el = Element.new(:html_element, name, :attr => attrs, :category => :block)
|
||||
@tree.children << el
|
||||
|
||||
if !closed && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value)
|
||||
warning("The HTML tag '#{el.value}' cannot have any content - auto-closing it")
|
||||
closed = true
|
||||
end
|
||||
if name == 'script'
|
||||
handle_html_script_tag
|
||||
yield(el, true)
|
||||
else
|
||||
yield(el, closed)
|
||||
end
|
||||
end
|
||||
|
||||
def handle_html_script_tag
|
||||
curpos = @src.pos
|
||||
if result = @src.scan_until(/(?=<\/script\s*>)/m)
|
||||
add_text(extract_string(curpos...@src.pos, @src), @tree.children.last, :raw)
|
||||
@src.scan(HTML_TAG_CLOSE_RE)
|
||||
else
|
||||
add_text(@src.scan(/.*/m), @tree.children.last, :raw)
|
||||
warning("Found no end tag for 'script' - auto-closing it")
|
||||
end
|
||||
end
|
||||
|
||||
HTML_RAW_START = /(?=<(#{REXML::Parsers::BaseParser::UNAME_STR}|\/|!--|\?))/
|
||||
|
||||
# Parse raw HTML from the current source position, storing the found elements in +el+.
|
||||
# Parsing continues until one of the following criteria are fulfilled:
|
||||
#
|
||||
# - The end of the document is reached.
|
||||
# - The matching end tag for the element +el+ is found (only used if +el+ is an HTML
|
||||
# element).
|
||||
#
|
||||
# When an HTML start tag is found, processing is deferred to #handle_html_start_tag,
|
||||
# providing the block given to this method.
|
||||
def parse_raw_html(el, &block)
|
||||
@stack.push(@tree)
|
||||
@tree = el
|
||||
|
||||
done = false
|
||||
while !@src.eos? && !done
|
||||
if result = @src.scan_until(HTML_RAW_START)
|
||||
add_text(result, @tree, :text)
|
||||
if result = @src.scan(HTML_COMMENT_RE)
|
||||
@tree.children << Element.new(:xml_comment, result, :category => :block, :parent_is_raw => true)
|
||||
elsif result = @src.scan(HTML_INSTRUCTION_RE)
|
||||
@tree.children << Element.new(:xml_pi, result, :category => :block, :parent_is_raw => true)
|
||||
elsif @src.scan(HTML_TAG_RE)
|
||||
handle_html_start_tag(&block)
|
||||
elsif @src.scan(HTML_TAG_CLOSE_RE)
|
||||
if @tree.value == @src[1]
|
||||
done = true
|
||||
else
|
||||
warning("Found invalidly used HTML closing tag for '#{@src[1]}' - ignoring it")
|
||||
end
|
||||
else
|
||||
add_text(@src.scan(/./), @tree, :text)
|
||||
end
|
||||
else
|
||||
result = @src.scan(/.*/m)
|
||||
add_text(result, @tree, :text)
|
||||
warning("Found no end tag for '#{@tree.value}' - auto-closing it") if @tree.type == :html_element
|
||||
done = true
|
||||
end
|
||||
end
|
||||
|
||||
@tree = @stack.pop
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Converts HTML elements to native elements if possible.
|
||||
class ElementConverter
|
||||
|
||||
include Constants
|
||||
include ::Kramdown::Utils::Entities
|
||||
|
||||
REMOVE_TEXT_CHILDREN = %w{html head hgroup ol ul dl table colgroup tbody thead tfoot tr select optgroup}
|
||||
WRAP_TEXT_CHILDREN = %w{body section nav article aside header footer address div li dd blockquote figure
|
||||
figcaption fieldset form}
|
||||
REMOVE_WHITESPACE_CHILDREN = %w{body section nav article aside header footer address
|
||||
div li dd blockquote figure figcaption td th fieldset form}
|
||||
STRIP_WHITESPACE = %w{address article aside blockquote body caption dd div dl dt fieldset figcaption form footer
|
||||
header h1 h2 h3 h4 h5 h6 legend li nav p section td th}
|
||||
SIMPLE_ELEMENTS = %w{em strong blockquote hr br a img p thead tbody tfoot tr td th ul ol dl li dl dt dd}
|
||||
|
||||
def initialize(doc)
|
||||
@doc = doc
|
||||
end
|
||||
|
||||
# Convert the element +el+ and its children.
|
||||
def process(el, do_conversion = true, preserve_text = false, parent = nil)
|
||||
case el.type
|
||||
when :xml_comment, :xml_pi, :html_doctype
|
||||
ptype = if parent.nil?
|
||||
'div'
|
||||
else
|
||||
case parent.type
|
||||
when :html_element then parent.value
|
||||
when :code_span then 'code'
|
||||
when :code_block then 'pre'
|
||||
when :header then 'h1'
|
||||
else parent.type.to_s
|
||||
end
|
||||
end
|
||||
el.options = {:category => HTML_PARSE_AS_SPAN.include?(ptype) ? :span : :block}
|
||||
return
|
||||
when :html_element
|
||||
else return
|
||||
end
|
||||
|
||||
type = el.value
|
||||
remove_text_children(el) if REMOVE_TEXT_CHILDREN.include?(type)
|
||||
|
||||
mname = "convert_#{el.value}"
|
||||
if do_conversion && self.class.method_defined?(mname)
|
||||
send(mname, el)
|
||||
elsif do_conversion && SIMPLE_ELEMENTS.include?(type)
|
||||
set_basics(el, type.intern, HTML_SPAN_ELEMENTS.include?(type) ? :span : :block)
|
||||
process_children(el, do_conversion, preserve_text)
|
||||
else
|
||||
process_html_element(el, do_conversion, preserve_text)
|
||||
end
|
||||
|
||||
strip_whitespace(el) if STRIP_WHITESPACE.include?(type)
|
||||
remove_whitespace_children(el) if REMOVE_WHITESPACE_CHILDREN.include?(type)
|
||||
wrap_text_children(el) if WRAP_TEXT_CHILDREN.include?(type)
|
||||
end
|
||||
|
||||
def process_children(el, do_conversion = true, preserve_text = false)
|
||||
el.children.map! do |c|
|
||||
if c.type == :text
|
||||
process_text(c.value, preserve_text)
|
||||
else
|
||||
process(c, do_conversion, preserve_text, el)
|
||||
c
|
||||
end
|
||||
end.flatten!
|
||||
end
|
||||
|
||||
# Process the HTML text +raw+: compress whitespace (if +preserve+ is +false+) and convert
|
||||
# entities in entity elements.
|
||||
def process_text(raw, preserve = false)
|
||||
raw.gsub!(/\s+/, ' ') unless preserve
|
||||
src = StringScanner.new(raw)
|
||||
result = []
|
||||
while !src.eos?
|
||||
if tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/)
|
||||
result << Element.new(:text, tmp)
|
||||
src.scan(HTML_ENTITY_RE)
|
||||
val = src[1] || (src[2] && src[2].to_i) || src[3].hex
|
||||
result << if %w{lsquo rsquo ldquo rdquo}.include?(val)
|
||||
Element.new(:smart_quote, val.intern)
|
||||
elsif %w{mdash ndash hellip laquo raquo}.include?(val)
|
||||
Element.new(:typographic_sym, val.intern)
|
||||
else
|
||||
Element.new(:entity, entity(val))
|
||||
end
|
||||
else
|
||||
result << Element.new(:text, src.scan(/.*/m))
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def process_html_element(el, do_conversion = true, preserve_text = false)
|
||||
el.options = {:category => HTML_SPAN_ELEMENTS.include?(el.value) ? :span : :block,
|
||||
:parse_type => HTML_PARSE_AS[el.value],
|
||||
:attr => el.options[:attr]
|
||||
}
|
||||
process_children(el, do_conversion, preserve_text)
|
||||
end
|
||||
|
||||
def remove_text_children(el)
|
||||
el.children.delete_if {|c| c.type == :text}
|
||||
end
|
||||
|
||||
SPAN_ELEMENTS = [:em, :strong, :br, :a, :img, :codespan, :entity, :smart_quote, :typographic_sym, :math]
|
||||
|
||||
def wrap_text_children(el)
|
||||
tmp = []
|
||||
last_is_p = false
|
||||
el.children.each do |c|
|
||||
if c.options[:category] != :block || c.type == :text
|
||||
if !last_is_p
|
||||
tmp << Element.new(:p, nil, :transparent => true)
|
||||
last_is_p = true
|
||||
end
|
||||
tmp.last.children << c
|
||||
tmp
|
||||
else
|
||||
tmp << c
|
||||
last_is_p = false
|
||||
end
|
||||
end
|
||||
el.children = tmp
|
||||
end
|
||||
|
||||
def strip_whitespace(el)
|
||||
return if el.children.empty?
|
||||
if el.children.first.type == :text
|
||||
el.children.first.value.lstrip!
|
||||
end
|
||||
if el.children.last.type == :text
|
||||
el.children.last.value.rstrip!
|
||||
end
|
||||
end
|
||||
|
||||
def remove_whitespace_children(el)
|
||||
i = -1
|
||||
el.children.delete_if do |c|
|
||||
i += 1
|
||||
c.type == :text && c.value.strip.empty? &&
|
||||
(i == 0 || i == el.children.length - 1 || (el.children[i-1].options[:category] == :block &&
|
||||
el.children[i+1].options[:category] == :block))
|
||||
end
|
||||
end
|
||||
|
||||
def set_basics(el, type, category, opts = {})
|
||||
el.type = type
|
||||
el.options = {:category => category, :attr => el.options[:attr]}.merge(opts)
|
||||
el.value = nil
|
||||
end
|
||||
|
||||
def extract_text(el, raw)
|
||||
raw << el.value.to_s if el.type == :text
|
||||
el.children.each {|c| extract_text(c, raw)}
|
||||
end
|
||||
|
||||
def convert_h1(el)
|
||||
set_basics(el, :header, :block, :level => el.value[1..1].to_i)
|
||||
extract_text(el, el.options[:raw_text] = '')
|
||||
process_children(el)
|
||||
end
|
||||
%w{h2 h3 h4 h5 h6}.each do |i|
|
||||
alias_method("convert_#{i}".to_sym, :convert_h1)
|
||||
end
|
||||
|
||||
def convert_code(el)
|
||||
raw = ''
|
||||
extract_text(el, raw)
|
||||
result = process_text(raw, true)
|
||||
begin
|
||||
str = result.inject('') do |mem, c|
|
||||
if c.type == :text
|
||||
mem << c.value
|
||||
elsif c.type == :entity
|
||||
if RUBY_VERSION >= '1.9'
|
||||
mem << c.value.char.encode(@doc.parse_infos[:encoding])
|
||||
elsif [60, 62, 34, 38].include?(c.value.code_point)
|
||||
mem << c.value.code_point.chr
|
||||
end
|
||||
elsif c.type == :smart_quote || c.type == :typographic_sym
|
||||
mem << entity(c.value.to_s).char.encode(@doc.parse_infos[:encoding])
|
||||
else
|
||||
raise "Bug - please report"
|
||||
end
|
||||
end
|
||||
result.clear
|
||||
result << Element.new(:text, str)
|
||||
rescue
|
||||
end
|
||||
if result.length > 1 || result.first.type != :text
|
||||
process_html_element(el, false, true)
|
||||
else
|
||||
if el.value == 'code'
|
||||
set_basics(el, :codespan, :span)
|
||||
else
|
||||
set_basics(el, :codeblock, :block)
|
||||
end
|
||||
el.value = result.first.value
|
||||
end
|
||||
end
|
||||
alias :convert_pre :convert_code
|
||||
|
||||
def convert_table(el)
|
||||
if !is_simple_table?(el)
|
||||
process_html_element(el, false)
|
||||
return
|
||||
end
|
||||
process_children(el)
|
||||
set_basics(el, :table, :block)
|
||||
el.options[:alignment] = []
|
||||
calc_alignment = lambda do |c|
|
||||
if c.type == :tr && el.options[:alignment].empty?
|
||||
el.options[:alignment] = [:default] * c.children.length
|
||||
break
|
||||
else
|
||||
c.children.each {|cc| calc_alignment.call(cc)}
|
||||
end
|
||||
end
|
||||
calc_alignment.call(el)
|
||||
if el.children.first.type == :tr
|
||||
tbody = Element.new(:tbody, nil, :category => :block)
|
||||
tbody.children = el.children
|
||||
el.children = [tbody]
|
||||
end
|
||||
end
|
||||
|
||||
def is_simple_table?(el)
|
||||
only_phrasing_content = lambda do |c|
|
||||
c.children.all? do |cc|
|
||||
(cc.type == :text || !HTML_BLOCK_ELEMENTS.include?(cc.value)) && only_phrasing_content.call(cc)
|
||||
end
|
||||
end
|
||||
check_cells = Proc.new do |c|
|
||||
if c.value == 'th' || c.value == 'td'
|
||||
return false if !only_phrasing_content.call(c)
|
||||
else
|
||||
c.children.each {|cc| check_cells.call(cc)}
|
||||
end
|
||||
end
|
||||
check_cells.call(el)
|
||||
|
||||
check_rows = lambda do |t, type|
|
||||
t.children.all? {|r| (r.value == 'tr' || r.type == :text) && r.children.all? {|c| c.value == type || c.type == :text}}
|
||||
end
|
||||
check_rows.call(el, 'td') ||
|
||||
(el.children.all? do |t|
|
||||
t.type == :text || (t.value == 'thead' && check_rows.call(t, 'th')) ||
|
||||
((t.value == 'tfoot' || t.value == 'tbody') && check_rows.call(t, 'td'))
|
||||
end && el.children.any? {|t| t.value == 'tbody'})
|
||||
end
|
||||
|
||||
def convert_div(el)
|
||||
if !is_math_tag?(el)
|
||||
process_html_element(el)
|
||||
else
|
||||
handle_math_tag(el)
|
||||
end
|
||||
end
|
||||
alias :convert_span :convert_div
|
||||
|
||||
def is_math_tag?(el)
|
||||
el.options[:attr] && el.options[:attr]['class'].to_s =~ /\bmath\b/ &&
|
||||
el.children.size == 1 && el.children.first.type == :text
|
||||
end
|
||||
|
||||
def handle_math_tag(el)
|
||||
set_basics(el, :math, (el.value == 'div' ? :block : :span))
|
||||
el.value = el.children.shift.value
|
||||
if el.options[:attr]['class'] =~ /^\s*math\s*$/
|
||||
el.options[:attr].delete('class')
|
||||
else
|
||||
el.options[:attr]['class'].sub!(/\s?math/, '')
|
||||
end
|
||||
el.value.gsub!(/&(amp|quot|gt|lt);/) do |m|
|
||||
case m
|
||||
when '&' then '&'
|
||||
when '"' then '"'
|
||||
when '>' then '>'
|
||||
when '<' then '<'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include Parser
|
||||
|
||||
# Parse +source+ as HTML document and return the created +tree+.
|
||||
def parse(source)
|
||||
@stack = []
|
||||
@tree = Element.new(:root)
|
||||
@src = StringScanner.new(adapt_source(source))
|
||||
|
||||
while true
|
||||
if result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/)
|
||||
@tree.children << Element.new(:xml_pi, result.strip, :category => :block)
|
||||
elsif result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/)
|
||||
@tree.children << Element.new(:html_doctype, result.strip, :category => :block)
|
||||
elsif result = @src.scan(/\s*#{HTML_COMMENT_RE}/)
|
||||
@tree.children << Element.new(:xml_comment, result.strip, :category => :block)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
tag_handler = lambda do |c, closed|
|
||||
parse_raw_html(c, &tag_handler) if !closed
|
||||
end
|
||||
parse_raw_html(@tree, &tag_handler)
|
||||
|
||||
ec = ElementConverter.new(@doc)
|
||||
@tree.children.each {|c| ec.process(c)}
|
||||
ec.remove_whitespace_children(@tree)
|
||||
@tree
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
303
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown.rb
Executable file
303
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown.rb
Executable file
@@ -0,0 +1,303 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'strscan'
|
||||
require 'stringio'
|
||||
|
||||
#TODO: use [[:alpha:]] in all regexp to allow parsing of international values in 1.9.1
|
||||
#NOTE: use @src.pre_match only before other check/match?/... operations, otherwise the content is changed
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Parser
|
||||
|
||||
# Used for parsing a document in kramdown format.
|
||||
#
|
||||
# If you want to extend the functionality of the parser, you need to the following:
|
||||
#
|
||||
# * Create a new subclass
|
||||
# * add the needed parser methods
|
||||
# * modify the @block_parsers and @span_parsers variables and add the names of your parser
|
||||
# methods
|
||||
#
|
||||
# Here is a small example for an extended parser class that parses ERB style tags as raw text if
|
||||
# they are used as span level elements (an equivalent block level parser should probably also be
|
||||
# made to handle the block case):
|
||||
#
|
||||
# require 'kramdown/parser/kramdown'
|
||||
#
|
||||
# class Kramdown::Parser::ERBKramdown < Kramdown::Parser::Kramdown
|
||||
#
|
||||
# def initialize(doc)
|
||||
# super(doc)
|
||||
# @span_parsers.unshift(:erb_tags)
|
||||
# end
|
||||
#
|
||||
# ERB_TAGS_START = /<%.*?%>/
|
||||
#
|
||||
# def parse_erb_tags
|
||||
# @src.pos += @src.matched_size
|
||||
# @tree.children << Element.new(:raw, @src.matched)
|
||||
# end
|
||||
# define_parser(:erb_tags, ERB_TAGS_START, '<%')
|
||||
#
|
||||
# end
|
||||
#
|
||||
# The new parser can be used like this:
|
||||
#
|
||||
# require 'kramdown/document'
|
||||
# # require the file with the above parser class
|
||||
#
|
||||
# Kramdown::Document.new(input_text, :input => 'ERBKramdown').to_html
|
||||
#
|
||||
class Kramdown < Base
|
||||
|
||||
include ::Kramdown
|
||||
|
||||
attr_reader :tree
|
||||
attr_reader :doc
|
||||
attr_reader :options
|
||||
|
||||
# Create a new Kramdown parser object for the Kramdown::Document +doc+.
|
||||
def initialize(doc)
|
||||
super(doc)
|
||||
|
||||
@src = nil
|
||||
@tree = nil
|
||||
@stack = []
|
||||
@text_type = :raw_text
|
||||
@block_ial = nil
|
||||
|
||||
@doc.parse_infos[:ald] = {}
|
||||
@doc.parse_infos[:link_defs] = {}
|
||||
@doc.parse_infos[:abbrev_defs] = {}
|
||||
@doc.parse_infos[:footnotes] = {}
|
||||
|
||||
@block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :table, :atx_header,
|
||||
:setext_header, :horizontal_rule, :list, :definition_list, :link_definition, :block_html,
|
||||
:footnote_definition, :abbrev_definition, :ald, :block_math,
|
||||
:block_extension, :block_ial, :eob_marker, :paragraph]
|
||||
@span_parsers = [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link, :smart_quotes, :inline_math,
|
||||
:span_extension, :span_ial, :html_entity, :typographic_syms, :line_break, :escaped_chars]
|
||||
|
||||
end
|
||||
private_class_method(:new, :allocate)
|
||||
|
||||
|
||||
# The source string provided on initialization is parsed and the created +tree+ is returned.
|
||||
def parse(source)
|
||||
configure_parser
|
||||
tree = Element.new(:root)
|
||||
parse_blocks(tree, adapt_source(source))
|
||||
update_tree(tree)
|
||||
replace_abbreviations(tree)
|
||||
@doc.parse_infos[:footnotes].each do |name, data|
|
||||
update_tree(data[:content])
|
||||
end
|
||||
tree
|
||||
end
|
||||
|
||||
#######
|
||||
protected
|
||||
#######
|
||||
|
||||
# Adapt the object to allow parsing like specified in the options.
|
||||
def configure_parser
|
||||
@parsers = {}
|
||||
(@block_parsers + @span_parsers).each do |name|
|
||||
if self.class.has_parser?(name)
|
||||
@parsers[name] = self.class.parser(name)
|
||||
else
|
||||
raise Kramdown::Error, "Unknown parser: #{name}"
|
||||
end
|
||||
end
|
||||
@span_start, @span_start_re = span_parser_regexps
|
||||
end
|
||||
|
||||
# Create the needed span parser regexps.
|
||||
def span_parser_regexps(parsers = @span_parsers)
|
||||
span_start = /#{parsers.map {|name| @parsers[name].span_start}.join('|')}/
|
||||
[span_start, /(?=#{span_start})/]
|
||||
end
|
||||
|
||||
# Parse all block level elements in +text+ into the element +el+.
|
||||
def parse_blocks(el, text = nil)
|
||||
@stack.push([@tree, @src])
|
||||
@tree, @src = el, (text.nil? ? @src : StringScanner.new(text))
|
||||
|
||||
status = catch(:stop_block_parsing) do
|
||||
while !@src.eos?
|
||||
block_ial_set = @block_ial
|
||||
@block_parsers.any? do |name|
|
||||
if @src.check(@parsers[name].start_re)
|
||||
send(@parsers[name].method)
|
||||
else
|
||||
false
|
||||
end
|
||||
end || begin
|
||||
warning('Warning: this should not occur - no block parser handled the line')
|
||||
add_text(@src.scan(/.*\n/))
|
||||
end
|
||||
@block_ial = nil if block_ial_set
|
||||
end
|
||||
end
|
||||
|
||||
@tree, @src = *@stack.pop
|
||||
status
|
||||
end
|
||||
|
||||
# Update the tree by parsing all <tt>:raw_text</tt> elements with the span level parser
|
||||
# (resets +@tree+, +@src+ and the +@stack+) and by updating the attributes from the IALs.
|
||||
def update_tree(element)
|
||||
element.children.map! do |child|
|
||||
if child.type == :raw_text
|
||||
@stack, @tree, @text_type = [], nil, :text
|
||||
@src = StringScanner.new(child.value)
|
||||
parse_spans(child)
|
||||
child.children
|
||||
elsif child.type == :eob
|
||||
[]
|
||||
else
|
||||
update_tree(child)
|
||||
update_attr_with_ial(child.options[:attr] ||= {}, child.options[:ial]) if child.options[:ial]
|
||||
child
|
||||
end
|
||||
end.flatten!
|
||||
end
|
||||
|
||||
# Parse all span level elements in the source string.
|
||||
def parse_spans(el, stop_re = nil, parsers = nil, text_type = @text_type)
|
||||
@stack.push([@tree, @text_type]) unless @tree.nil?
|
||||
@tree, @text_type = el, text_type
|
||||
|
||||
span_start = @span_start
|
||||
span_start_re = @span_start_re
|
||||
span_start, span_start_re = span_parser_regexps(parsers) if parsers
|
||||
parsers = parsers || @span_parsers
|
||||
|
||||
used_re = (stop_re.nil? ? span_start_re : /(?=#{Regexp.union(stop_re, span_start)})/)
|
||||
stop_re_found = false
|
||||
while !@src.eos? && !stop_re_found
|
||||
if result = @src.scan_until(used_re)
|
||||
add_text(result)
|
||||
if stop_re && (stop_re_matched = @src.check(stop_re))
|
||||
stop_re_found = (block_given? ? yield : true)
|
||||
end
|
||||
processed = parsers.any? do |name|
|
||||
if @src.check(@parsers[name].start_re)
|
||||
send(@parsers[name].method)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end unless stop_re_found
|
||||
add_text(@src.scan(/./)) if !processed && !stop_re_found
|
||||
else
|
||||
add_text(@src.scan(/.*/m)) unless stop_re
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@tree, @text_type = @stack.pop
|
||||
|
||||
stop_re_found
|
||||
end
|
||||
|
||||
# Update the attributes with the information from the inline attribute list and all referenced ALDs.
|
||||
def update_attr_with_ial(attr, ial)
|
||||
ial[:refs].each do |ref|
|
||||
update_attr_with_ial(attr, ref) if ref = @doc.parse_infos[:ald][ref]
|
||||
end if ial[:refs]
|
||||
attr['class'] = ((attr['class'] || '') + " #{ial['class']}").lstrip if ial['class']
|
||||
ial.each {|k,v| attr[k] = v if k.kind_of?(String) && k != 'class' }
|
||||
end
|
||||
|
||||
# Create a new block level element, taking care of applying a preceding block IAL if it exists.
|
||||
def new_block_el(*args)
|
||||
el = Element.new(*args)
|
||||
el.options[:category] ||= :block
|
||||
el.options[:ial] = @block_ial if @block_ial && el.type != :blank && el.type != :eob
|
||||
el
|
||||
end
|
||||
|
||||
@@parsers = {}
|
||||
|
||||
# Holds all the needed data for one block/span level parser.
|
||||
Data = Struct.new(:name, :start_re, :span_start, :method)
|
||||
|
||||
# Add a parser method
|
||||
#
|
||||
# * with the given +name+,
|
||||
# * using +start_re+ as start regexp
|
||||
# * and, for span parsers, +span_start+ as a String that can be used in a regexp and
|
||||
# which identifies the starting character(s)
|
||||
#
|
||||
# to the registry. The method name is automatically derived from the +name+ or can explicitly
|
||||
# be set by using the +meth_name+ parameter.
|
||||
def self.define_parser(name, start_re, span_start = nil, meth_name = "parse_#{name}")
|
||||
raise "A parser with the name #{name} already exists!" if @@parsers.has_key?(name)
|
||||
@@parsers[name] = Data.new(name, start_re, span_start, meth_name)
|
||||
end
|
||||
|
||||
# Return the Data structure for the parser +name+.
|
||||
def self.parser(name = nil)
|
||||
@@parsers[name]
|
||||
end
|
||||
|
||||
# Return +true+ if there is a parser called +name+.
|
||||
def self.has_parser?(name)
|
||||
@@parsers.has_key?(name)
|
||||
end
|
||||
|
||||
INDENT = /^(?:\t| {4})/
|
||||
OPT_SPACE = / {0,3}/
|
||||
|
||||
require 'kramdown/parser/kramdown/blank_line'
|
||||
require 'kramdown/parser/kramdown/eob'
|
||||
require 'kramdown/parser/kramdown/paragraph'
|
||||
require 'kramdown/parser/kramdown/header'
|
||||
require 'kramdown/parser/kramdown/blockquote'
|
||||
require 'kramdown/parser/kramdown/table'
|
||||
require 'kramdown/parser/kramdown/codeblock'
|
||||
require 'kramdown/parser/kramdown/horizontal_rule'
|
||||
require 'kramdown/parser/kramdown/list'
|
||||
require 'kramdown/parser/kramdown/link'
|
||||
require 'kramdown/parser/kramdown/attribute_list'
|
||||
require 'kramdown/parser/kramdown/extension'
|
||||
require 'kramdown/parser/kramdown/footnote'
|
||||
require 'kramdown/parser/kramdown/html'
|
||||
require 'kramdown/parser/kramdown/escaped_chars'
|
||||
require 'kramdown/parser/kramdown/html_entity'
|
||||
require 'kramdown/parser/kramdown/line_break'
|
||||
require 'kramdown/parser/kramdown/typographic_symbol'
|
||||
require 'kramdown/parser/kramdown/autolink'
|
||||
require 'kramdown/parser/kramdown/codespan'
|
||||
require 'kramdown/parser/kramdown/emphasis'
|
||||
require 'kramdown/parser/kramdown/smart_quotes'
|
||||
require 'kramdown/parser/kramdown/math'
|
||||
require 'kramdown/parser/kramdown/abbreviation'
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
65
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/abbreviation.rb
Executable file
65
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/abbreviation.rb
Executable file
@@ -0,0 +1,65 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
ABBREV_DEFINITION_START = /^#{OPT_SPACE}\*\[(.+?)\]:(.*?)\n/
|
||||
|
||||
# Parse the link definition at the current location.
|
||||
def parse_abbrev_definition
|
||||
@src.pos += @src.matched_size
|
||||
abbrev_id, abbrev_text = @src[1], @src[2].strip
|
||||
warning("Duplicate abbreviation ID '#{abbrev_id}' - overwriting") if @doc.parse_infos[:abbrev_defs][abbrev_id]
|
||||
@doc.parse_infos[:abbrev_defs][abbrev_id] = abbrev_text
|
||||
true
|
||||
end
|
||||
define_parser(:abbrev_definition, ABBREV_DEFINITION_START)
|
||||
|
||||
# Replace the abbreviation text with elements.
|
||||
def replace_abbreviations(el, regexps = nil)
|
||||
return if @doc.parse_infos[:abbrev_defs].empty?
|
||||
if !regexps
|
||||
regexps = [Regexp.union(*@doc.parse_infos[:abbrev_defs].keys.map {|k| /#{Regexp.escape(k)}/})]
|
||||
regexps << /(?=(?:\W|^)#{regexps.first}(?!\w))/ # regexp should only match on word boundaries
|
||||
end
|
||||
el.children.map! do |child|
|
||||
if child.type == :text
|
||||
result = []
|
||||
strscan = StringScanner.new(child.value)
|
||||
while temp = strscan.scan_until(regexps.last)
|
||||
temp += strscan.scan(/\W|^/)
|
||||
abbr = strscan.scan(regexps.first)
|
||||
result += [Element.new(:text, temp), Element.new(:abbreviation, abbr)]
|
||||
end
|
||||
result + [Element.new(:text, extract_string(strscan.pos..-1, strscan))]
|
||||
else
|
||||
replace_abbreviations(child, regexps)
|
||||
child
|
||||
end
|
||||
end.flatten!
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
105
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/attribute_list.rb
Executable file
105
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/attribute_list.rb
Executable file
@@ -0,0 +1,105 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
# Parse the string +str+ and extract all attributes and add all found attributes to the hash
|
||||
# +opts+.
|
||||
def parse_attribute_list(str, opts)
|
||||
str.scan(ALD_TYPE_ANY).each do |key, sep, val, id_attr, class_attr, ref|
|
||||
if ref
|
||||
(opts[:refs] ||= []) << ref
|
||||
elsif class_attr
|
||||
opts['class'] = ((opts['class'] || '') + " #{class_attr}").lstrip
|
||||
elsif id_attr
|
||||
opts['id'] = id_attr
|
||||
else
|
||||
opts[key] = val.gsub(/\\(\}|#{sep})/, "\\1")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Update the +ial+ with the information from the inline attribute list +opts+.
|
||||
def update_ial_with_ial(ial, opts)
|
||||
(ial[:refs] ||= []) << opts[:refs]
|
||||
ial['class'] = ((ial['class'] || '') + " #{opts['class']}").lstrip if opts['class']
|
||||
opts.each {|k,v| ial[k] = v if k != :refs && k != 'class' }
|
||||
end
|
||||
|
||||
|
||||
ALD_ID_CHARS = /[\w\d-]/
|
||||
ALD_ANY_CHARS = /\\\}|[^\}]/
|
||||
ALD_ID_NAME = /(?:\w|\d)#{ALD_ID_CHARS}*/
|
||||
ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^\}\2])*?)\2/
|
||||
ALD_TYPE_CLASS_NAME = /\.(#{ALD_ID_NAME})/
|
||||
ALD_TYPE_ID_NAME = /#(#{ALD_ID_NAME})/
|
||||
ALD_TYPE_REF = /(#{ALD_ID_NAME})/
|
||||
ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}|#{ALD_TYPE_REF})(?=\s|\Z)/
|
||||
ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/
|
||||
|
||||
# Parse the attribute list definition at the current location.
|
||||
def parse_ald
|
||||
@src.pos += @src.matched_size
|
||||
parse_attribute_list(@src[2], @doc.parse_infos[:ald][@src[1]] ||= {})
|
||||
@tree.children << Element.new(:eob)
|
||||
true
|
||||
end
|
||||
define_parser(:ald, ALD_START)
|
||||
|
||||
|
||||
IAL_BLOCK_START = /^#{OPT_SPACE}\{:(?!:)(#{ALD_ANY_CHARS}+)\}\s*?\n/
|
||||
|
||||
# Parse the inline attribute list at the current location.
|
||||
def parse_block_ial
|
||||
@src.pos += @src.matched_size
|
||||
if @tree.children.last && @tree.children.last.type != :blank && @tree.children.last.type != :eob
|
||||
parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||= {})
|
||||
else
|
||||
parse_attribute_list(@src[1], @block_ial = {})
|
||||
end
|
||||
@tree.children << Element.new(:eob) unless @src.check(IAL_BLOCK_START)
|
||||
true
|
||||
end
|
||||
define_parser(:block_ial, IAL_BLOCK_START)
|
||||
|
||||
|
||||
IAL_SPAN_START = /\{:(#{ALD_ANY_CHARS}+)\}/
|
||||
|
||||
# Parse the inline attribute list at the current location.
|
||||
def parse_span_ial
|
||||
@src.pos += @src.matched_size
|
||||
if @tree.children.last && @tree.children.last.type != :text
|
||||
attr = {}
|
||||
parse_attribute_list(@src[1], attr)
|
||||
update_ial_with_ial(@tree.children.last.options[:ial] ||= {}, attr)
|
||||
update_attr_with_ial(@tree.children.last.options[:attr] ||= {}, attr)
|
||||
else
|
||||
warning("Ignoring span IAL because preceding element is just text")
|
||||
end
|
||||
end
|
||||
define_parser(:span_ial, IAL_SPAN_START, '\{:')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
47
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/autolink.rb
Executable file
47
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/autolink.rb
Executable file
@@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
if RUBY_VERSION == '1.8.5'
|
||||
ACHARS = '\x80-\xFF'
|
||||
else
|
||||
ACHARS = ''
|
||||
end
|
||||
AUTOLINK_START = /<((mailto|https?|ftps?):.+?|[-.\w#{ACHARS}]+@[-\w#{ACHARS}]+(\.[-\w#{ACHARS}]+)*\.[a-z]+)>/u
|
||||
|
||||
# Parse the autolink at the current location.
|
||||
def parse_autolink
|
||||
@src.pos += @src.matched_size
|
||||
href = @src[1]
|
||||
href= "mailto:#{href}" if @src[2].nil?
|
||||
el = Element.new(:a, nil, {:attr => {'href' => href}})
|
||||
add_text(@src[1].sub(/^mailto:/, ''), el)
|
||||
@tree.children << el
|
||||
end
|
||||
define_parser(:autolink, AUTOLINK_START, '<')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
43
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/blank_line.rb
Executable file
43
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/blank_line.rb
Executable file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
BLANK_LINE = /(?:^\s*\n)+/
|
||||
|
||||
# Parse the blank line at the current postition.
|
||||
def parse_blank_line
|
||||
@src.pos += @src.matched_size
|
||||
if @tree.children.last && @tree.children.last.type == :blank
|
||||
@tree.children.last.value += @src.matched
|
||||
else
|
||||
@tree.children << new_block_el(:blank, @src.matched)
|
||||
end
|
||||
true
|
||||
end
|
||||
define_parser(:blank_line, BLANK_LINE)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
42
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/blockquote.rb
Executable file
42
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/blockquote.rb
Executable file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
BLOCKQUOTE_START = /^#{OPT_SPACE}> ?/
|
||||
BLOCKQUOTE_MATCH = /(^#{OPT_SPACE}>.*?\n)+/
|
||||
|
||||
# Parse the blockquote at the current location.
|
||||
def parse_blockquote
|
||||
result = @src.scan(BLOCKQUOTE_MATCH).gsub(BLOCKQUOTE_START, '')
|
||||
el = new_block_el(:blockquote)
|
||||
@tree.children << el
|
||||
parse_blocks(el, result)
|
||||
true
|
||||
end
|
||||
define_parser(:blockquote, BLOCKQUOTE_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
58
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/codeblock.rb
Executable file
58
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/codeblock.rb
Executable file
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/kramdown/blank_line'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
CODEBLOCK_START = INDENT
|
||||
CODEBLOCK_LINE = /(?:#{INDENT}.*?\S.*?\n)+/
|
||||
CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?#{CODEBLOCK_LINE})*/
|
||||
|
||||
# Parse the indented codeblock at the current location.
|
||||
def parse_codeblock
|
||||
@tree.children << new_block_el(:codeblock, @src.scan(CODEBLOCK_MATCH).gsub!(INDENT, ''))
|
||||
true
|
||||
end
|
||||
define_parser(:codeblock, CODEBLOCK_START)
|
||||
|
||||
|
||||
FENCED_CODEBLOCK_START = /^~{3,}/
|
||||
FENCED_CODEBLOCK_MATCH = /^(~{3,})\s*?\n(.*?)^\1~*\s*?\n/m
|
||||
|
||||
# Parse the fenced codeblock at the current location.
|
||||
def parse_codeblock_fenced
|
||||
if @src.check(FENCED_CODEBLOCK_MATCH)
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << new_block_el(:codeblock, @src[2])
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
define_parser(:codeblock_fenced, FENCED_CODEBLOCK_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
57
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/codespan.rb
Executable file
57
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/codespan.rb
Executable file
@@ -0,0 +1,57 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
CODESPAN_DELIMITER = /`+/
|
||||
|
||||
# Parse the codespan at the current scanner location.
|
||||
def parse_codespan
|
||||
result = @src.scan(CODESPAN_DELIMITER)
|
||||
simple = (result.length == 1)
|
||||
reset_pos = @src.pos
|
||||
|
||||
if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/)
|
||||
add_text(result)
|
||||
return
|
||||
end
|
||||
|
||||
text = @src.scan_until(/#{result}/)
|
||||
if text
|
||||
text.sub!(/#{result}\Z/, '')
|
||||
if !simple
|
||||
text = text[1..-1] if text[0..0] == ' '
|
||||
text = text[0..-2] if text[-1..-1] == ' '
|
||||
end
|
||||
@tree.children << Element.new(:codespan, text)
|
||||
else
|
||||
@src.pos = reset_pos
|
||||
add_text(result)
|
||||
end
|
||||
end
|
||||
define_parser(:codespan, CODESPAN_DELIMITER, '`')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
70
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/emphasis.rb
Executable file
70
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/emphasis.rb
Executable file
@@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
EMPHASIS_START = /(?:\*\*?|__?)/
|
||||
|
||||
# Parse the emphasis at the current location.
|
||||
def parse_emphasis
|
||||
result = @src.scan(EMPHASIS_START)
|
||||
element = (result.length == 2 ? :strong : :em)
|
||||
type = (result =~ /_/ ? '_' : '*')
|
||||
reset_pos = @src.pos
|
||||
|
||||
if (type == '_' && @src.pre_match =~ /[[:alpha:]]\z/ && @src.check(/[[:alpha:]]/)) || @src.check(/\s/) ||
|
||||
@tree.type == element || @stack.any? {|el, _| el.type == element}
|
||||
add_text(result)
|
||||
return
|
||||
end
|
||||
|
||||
sub_parse = lambda do |delim, elem|
|
||||
el = Element.new(elem)
|
||||
stop_re = /#{Regexp.escape(delim)}/
|
||||
found = parse_spans(el, stop_re) do
|
||||
(@src.pre_match[-1, 1] !~ /\s/) &&
|
||||
(elem != :em || !@src.match?(/#{Regexp.escape(delim*2)}(?!#{Regexp.escape(delim)})/)) &&
|
||||
(type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alpha:]]/)) && el.children.size > 0
|
||||
end
|
||||
[found, el, stop_re]
|
||||
end
|
||||
|
||||
found, el, stop_re = sub_parse.call(result, element)
|
||||
if !found && element == :strong && @tree.type != :em
|
||||
@src.pos = reset_pos - 1
|
||||
found, el, stop_re = sub_parse.call(type, :em)
|
||||
end
|
||||
if found
|
||||
@src.scan(stop_re)
|
||||
@tree.children << el
|
||||
else
|
||||
@src.pos = reset_pos
|
||||
add_text(result)
|
||||
end
|
||||
end
|
||||
define_parser(:emphasis, EMPHASIS_START, '\*|_')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
39
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/eob.rb
Executable file
39
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/eob.rb
Executable file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
EOB_MARKER = /^\^\s*?\n/
|
||||
|
||||
# Parse the EOB marker at the current location.
|
||||
def parse_eob_marker
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << new_block_el(:eob)
|
||||
true
|
||||
end
|
||||
define_parser(:eob_marker, EOB_MARKER)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
38
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/escaped_chars.rb
Executable file
38
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/escaped_chars.rb
Executable file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
ESCAPED_CHARS = /\\([\\.*_+`()\[\]{}#!:|"'\$-])/
|
||||
|
||||
# Parse the backslash-escaped character at the current location.
|
||||
def parse_escaped_chars
|
||||
@src.pos += @src.matched_size
|
||||
add_text(@src[1])
|
||||
end
|
||||
define_parser(:escaped_chars, ESCAPED_CHARS, '\\\\')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
102
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/extension.rb
Executable file
102
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/extension.rb
Executable file
@@ -0,0 +1,102 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/kramdown/attribute_list'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
def parse_extension_start_tag(type)
|
||||
@src.pos += @src.matched_size
|
||||
|
||||
if @src[4] || @src.matched == '{:/}'
|
||||
name = (@src[4] ? "for '#{@src[4]}' " : '')
|
||||
warning("Invalid extension stop tag #{name}found - ignoring it")
|
||||
return
|
||||
end
|
||||
|
||||
ext = @src[1]
|
||||
opts = {}
|
||||
body = nil
|
||||
parse_attribute_list(@src[2] || '', opts)
|
||||
|
||||
if !@src[3]
|
||||
stop_re = (type == :block ? /#{EXT_BLOCK_STOP_STR % ext}/ : /#{EXT_STOP_STR % ext}/)
|
||||
if result = @src.scan_until(stop_re)
|
||||
body = result.sub!(stop_re, '')
|
||||
body.chomp! if type == :block
|
||||
else
|
||||
warning("No stop tag for extension '#{ext}' found - treating it as extension without body")
|
||||
end
|
||||
end
|
||||
|
||||
handle_extension(ext, opts, body, type)
|
||||
end
|
||||
|
||||
def handle_extension(name, opts, body, type)
|
||||
case name
|
||||
when 'comment'
|
||||
@tree.children << Element.new(:comment, body, :category => type) if body.kind_of?(String)
|
||||
when 'nomarkdown'
|
||||
@tree.children << Element.new(:raw, body, :category => type) if body.kind_of?(String)
|
||||
when 'options'
|
||||
opts.select do |k,v|
|
||||
k = k.to_sym
|
||||
if Kramdown::Options.defined?(k)
|
||||
@doc.options[k] = Kramdown::Options.parse(k, v) rescue @doc.options[k]
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end.each do |k,v|
|
||||
warning("Unknown kramdown option '#{k}'")
|
||||
end
|
||||
else
|
||||
warning("Invalid extension name '#{name}' specified - ignoring extension")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
EXT_STOP_STR = "\\{:/(%s)?\\}"
|
||||
EXT_START_STR = "\\{::(\\w+)(?:\\s(#{ALD_ANY_CHARS}*?)|)(\\/)?\\}"
|
||||
EXT_SPAN_START = /#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME}/
|
||||
EXT_BLOCK_START = /^#{OPT_SPACE}(?:#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME})\s*?\n/
|
||||
EXT_BLOCK_STOP_STR = "^#{OPT_SPACE}#{EXT_STOP_STR}\s*?\n"
|
||||
|
||||
# Parse the extension block at the current location.
|
||||
def parse_block_extension
|
||||
parse_extension_start_tag(:block)
|
||||
true
|
||||
end
|
||||
define_parser(:block_extension, EXT_BLOCK_START)
|
||||
|
||||
|
||||
# Parse the extension span at the current location.
|
||||
def parse_span_extension
|
||||
parse_extension_start_tag(:span)
|
||||
end
|
||||
define_parser(:span_extension, EXT_SPAN_START, '\{:[:/]')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
73
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/footnote.rb
Executable file
73
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/footnote.rb
Executable file
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/kramdown/attribute_list'
|
||||
require 'kramdown/parser/kramdown/blank_line'
|
||||
require 'kramdown/parser/kramdown/codeblock'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
FOOTNOTE_DEFINITION_START = /^#{OPT_SPACE}\[\^(#{ALD_ID_NAME})\]:\s*?(.*?\n(?:#{BLANK_LINE}?#{CODEBLOCK_LINE})*)/
|
||||
|
||||
# Parse the foot note definition at the current location.
|
||||
def parse_footnote_definition
|
||||
@src.pos += @src.matched_size
|
||||
|
||||
el = Element.new(:footnote_def)
|
||||
parse_blocks(el, @src[2].gsub(INDENT, ''))
|
||||
warning("Duplicate footnote name '#{@src[1]}' - overwriting") if @doc.parse_infos[:footnotes][@src[1]]
|
||||
(@doc.parse_infos[:footnotes][@src[1]] = {})[:content] = el
|
||||
true
|
||||
end
|
||||
define_parser(:footnote_definition, FOOTNOTE_DEFINITION_START)
|
||||
|
||||
|
||||
FOOTNOTE_MARKER_START = /\[\^(#{ALD_ID_NAME})\]/
|
||||
|
||||
# Parse the footnote marker at the current location.
|
||||
def parse_footnote_marker
|
||||
@src.pos += @src.matched_size
|
||||
fn_def = @doc.parse_infos[:footnotes][@src[1]]
|
||||
if fn_def
|
||||
valid = fn_def[:marker] && fn_def[:marker].options[:stack][0..-2].zip(fn_def[:marker].options[:stack][1..-1]).all? do |par, child|
|
||||
par.children.include?(child)
|
||||
end
|
||||
if !fn_def[:marker] || !valid
|
||||
fn_def[:marker] = Element.new(:footnote, nil, :name => @src[1])
|
||||
fn_def[:marker].options[:stack] = [@stack.map {|s| s.first}, @tree, fn_def[:marker]].flatten.compact
|
||||
@tree.children << fn_def[:marker]
|
||||
else
|
||||
warning("Footnote marker '#{@src[1]}' already appeared in document, ignoring newly found marker")
|
||||
add_text(@src.matched)
|
||||
end
|
||||
else
|
||||
warning("Footnote definition for '#{@src[1]}' not found")
|
||||
add_text(@src.matched)
|
||||
end
|
||||
end
|
||||
define_parser(:footnote_marker, FOOTNOTE_MARKER_START, '\[')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
66
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/header.rb
Executable file
66
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/header.rb
Executable file
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
HEADER_ID=/(?:[ \t]\{#((?:\w|\d)[\w\d-]*)\})?/
|
||||
SETEXT_HEADER_START = /^(#{OPT_SPACE}[^ \t].*?)#{HEADER_ID}[ \t]*?\n(-|=)+\s*?\n/
|
||||
|
||||
# Parse the Setext header at the current location.
|
||||
def parse_setext_header
|
||||
if @tree.children.last && @tree.children.last.type != :blank
|
||||
return false
|
||||
end
|
||||
@src.pos += @src.matched_size
|
||||
text, id, level = @src[1].strip, @src[2], @src[3]
|
||||
el = new_block_el(:header, nil, :level => (level == '-' ? 2 : 1), :raw_text => text)
|
||||
add_text(text, el)
|
||||
el.options[:attr] = {'id' => id} if id
|
||||
@tree.children << el
|
||||
true
|
||||
end
|
||||
define_parser(:setext_header, SETEXT_HEADER_START)
|
||||
|
||||
|
||||
ATX_HEADER_START = /^\#{1,6}/
|
||||
ATX_HEADER_MATCH = /^(\#{1,6})(.+?)\s*?#*#{HEADER_ID}\s*?\n/
|
||||
|
||||
# Parse the Atx header at the current location.
|
||||
def parse_atx_header
|
||||
if @tree.children.last && @tree.children.last.type != :blank
|
||||
return false
|
||||
end
|
||||
result = @src.scan(ATX_HEADER_MATCH)
|
||||
level, text, id = @src[1], @src[2].strip, @src[3]
|
||||
el = new_block_el(:header, nil, :level => level.length, :raw_text => text)
|
||||
add_text(text, el)
|
||||
el.options[:attr] = {'id' => id} if id
|
||||
@tree.children << el
|
||||
true
|
||||
end
|
||||
define_parser(:atx_header, ATX_HEADER_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
39
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/horizontal_rule.rb
Executable file
39
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/horizontal_rule.rb
Executable file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
HR_START = /^#{OPT_SPACE}(\*|-|_)[ \t]*\1[ \t]*\1[ \t]*(\1|[ \t])*\n/
|
||||
|
||||
# Parse the horizontal rule at the current location.
|
||||
def parse_horizontal_rule
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << new_block_el(:hr)
|
||||
true
|
||||
end
|
||||
define_parser(:horizontal_rule, HR_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
173
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/html.rb
Executable file
173
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/html.rb
Executable file
@@ -0,0 +1,173 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/html'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
include Kramdown::Parser::Html::Parser
|
||||
|
||||
def handle_kramdown_html_tag(el, closed)
|
||||
parse_type = if @tree.type != :html_element || @tree.options[:parse_type] != :raw
|
||||
(@doc.options[:parse_block_html] ? HTML_PARSE_AS[el.value] : :raw)
|
||||
else
|
||||
:raw
|
||||
end
|
||||
if val = html_parse_type(el.options[:attr].delete('markdown'))
|
||||
parse_type = (val == :default ? HTML_PARSE_AS[el.value] : val)
|
||||
end
|
||||
|
||||
@src.scan(/[ \t]*\n/) if parse_type == :block
|
||||
el.options[:outer_element] = true if @tree.type != :html_element
|
||||
el.options[:parent_is_raw] = true if @tree.type == :html_element && @tree.options[:parse_type] == :raw
|
||||
el.options[:parse_type] = parse_type
|
||||
|
||||
if !closed
|
||||
if parse_type == :block
|
||||
end_tag_found = parse_blocks(el)
|
||||
if !end_tag_found
|
||||
warning("Found no end tag for '#{el.value}' - auto-closing it")
|
||||
end
|
||||
elsif parse_type == :span
|
||||
curpos = @src.pos
|
||||
if result = @src.scan_until(/(?=<\/#{el.value}\s*>)/m)
|
||||
add_text(extract_string(curpos...@src.pos, @src), el)
|
||||
@src.scan(HTML_TAG_CLOSE_RE)
|
||||
else
|
||||
add_text(@src.scan(/.*/m), el)
|
||||
warning("Found no end tag for '#{el.value}' - auto-closing it")
|
||||
end
|
||||
else
|
||||
parse_raw_html(el, &method(:handle_kramdown_html_tag))
|
||||
end
|
||||
@src.scan(/[ \t]*\n/) unless (@tree.type == :html_element && @tree.options[:parse_type] == :raw)
|
||||
end
|
||||
end
|
||||
|
||||
# Return the HTML parse type defined by the string +val+, i.e. raw when "0", default parsing
|
||||
# (return value +nil+) when "1", span parsing when "span" and block parsing when "block". If
|
||||
# +val+ is nil, then the default parsing mode is used.
|
||||
def html_parse_type(val)
|
||||
case val
|
||||
when "0" then :raw
|
||||
when "1" then :default
|
||||
when "span" then :span
|
||||
when "block" then :block
|
||||
when NilClass then nil
|
||||
else
|
||||
warning("Invalid markdown attribute val '#{val}', using default")
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
HTML_BLOCK_START = /^#{OPT_SPACE}<(#{REXML::Parsers::BaseParser::UNAME_STR}|\?|!--|\/)/
|
||||
|
||||
# Parse the HTML at the current position as block level HTML.
|
||||
def parse_block_html
|
||||
if result = @src.scan(HTML_COMMENT_RE)
|
||||
@tree.children << Element.new(:xml_comment, result, :category => :block)
|
||||
@src.scan(/[ \t]*\n/)
|
||||
true
|
||||
elsif result = @src.scan(HTML_INSTRUCTION_RE)
|
||||
@tree.children << Element.new(:xml_pi, result, :category => :block)
|
||||
@src.scan(/[ \t]*\n/)
|
||||
true
|
||||
else
|
||||
if result = @src.check(/^#{OPT_SPACE}#{HTML_TAG_RE}/) && !HTML_SPAN_ELEMENTS.include?(@src[1])
|
||||
@src.pos += @src.matched_size
|
||||
handle_html_start_tag(&method(:handle_kramdown_html_tag))
|
||||
Kramdown::Parser::Html::ElementConverter.new(@doc).process(@tree.children.last) if @doc.options[:html_to_native]
|
||||
true
|
||||
elsif result = @src.check(/^#{OPT_SPACE}#{HTML_TAG_CLOSE_RE}/) && !HTML_SPAN_ELEMENTS.include?(@src[1])
|
||||
@src.pos += @src.matched_size
|
||||
name = @src[1]
|
||||
|
||||
if @tree.type == :html_element && @tree.value == name
|
||||
throw :stop_block_parsing, :found
|
||||
else
|
||||
warning("Found invalidly used HTML closing tag for '#{name}' - ignoring it")
|
||||
true
|
||||
end
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
define_parser(:block_html, HTML_BLOCK_START)
|
||||
|
||||
|
||||
HTML_SPAN_START = /<(#{REXML::Parsers::BaseParser::UNAME_STR}|\?|!--|\/)/
|
||||
|
||||
# Parse the HTML at the current position as span level HTML.
|
||||
def parse_span_html
|
||||
if result = @src.scan(HTML_COMMENT_RE)
|
||||
@tree.children << Element.new(:xml_comment, result, :category => :span)
|
||||
elsif result = @src.scan(HTML_INSTRUCTION_RE)
|
||||
@tree.children << Element.new(:xml_pi, result, :category => :span)
|
||||
elsif result = @src.scan(HTML_TAG_CLOSE_RE)
|
||||
warning("Found invalidly used HTML closing tag for '#{@src[1]}' - ignoring it")
|
||||
elsif result = @src.scan(HTML_TAG_RE)
|
||||
return if HTML_BLOCK_ELEMENTS.include?(@src[1])
|
||||
|
||||
reset_pos = @src.pos
|
||||
attrs = {}
|
||||
@src[2].scan(HTML_ATTRIBUTE_RE).each {|name,sep,val| attrs[name] = val.gsub(/\n+/, ' ')}
|
||||
|
||||
do_parsing = (HTML_PARSE_AS_RAW.include?(@src[1]) || @tree.options[:parse_type] == :raw ? false : @doc.options[:parse_span_html])
|
||||
if val = html_parse_type(attrs.delete('markdown'))
|
||||
if val == :block
|
||||
warning("Cannot use block level parsing in span level HTML tag - using default mode")
|
||||
elsif val == :span
|
||||
do_parsing = true
|
||||
elsif val == :default
|
||||
do_parsing = !HTML_PARSE_AS_RAW.include?(@src[1])
|
||||
elsif val == :raw
|
||||
do_parsing = false
|
||||
end
|
||||
end
|
||||
|
||||
el = Element.new(:html_element, @src[1], :attr => attrs, :category => :span, :parse_type => (do_parsing ? :span : :raw))
|
||||
@tree.children << el
|
||||
stop_re = /<\/#{Regexp.escape(@src[1])}\s*>/
|
||||
if !@src[4] && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value)
|
||||
warning("The HTML tag '#{el.value}' cannot have any content - auto-closing it")
|
||||
elsif !@src[4]
|
||||
if parse_spans(el, stop_re, (do_parsing ? nil : [:span_html]))
|
||||
@src.scan(stop_re)
|
||||
else
|
||||
warning("Found no end tag for '#{el.value}' - auto-closing it")
|
||||
add_text(@src.scan(/.*/m), el)
|
||||
end
|
||||
end
|
||||
Kramdown::Parser::Html::ElementConverter.new(@doc).process(el) if @doc.options[:html_to_native]
|
||||
else
|
||||
add_text(@src.scan(/./))
|
||||
end
|
||||
end
|
||||
define_parser(:span_html, HTML_SPAN_START, '<')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
38
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/html_entity.rb
Executable file
38
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/html_entity.rb
Executable file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/html'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
# Parse the HTML entity at the current location.
|
||||
def parse_html_entity
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2] && @src[2].to_i) || @src[3].hex))
|
||||
end
|
||||
define_parser(:html_entity, Kramdown::Parser::Html::Constants::HTML_ENTITY_RE, '&')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
38
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/line_break.rb
Executable file
38
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/line_break.rb
Executable file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
LINE_BREAK = /( |\\\\)(?=\n)/
|
||||
|
||||
# Parse the line break at the current location.
|
||||
def parse_line_break
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << Element.new(:br)
|
||||
end
|
||||
define_parser(:line_break, LINE_BREAK, '( |\\\\)(?=\n)')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
156
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/link.rb
Executable file
156
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/link.rb
Executable file
@@ -0,0 +1,156 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
PUNCTUATION_CHARS = "_.:,;!?-"
|
||||
LINK_ID_CHARS = /[a-zA-Z0-9 #{PUNCTUATION_CHARS}]/
|
||||
LINK_ID_NON_CHARS = /[^a-zA-Z0-9 #{PUNCTUATION_CHARS}]/
|
||||
LINK_DEFINITION_START = /^#{OPT_SPACE}\[(#{LINK_ID_CHARS}+)\]:[ \t]*(?:<(.*?)>|([^\s]+))[ \t]*?(?:\n?[ \t]*?(["'])(.+?)\4[ \t]*?)?\n/
|
||||
|
||||
# Parse the link definition at the current location.
|
||||
def parse_link_definition
|
||||
@src.pos += @src.matched_size
|
||||
link_id, link_url, link_title = @src[1].downcase, @src[2] || @src[3], @src[5]
|
||||
warning("Duplicate link ID '#{link_id}' - overwriting") if @doc.parse_infos[:link_defs][link_id]
|
||||
@doc.parse_infos[:link_defs][link_id] = [link_url, link_title]
|
||||
true
|
||||
end
|
||||
define_parser(:link_definition, LINK_DEFINITION_START)
|
||||
|
||||
|
||||
# This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+
|
||||
# and the element itself to the <tt>@tree</tt>.
|
||||
def add_link(el, href, title, alt_text = nil)
|
||||
el.options[:attr] ||= {}
|
||||
el.options[:attr]['title'] = title if title
|
||||
if el.type == :a
|
||||
el.options[:attr]['href'] = href
|
||||
else
|
||||
el.options[:attr]['src'] = href
|
||||
el.options[:attr]['alt'] = alt_text
|
||||
el.children.clear
|
||||
end
|
||||
@tree.children << el
|
||||
end
|
||||
|
||||
LINK_TEXT_BRACKET_RE = /\\\[|\\\]|\[|\]/
|
||||
LINK_INLINE_ID_RE = /\s*?\[(#{LINK_ID_CHARS}+)?\]/
|
||||
LINK_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/
|
||||
LINK_START = /!?\[(?=[^^])/
|
||||
|
||||
# Parse the link at the current scanner position. This method is used to parse normal links as
|
||||
# well as image links.
|
||||
def parse_link
|
||||
result = @src.scan(LINK_START)
|
||||
reset_pos = @src.pos
|
||||
|
||||
link_type = (result =~ /^!/ ? :img : :a)
|
||||
|
||||
# no nested links allowed
|
||||
if link_type == :a && (@tree.type == :img || @tree.type == :a || @stack.any? {|t,s| t && (t.type == :img || t.type == :a)})
|
||||
add_text(result)
|
||||
return
|
||||
end
|
||||
el = Element.new(link_type)
|
||||
|
||||
stop_re = /\]|!?\[/
|
||||
count = 1
|
||||
found = parse_spans(el, stop_re) do
|
||||
case @src.matched
|
||||
when "[", "!["
|
||||
count += 1
|
||||
when "]"
|
||||
count -= 1
|
||||
end
|
||||
count - el.children.select {|c| c.type == :img}.size == 0
|
||||
end
|
||||
if !found || (link_type == :a && el.children.empty?)
|
||||
@src.pos = reset_pos
|
||||
add_text(result)
|
||||
return
|
||||
end
|
||||
alt_text = extract_string(reset_pos...@src.pos, @src)
|
||||
conv_link_id = alt_text.gsub(/(\s|\n)+/m, ' ').gsub(LINK_ID_NON_CHARS, '').downcase
|
||||
@src.scan(stop_re)
|
||||
|
||||
# reference style link or no link url
|
||||
if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/)
|
||||
link_id = (@src[1] || conv_link_id).downcase
|
||||
if link_id.empty?
|
||||
@src.pos = reset_pos
|
||||
add_text(result)
|
||||
elsif @doc.parse_infos[:link_defs].has_key?(link_id)
|
||||
add_link(el, @doc.parse_infos[:link_defs][link_id].first, @doc.parse_infos[:link_defs][link_id].last, alt_text)
|
||||
else
|
||||
warning("No link definition for link ID '#{link_id}' found")
|
||||
@src.pos = reset_pos
|
||||
add_text(result)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
# link url in parentheses
|
||||
if @src.scan(/\(<(.*?)>/)
|
||||
link_url = @src[1]
|
||||
if @src.scan(/\)/)
|
||||
add_link(el, link_url, nil, alt_text)
|
||||
return
|
||||
end
|
||||
else
|
||||
link_url = ''
|
||||
re = /\(|\)|\s/
|
||||
nr_of_brackets = 0
|
||||
while temp = @src.scan_until(re)
|
||||
link_url += temp
|
||||
case @src.matched
|
||||
when /\s/
|
||||
break
|
||||
when '('
|
||||
nr_of_brackets += 1
|
||||
when ')'
|
||||
nr_of_brackets -= 1
|
||||
break if nr_of_brackets == 0
|
||||
end
|
||||
end
|
||||
link_url = link_url[1..-2]
|
||||
|
||||
if nr_of_brackets == 0
|
||||
add_link(el, link_url, nil, alt_text)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if @src.scan(LINK_INLINE_TITLE_RE)
|
||||
add_link(el, link_url, @src[2], alt_text)
|
||||
else
|
||||
@src.pos = reset_pos
|
||||
add_text(result)
|
||||
end
|
||||
end
|
||||
define_parser(:link, LINK_START, '!?\[')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
232
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/list.rb
Executable file
232
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/list.rb
Executable file
@@ -0,0 +1,232 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/kramdown/blank_line'
|
||||
require 'kramdown/parser/kramdown/eob'
|
||||
require 'kramdown/parser/kramdown/horizontal_rule'
|
||||
require 'kramdown/parser/kramdown/attribute_list'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
# Used for parsing the first line of a list item or a definition, i.e. the line with list item
|
||||
# marker or the definition marker.
|
||||
def parse_first_list_line(indentation, content)
|
||||
if content =~ /^\s*(#{IAL_SPAN_START})?\s*\n/
|
||||
indentation = 4
|
||||
else
|
||||
while content =~ /^ *\t/
|
||||
temp = content.scan(/^ */).first.length + indentation
|
||||
content.sub!(/^( *)(\t+)/) {$1 + " "*(4 - (temp % 4)) + " "*($2.length - 1)*4}
|
||||
end
|
||||
indentation += content.scan(/^ */).first.length
|
||||
end
|
||||
content.sub!(/^\s*/, '')
|
||||
|
||||
indent_re = /^ {#{indentation}}/
|
||||
content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*?\n/
|
||||
[content, indentation, content_re, indent_re]
|
||||
end
|
||||
|
||||
|
||||
LIST_START_UL = /^(#{OPT_SPACE}[+*-])([\t| ].*?\n)/
|
||||
LIST_START_OL = /^(#{OPT_SPACE}\d+\.)([\t| ].*?\n)/
|
||||
LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/
|
||||
|
||||
# Parse the ordered or unordered list at the current location.
|
||||
def parse_list
|
||||
if @tree.children.last && @tree.children.last.type == :p # last element must not be a paragraph
|
||||
return false
|
||||
end
|
||||
|
||||
type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
|
||||
list = new_block_el(type)
|
||||
|
||||
item = nil
|
||||
indent_re = nil
|
||||
content_re = nil
|
||||
eob_found = false
|
||||
nested_list_found = false
|
||||
while !@src.eos?
|
||||
if @src.check(HR_START)
|
||||
break
|
||||
elsif @src.scan(list_start_re)
|
||||
item = Element.new(:li)
|
||||
item.value, indentation, content_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
||||
list.children << item
|
||||
|
||||
item.value.sub!(/^#{IAL_SPAN_START}\s*/) do |match|
|
||||
parse_attribute_list($~[1], item.options[:ial] ||= {})
|
||||
''
|
||||
end
|
||||
|
||||
list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ :
|
||||
/^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/)
|
||||
nested_list_found = false
|
||||
elsif result = @src.scan(content_re)
|
||||
result.sub!(/^(\t+)/) { " "*4*($1 ? $1.length : 0) }
|
||||
result.sub!(indent_re, '')
|
||||
if !nested_list_found && result =~ LIST_START
|
||||
parse_blocks(item, item.value)
|
||||
if item.children.length == 1 && item.children.first.type == :p
|
||||
item.value = ''
|
||||
else
|
||||
item.children.clear
|
||||
end
|
||||
nested_list_found = true
|
||||
end
|
||||
item.value << result
|
||||
elsif result = @src.scan(BLANK_LINE)
|
||||
nested_list_found = true
|
||||
item.value << result
|
||||
elsif @src.scan(EOB_MARKER)
|
||||
eob_found = true
|
||||
break
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@tree.children << list
|
||||
|
||||
last = nil
|
||||
list.children.each do |it|
|
||||
temp = Element.new(:temp)
|
||||
parse_blocks(temp, it.value)
|
||||
it.children += temp.children
|
||||
it.value = nil
|
||||
next if it.children.size == 0
|
||||
|
||||
if it.children.first.type == :p && (it.children.length < 2 || it.children[1].type != :blank ||
|
||||
(it == list.children.last && it.children.length == 2 && !eob_found)) &&
|
||||
(list.children.last != it || list.children.size == 1 ||
|
||||
list.children[0..-2].any? {|cit| cit.children.first.type != :p || cit.children.first.options[:transparent]})
|
||||
it.children.first.children.first.value += "\n" if it.children.size > 1 && it.children[1].type != :blank
|
||||
it.children.first.options[:transparent] = true
|
||||
end
|
||||
|
||||
if it.children.last.type == :blank
|
||||
last = it.children.pop
|
||||
else
|
||||
last = nil
|
||||
end
|
||||
end
|
||||
|
||||
@tree.children << last if !last.nil? && !eob_found
|
||||
|
||||
true
|
||||
end
|
||||
define_parser(:list, LIST_START)
|
||||
|
||||
|
||||
DEFINITION_LIST_START = /^(#{OPT_SPACE}:)([\t| ].*?\n)/
|
||||
|
||||
# Parse the ordered or unordered list at the current location.
|
||||
def parse_definition_list
|
||||
children = @tree.children
|
||||
if !children.last || (children.length == 1 && children.last.type != :p ) ||
|
||||
(children.length >= 2 && children[-1].type != :p && (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p))
|
||||
return false
|
||||
end
|
||||
|
||||
first_as_para = false
|
||||
deflist = new_block_el(:dl)
|
||||
para = @tree.children.pop
|
||||
if para.type == :blank
|
||||
para = @tree.children.pop
|
||||
first_as_para = true
|
||||
end
|
||||
para.children.first.value.split("\n").each do |term|
|
||||
el = Element.new(:dt)
|
||||
el.children << Element.new(:raw_text, term)
|
||||
deflist.children << el
|
||||
end
|
||||
|
||||
item = nil
|
||||
indent_re = nil
|
||||
content_re = nil
|
||||
def_start_re = DEFINITION_LIST_START
|
||||
while !@src.eos?
|
||||
if @src.scan(def_start_re)
|
||||
item = Element.new(:dd)
|
||||
item.options[:first_as_para] = first_as_para
|
||||
item.value, indentation, content_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
||||
deflist.children << item
|
||||
|
||||
item.value.sub!(/^#{IAL_SPAN_START}\s*/) do |match|
|
||||
parse_attribute_list($~[1], item.options[:ial] ||= {})
|
||||
''
|
||||
end
|
||||
|
||||
def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/
|
||||
first_as_para = false
|
||||
elsif result = @src.scan(content_re)
|
||||
result.sub!(/^(\t+)/) { " "*4*($1 ? $1.length : 0) }
|
||||
result.sub!(indent_re, '')
|
||||
item.value << result
|
||||
first_as_para = false
|
||||
elsif result = @src.scan(BLANK_LINE)
|
||||
first_as_para = true
|
||||
item.value << result
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
last = nil
|
||||
deflist.children.each do |it|
|
||||
next if it.type == :dt
|
||||
|
||||
parse_blocks(it, it.value)
|
||||
it.value = nil
|
||||
next if it.children.size == 0
|
||||
|
||||
if it.children.last.type == :blank
|
||||
last = it.children.pop
|
||||
else
|
||||
last = nil
|
||||
end
|
||||
if it.children.first.type == :p && !it.options.delete(:first_as_para)
|
||||
it.children.first.children.first.value += "\n" if it.children.size > 1
|
||||
it.children.first.options[:transparent] = true
|
||||
end
|
||||
end
|
||||
|
||||
if @tree.children.length >= 1 && @tree.children.last.type == :dl
|
||||
@tree.children[-1].children += deflist.children
|
||||
elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank && @tree.children[-2].type == :dl
|
||||
@tree.children.pop
|
||||
@tree.children[-1].children += deflist.children
|
||||
else
|
||||
@tree.children << deflist
|
||||
end
|
||||
|
||||
@tree.children << last if !last.nil?
|
||||
|
||||
true
|
||||
end
|
||||
define_parser(:definition_list, DEFINITION_LIST_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
53
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/math.rb
Executable file
53
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/math.rb
Executable file
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
BLOCK_MATH_START = /^#{OPT_SPACE}(\\)?\$\$(.*?)\$\$\s*?\n/m
|
||||
|
||||
# Parse the math block at the current location.
|
||||
def parse_block_math
|
||||
if @src[1]
|
||||
@src.scan(/^#{OPT_SPACE}\\/)
|
||||
return false
|
||||
end
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << new_block_el(:math, @src[2], :category => :block)
|
||||
true
|
||||
end
|
||||
define_parser(:block_math, BLOCK_MATH_START)
|
||||
|
||||
|
||||
INLINE_MATH_START = /\$\$(.*?)\$\$/
|
||||
|
||||
# Parse the inline math at the current location.
|
||||
def parse_inline_math
|
||||
@src.pos += @src.matched_size
|
||||
@tree.children << Element.new(:math, @src[1], :category => :span)
|
||||
end
|
||||
define_parser(:inline_math, INLINE_MATH_START, '\$')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
44
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/paragraph.rb
Executable file
44
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/paragraph.rb
Executable file
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/
|
||||
|
||||
# Parse the paragraph at the current location.
|
||||
def parse_paragraph
|
||||
@src.pos += @src.matched_size
|
||||
if @tree.children.last && @tree.children.last.type == :p
|
||||
@tree.children.last.children.first.value << "\n" << @src.matched.chomp
|
||||
else
|
||||
@tree.children << new_block_el(:p)
|
||||
add_text(@src.matched.lstrip.chomp, @tree.children.last)
|
||||
end
|
||||
true
|
||||
end
|
||||
define_parser(:paragraph, PARAGRAPH_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
214
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/smart_quotes.rb
Executable file
214
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/smart_quotes.rb
Executable file
@@ -0,0 +1,214 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
#--
|
||||
# Parts of this file are based on code from Maruku by Andrea Censi.
|
||||
# The needed license statements follow:
|
||||
#
|
||||
# Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
|
||||
#
|
||||
# Maruku is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Maruku 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 Maruku; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# NOTA BENE:
|
||||
#
|
||||
# The following algorithm is a rip-off of RubyPants written by
|
||||
# Christian Neukirchen.
|
||||
#
|
||||
# RubyPants is a Ruby port of SmartyPants written by John Gruber.
|
||||
#
|
||||
# This file is distributed under the GPL, which I guess is compatible
|
||||
# with the terms of the RubyPants license.
|
||||
#
|
||||
# -- Andrea Censi
|
||||
#
|
||||
# = RubyPants -- SmartyPants ported to Ruby
|
||||
#
|
||||
# Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com>
|
||||
# Copyright (C) 2004 Christian Neukirchen
|
||||
#
|
||||
# Incooporates ideas, comments and documentation by Chad Miller
|
||||
# Copyright (C) 2004 Chad Miller
|
||||
#
|
||||
# Original SmartyPants by John Gruber
|
||||
# Copyright (C) 2003 John Gruber
|
||||
#
|
||||
#
|
||||
# = RubyPants -- SmartyPants ported to Ruby
|
||||
#
|
||||
#
|
||||
# [snip]
|
||||
#
|
||||
# == Authors
|
||||
#
|
||||
# John Gruber did all of the hard work of writing this software in
|
||||
# Perl for Movable Type and almost all of this useful documentation.
|
||||
# Chad Miller ported it to Python to use with Pyblosxom.
|
||||
#
|
||||
# Christian Neukirchen provided the Ruby port, as a general-purpose
|
||||
# library that follows the *Cloth API.
|
||||
#
|
||||
#
|
||||
# == Copyright and License
|
||||
#
|
||||
# === SmartyPants license:
|
||||
#
|
||||
# Copyright (c) 2003 John Gruber
|
||||
# (http://daringfireball.net)
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# * Neither the name "SmartyPants" nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# This software is provided by the copyright holders and contributors
|
||||
# "as is" and any express or implied warranties, including, but not
|
||||
# limited to, the implied warranties of merchantability and fitness
|
||||
# for a particular purpose are disclaimed. In no event shall the
|
||||
# copyright owner or contributors be liable for any direct, indirect,
|
||||
# incidental, special, exemplary, or consequential damages (including,
|
||||
# but not limited to, procurement of substitute goods or services;
|
||||
# loss of use, data, or profits; or business interruption) however
|
||||
# caused and on any theory of liability, whether in contract, strict
|
||||
# liability, or tort (including negligence or otherwise) arising in
|
||||
# any way out of the use of this software, even if advised of the
|
||||
# possibility of such damage.
|
||||
#
|
||||
# === RubyPants license
|
||||
#
|
||||
# RubyPants is a derivative work of SmartyPants and smartypants.py.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# This software is provided by the copyright holders and contributors
|
||||
# "as is" and any express or implied warranties, including, but not
|
||||
# limited to, the implied warranties of merchantability and fitness
|
||||
# for a particular purpose are disclaimed. In no event shall the
|
||||
# copyright owner or contributors be liable for any direct, indirect,
|
||||
# incidental, special, exemplary, or consequential damages (including,
|
||||
# but not limited to, procurement of substitute goods or services;
|
||||
# loss of use, data, or profits; or business interruption) however
|
||||
# caused and on any theory of liability, whether in contract, strict
|
||||
# liability, or tort (including negligence or otherwise) arising in
|
||||
# any way out of the use of this software, even if advised of the
|
||||
# possibility of such damage.
|
||||
#
|
||||
# == Links
|
||||
#
|
||||
# John Gruber:: http://daringfireball.net
|
||||
# SmartyPants:: http://daringfireball.net/projects/smartypants
|
||||
#
|
||||
# Chad Miller:: http://web.chad.org
|
||||
#
|
||||
# Christian Neukirchen:: http://kronavita.de/chris
|
||||
#
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
|
||||
SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]!
|
||||
|
||||
SQ_RULES = [
|
||||
[/("|')(?=#{SQ_PUNCT}\B)/, [:rquote1]],
|
||||
# Special case for double sets of quotes, e.g.:
|
||||
# <p>He said, "'Quoted' words in a larger quote."</p>
|
||||
[/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]],
|
||||
[/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]],
|
||||
# Special case for decade abbreviations (the '80s):
|
||||
[/(\s?)'(?=\d\ds)/, [1, :rsquo]],
|
||||
|
||||
# Get most opening single/double quotes:
|
||||
[/(\s)('|")(?=\w)/, [1, :lquote2]],
|
||||
# Single/double closing quotes:
|
||||
[/(#{SQ_CLOSE})('|")/, [1, :rquote2]],
|
||||
# Special case for e.g. "<i>Custer</i>'s Last Stand."
|
||||
[/("|')(\s|s\b|$)/, [:rquote1, 2]],
|
||||
# Any remaining single quotes should be opening ones:
|
||||
[/(.?)'/m, [1, :lsquo]],
|
||||
[/(.?)"/m, [1, :ldquo]],
|
||||
] #'"
|
||||
|
||||
SQ_SUBSTS = {
|
||||
[:rquote1, '"'] => :rdquo,
|
||||
[:rquote1, "'"] => :rsquo,
|
||||
[:rquote2, '"'] => :rdquo,
|
||||
[:rquote2, "'"] => :rsquo,
|
||||
[:lquote1, '"'] => :ldquo,
|
||||
[:lquote1, "'"] => :lsquo,
|
||||
[:lquote2, '"'] => :ldquo,
|
||||
[:lquote2, "'"] => :lsquo,
|
||||
}
|
||||
SMART_QUOTES_RE = /[^\\]?["']/
|
||||
|
||||
# Parse the smart quotes at current location.
|
||||
def parse_smart_quotes
|
||||
regexp, substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}
|
||||
substs.each do |subst|
|
||||
if subst.kind_of?(Integer)
|
||||
add_text(@src[subst].to_s)
|
||||
else
|
||||
val = SQ_SUBSTS[[subst, @src[subst.to_s[-1,1].to_i]]] || subst
|
||||
@tree.children << Element.new(:smart_quote, val)
|
||||
end
|
||||
end
|
||||
end
|
||||
define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
126
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/table.rb
Executable file
126
vim/plugin/vim-markdown-preview/kramdown/parser/kramdown/table.rb
Executable file
@@ -0,0 +1,126 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/parser/kramdown/blank_line'
|
||||
require 'kramdown/parser/kramdown/eob'
|
||||
require 'kramdown/parser/kramdown/horizontal_rule'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
TABLE_SEP_LINE = /^#{OPT_SPACE}(?:\||\+)([ ]?:?-[+|: -]*)[ \t]*\n/
|
||||
TABLE_HSEP_ALIGN = /[ ]?(:?)-+(:?)[ ]?/
|
||||
TABLE_FSEP_LINE = /^#{OPT_SPACE}(\||\+)[ ]?:?=[+|: =]*[ \t]*\n/
|
||||
TABLE_ROW_LINE = /^#{OPT_SPACE}\|(.*?)[ \t]*\n/
|
||||
TABLE_START = /^#{OPT_SPACE}\|(?:-|(?!=))/
|
||||
|
||||
# Parse the table at the current location.
|
||||
def parse_table
|
||||
orig_pos = @src.pos
|
||||
table = new_block_el(:table, nil, :alignment => [])
|
||||
|
||||
@src.scan(TABLE_SEP_LINE)
|
||||
|
||||
rows = []
|
||||
has_footer = false
|
||||
columns = 0
|
||||
|
||||
add_container = lambda do |type, force|
|
||||
if force || type != :tbody || !has_footer
|
||||
cont = Element.new(type)
|
||||
cont.children, rows = rows, []
|
||||
table.children << cont
|
||||
end
|
||||
end
|
||||
|
||||
while !@src.eos?
|
||||
if @src.scan(TABLE_SEP_LINE) && !rows.empty?
|
||||
if table.options[:alignment].empty? && !has_footer
|
||||
add_container.call(:thead, false)
|
||||
table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
|
||||
(left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
|
||||
end
|
||||
else # treat as normal separator line
|
||||
add_container.call(:tbody, false)
|
||||
end
|
||||
elsif @src.scan(TABLE_FSEP_LINE)
|
||||
add_container.call(:tbody, true) if !rows.empty?
|
||||
has_footer = true
|
||||
elsif @src.scan(TABLE_ROW_LINE)
|
||||
trow = Element.new(:tr)
|
||||
cells = (@src[1] + ' ').split(/\|/)
|
||||
i = 0
|
||||
while i < cells.length - 1
|
||||
backslashes = cells[i].scan(/\\+$/).first
|
||||
if backslashes && backslashes.length % 2 == 1
|
||||
cells[i] = cells[i].chop + '|' + cells[i+1]
|
||||
cells.delete_at(i+1)
|
||||
else
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
cells.pop if cells.last.strip.empty?
|
||||
cells.each do |cell_text|
|
||||
tcell = Element.new(:td)
|
||||
tcell.children << Element.new(:raw_text, cell_text.strip)
|
||||
trow.children << tcell
|
||||
end
|
||||
columns = [columns, cells.length].max
|
||||
rows << trow
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty?
|
||||
|
||||
if !table.children.any? {|c| c.type == :tbody}
|
||||
warning("Found table without body - ignoring it")
|
||||
@src.pos = orig_pos
|
||||
return false
|
||||
end
|
||||
|
||||
# adjust all table rows to have equal number of columns, same for alignment defs
|
||||
table.children.each do |kind|
|
||||
kind.children.each do |row|
|
||||
(columns - row.children.length).times do
|
||||
row.children << Element.new(:td)
|
||||
end
|
||||
row.children.each {|el| el.type = :th} if kind.type == :thead
|
||||
end
|
||||
end
|
||||
if table.options[:alignment].length > columns
|
||||
table.options[:alignment] = table.options[:alignment][0...columns]
|
||||
else
|
||||
table.options[:alignment] += [:default] * (columns - table.options[:alignment].length)
|
||||
end
|
||||
|
||||
@tree.children << table
|
||||
|
||||
true
|
||||
end
|
||||
define_parser(:table, TABLE_START)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class Kramdown
|
||||
|
||||
TYPOGRAPHIC_SYMS = [['---', :mdash], ['--', :ndash], ['...', :hellip],
|
||||
['\\<<', '<<'], ['\\>>', '>>'],
|
||||
['<< ', :laquo_space], [' >>', :raquo_space],
|
||||
['<<', :laquo], ['>>', :raquo]]
|
||||
TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten]
|
||||
TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k,v| Regexp.escape(k)}.join('|')}/
|
||||
|
||||
# Parse the typographic symbols at the current location.
|
||||
def parse_typographic_syms
|
||||
@src.pos += @src.matched_size
|
||||
val = TYPOGRAPHIC_SYMS_SUBST[@src.matched]
|
||||
if val.kind_of?(Symbol)
|
||||
@tree.children << Element.new(:typographic_sym, val)
|
||||
elsif @src.matched == '\\<<'
|
||||
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'))
|
||||
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'))
|
||||
else
|
||||
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'))
|
||||
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'))
|
||||
end
|
||||
end
|
||||
define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
36
vim/plugin/vim-markdown-preview/kramdown/utils.rb
Executable file
36
vim/plugin/vim-markdown-preview/kramdown/utils.rb
Executable file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
# == Utils Module
|
||||
#
|
||||
# This module contains utility class/modules/methods that can be used by both parsers and
|
||||
# converters.
|
||||
module Utils
|
||||
|
||||
autoload :Entities, 'kramdown/utils/entities'
|
||||
autoload :HTML, 'kramdown/utils/html'
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
338
vim/plugin/vim-markdown-preview/kramdown/utils/entities.rb
Executable file
338
vim/plugin/vim-markdown-preview/kramdown/utils/entities.rb
Executable file
@@ -0,0 +1,338 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Utils
|
||||
|
||||
module Entities
|
||||
|
||||
class Entity < Struct.new(:code_point, :name)
|
||||
|
||||
def char
|
||||
[code_point].pack('U*') rescue nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ENTITY_TABLE = [
|
||||
[913, 'Alpha'],
|
||||
[914, 'Beta'],
|
||||
[915, 'Gamma'],
|
||||
[916, 'Delta'],
|
||||
[917, 'Epsilon'],
|
||||
[918, 'Zeta'],
|
||||
[919, 'Eta'],
|
||||
[920, 'Theta'],
|
||||
[921, 'Iota'],
|
||||
[922, 'Kappa'],
|
||||
[923, 'Lambda'],
|
||||
[924, 'Mu'],
|
||||
[925, 'Nu'],
|
||||
[926, 'Xi'],
|
||||
[927, 'Omicron'],
|
||||
[928, 'Pi'],
|
||||
[929, 'Rho'],
|
||||
[931, 'Sigma'],
|
||||
[932, 'Tau'],
|
||||
[933, 'Upsilon'],
|
||||
[934, 'Phi'],
|
||||
[935, 'Chi'],
|
||||
[936, 'Psi'],
|
||||
[937, 'Omega'],
|
||||
[945, 'alpha'],
|
||||
[946, 'beta'],
|
||||
[947, 'gamma'],
|
||||
[948, 'delta'],
|
||||
[949, 'epsilon'],
|
||||
[950, 'zeta'],
|
||||
[951, 'eta'],
|
||||
[952, 'theta'],
|
||||
[953, 'iota'],
|
||||
[954, 'kappa'],
|
||||
[955, 'lambda'],
|
||||
[956, 'mu'],
|
||||
[957, 'nu'],
|
||||
[958, 'xi'],
|
||||
[959, 'omicron'],
|
||||
[960, 'pi'],
|
||||
[961, 'rho'],
|
||||
[963, 'sigma'],
|
||||
[964, 'tau'],
|
||||
[965, 'upsilon'],
|
||||
[966, 'phi'],
|
||||
[967, 'chi'],
|
||||
[968, 'psi'],
|
||||
[969, 'omega'],
|
||||
[962, 'sigmaf'],
|
||||
[977, 'thetasym'],
|
||||
[982, 'piv'],
|
||||
[8230, 'hellip'],
|
||||
[8242, 'prime'],
|
||||
[8254, 'oline'],
|
||||
[8260, 'frasl'],
|
||||
[8472, 'weierp'],
|
||||
[8465, 'image'],
|
||||
[8476, 'real'],
|
||||
[8501, 'alefsym'],
|
||||
[8226, 'bull'],
|
||||
[8482, 'trade'],
|
||||
[8592, 'larr'],
|
||||
[8594, 'rarr'],
|
||||
[8593, 'uarr'],
|
||||
[8595, 'darr'],
|
||||
[8596, 'harr'],
|
||||
[8629, 'crarr'],
|
||||
[8657, 'uArr'],
|
||||
[8659, 'dArr'],
|
||||
[8656, 'lArr'],
|
||||
[8658, 'rArr'],
|
||||
[8660, 'hArr'],
|
||||
[8704, 'forall'],
|
||||
[8706, 'part'],
|
||||
[8707, 'exist'],
|
||||
[8709, 'empty'],
|
||||
[8711, 'nabla'],
|
||||
[8712, 'isin'],
|
||||
[8715, 'ni'],
|
||||
[8713, 'notin'],
|
||||
[8721, 'sum'],
|
||||
[8719, 'prod'],
|
||||
[8722, 'minus'],
|
||||
[8727, 'lowast'],
|
||||
[8730, 'radic'],
|
||||
[8733, 'prop'],
|
||||
[8734, 'infin'],
|
||||
[8736, 'ang'],
|
||||
[8743, 'and'],
|
||||
[8744, 'or'],
|
||||
[8745, 'cup'],
|
||||
[8746, 'cap'],
|
||||
[8747, 'int'],
|
||||
[8756, 'there4'],
|
||||
[8764, 'sim'],
|
||||
[8776, 'asymp'],
|
||||
[8773, 'cong'],
|
||||
[8800, 'ne'],
|
||||
[8801, 'equiv'],
|
||||
[8804, 'le'],
|
||||
[8805, 'ge'],
|
||||
[8834, 'sub'],
|
||||
[8835, 'sup'],
|
||||
[8838, 'sube'],
|
||||
[8839, 'supe'],
|
||||
[8836, 'nsub'],
|
||||
[8853, 'oplus'],
|
||||
[8855, 'otimes'],
|
||||
[8869, 'perp'],
|
||||
[8901, 'sdot'],
|
||||
[8968, 'rceil'],
|
||||
[8969, 'lceil'],
|
||||
[8970, 'lfloor'],
|
||||
[8971, 'rfloor'],
|
||||
[9001, 'rang'],
|
||||
[9002, 'lang'],
|
||||
[9674, 'loz'],
|
||||
[9824, 'spades'],
|
||||
[9827, 'clubs'],
|
||||
[9829, 'hearts'],
|
||||
[9830, 'diams'],
|
||||
[38, 'amp'],
|
||||
[34, 'quot'],
|
||||
[39, 'apos'],
|
||||
[169, 'copy'],
|
||||
[60, 'lt'],
|
||||
[62, 'gt'],
|
||||
[338, 'OElig'],
|
||||
[339, 'oelig'],
|
||||
[352, 'Scaron'],
|
||||
[353, 'scaron'],
|
||||
[376, 'Yuml'],
|
||||
[710, 'circ'],
|
||||
[732, 'tilde'],
|
||||
[8211, 'ndash'],
|
||||
[8212, 'mdash'],
|
||||
[8216, 'lsquo'],
|
||||
[8217, 'rsquo'],
|
||||
[8220, 'ldquo'],
|
||||
[8221, 'rdquo'],
|
||||
[8224, 'dagger'],
|
||||
[8225, 'Dagger'],
|
||||
[8240, 'permil'],
|
||||
[8364, 'euro'],
|
||||
[8249, 'lsaquo'],
|
||||
[8250, 'rsaquo'],
|
||||
[160, 'nbsp'],
|
||||
[161, 'iexcl'],
|
||||
[163, 'pound'],
|
||||
[164, 'curren'],
|
||||
[165, 'yen'],
|
||||
[166, 'brvbar'],
|
||||
[167, 'sect'],
|
||||
[171, 'laquo'],
|
||||
[187, 'raquo'],
|
||||
[174, 'reg'],
|
||||
[170, 'ordf'],
|
||||
[172, 'not'],
|
||||
[176, 'deg'],
|
||||
[177, 'plusmn'],
|
||||
[180, 'acute'],
|
||||
[181, 'micro'],
|
||||
[182, 'para'],
|
||||
[183, 'middot'],
|
||||
[186, 'ordm'],
|
||||
[162, 'cent'],
|
||||
[185, 'sup1'],
|
||||
[178, 'sup2'],
|
||||
[179, 'sup3'],
|
||||
[189, 'frac12'],
|
||||
[188, 'frac14'],
|
||||
[190, 'frac34'],
|
||||
[192, 'Agrave'],
|
||||
[193, 'Aacute'],
|
||||
[194, 'Acirc'],
|
||||
[195, 'Atilde'],
|
||||
[196, 'Auml'],
|
||||
[197, 'Aring'],
|
||||
[198, 'AElig'],
|
||||
[199, 'Ccedil'],
|
||||
[200, 'Egrave'],
|
||||
[201, 'Eacute'],
|
||||
[202, 'Ecirc'],
|
||||
[203, 'Euml'],
|
||||
[204, 'Igrave'],
|
||||
[205, 'Iacute'],
|
||||
[206, 'Icirc'],
|
||||
[207, 'Iuml'],
|
||||
[208, 'ETH'],
|
||||
[209, 'Ntilde'],
|
||||
[210, 'Ograve'],
|
||||
[211, 'Oacute'],
|
||||
[212, 'Ocirc'],
|
||||
[213, 'Otilde'],
|
||||
[214, 'Ouml'],
|
||||
[215, 'times'],
|
||||
[216, 'Oslash'],
|
||||
[217, 'Ugrave'],
|
||||
[218, 'Uacute'],
|
||||
[219, 'Ucirc'],
|
||||
[220, 'Uuml'],
|
||||
[221, 'Yacute'],
|
||||
[222, 'THORN'],
|
||||
[223, 'szlig'],
|
||||
[224, 'agrave'],
|
||||
[225, 'aacute'],
|
||||
[226, 'acirc'],
|
||||
[227, 'atilde'],
|
||||
[228, 'auml'],
|
||||
[229, 'aring'],
|
||||
[230, 'aelig'],
|
||||
[231, 'ccedil'],
|
||||
[232, 'egrave'],
|
||||
[233, 'eacute'],
|
||||
[234, 'ecirc'],
|
||||
[235, 'euml'],
|
||||
[236, 'igrave'],
|
||||
[237, 'iacute'],
|
||||
[238, 'icirc'],
|
||||
[239, 'iuml'],
|
||||
[240, 'eth'],
|
||||
[241, 'ntilde'],
|
||||
[242, 'ograve'],
|
||||
[243, 'oacute'],
|
||||
[244, 'ocirc'],
|
||||
[245, 'otilde'],
|
||||
[246, 'ouml'],
|
||||
[247, 'divide'],
|
||||
[248, 'oslash'],
|
||||
[249, 'ugrave'],
|
||||
[250, 'uacute'],
|
||||
[251, 'ucirc'],
|
||||
[252, 'uuml'],
|
||||
[253, 'yacute'],
|
||||
[254, 'thorn'],
|
||||
[255, 'yuml'],
|
||||
|
||||
[8218, 'sbquo'],
|
||||
[402, 'fnof'],
|
||||
[8222, 'bdquo'],
|
||||
[381, 'Zcaron'],
|
||||
[382, 'zcaron'],
|
||||
|
||||
[128, 8364],
|
||||
[130, 8218],
|
||||
[131, 402],
|
||||
[132, 8222],
|
||||
[133, 8230],
|
||||
[134, 8224],
|
||||
[135, 8225],
|
||||
[136, 710],
|
||||
[137, 8240],
|
||||
[138, 352],
|
||||
[139, 8249],
|
||||
[140, 338],
|
||||
[142, 381],
|
||||
[145, 8216],
|
||||
[146, 8217],
|
||||
[147, 8220],
|
||||
[148, 8221],
|
||||
[149, 8226],
|
||||
[150, 8211],
|
||||
[151, 8212],
|
||||
[152, 732],
|
||||
[153, 8482],
|
||||
[154, 353],
|
||||
[155, 8250],
|
||||
[156, 339],
|
||||
[158, 382],
|
||||
[159, 376],
|
||||
]
|
||||
ENTITY_MAP = Hash.new do |h,k|
|
||||
if k.kind_of?(Integer)
|
||||
h[k] = Entity.new(k, nil)
|
||||
else
|
||||
raise Kramdown::Error, "Can't handle generic non-integer character reference '#{k}'"
|
||||
end
|
||||
end
|
||||
|
||||
ENTITY_TABLE.each do |code_point, data|
|
||||
if data.kind_of?(String)
|
||||
ENTITY_MAP[code_point] = ENTITY_MAP[data] = Entity.new(code_point, data)
|
||||
else
|
||||
raise "No entity object for code point #{data} found" unless ENTITY_MAP.has_key?(data)
|
||||
ENTITY_MAP[code_point] = ENTITY_MAP[data]
|
||||
end
|
||||
end
|
||||
|
||||
# Return the entity for the given +point_or_name+.
|
||||
def entity(point_or_name)
|
||||
ENTITY_MAP[point_or_name]
|
||||
end
|
||||
|
||||
module_function :entity
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
72
vim/plugin/vim-markdown-preview/kramdown/utils/html.rb
Executable file
72
vim/plugin/vim-markdown-preview/kramdown/utils/html.rb
Executable file
@@ -0,0 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
module Utils
|
||||
|
||||
module HTML
|
||||
|
||||
# Convert the +entity+ to a string.
|
||||
def entity_to_str(e)
|
||||
if RUBY_VERSION >= '1.9' && (c = e.char.encode(@doc.parse_infos[:encoding]) rescue nil) && !ESCAPE_MAP.has_key?(c)
|
||||
c
|
||||
elsif @doc.options[:numeric_entities] || e.name.nil?
|
||||
"&##{e.code_point};"
|
||||
else
|
||||
"&#{e.name};"
|
||||
end
|
||||
end
|
||||
|
||||
# Return the string with the attributes of the element +el+.
|
||||
def html_attributes(el)
|
||||
(el.options[:attr] || {}).map {|k,v| v.nil? ? '' : " #{k}=\"#{escape_html(v.to_s, :no_entities)}\"" }.sort.join('')
|
||||
end
|
||||
|
||||
ESCAPE_MAP = {
|
||||
'<' => '<',
|
||||
'>' => '>',
|
||||
'&' => '&',
|
||||
'"' => '"'
|
||||
}
|
||||
ESCAPE_ALL_RE = Regexp.union(*ESCAPE_MAP.collect {|k,v| k})
|
||||
ESCAPE_NO_ENTITIES_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, ESCAPE_ALL_RE)
|
||||
ESCAPE_NORMAL = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&/)
|
||||
ESCAPE_RE_FROM_TYPE = {
|
||||
:all => ESCAPE_ALL_RE,
|
||||
:no_entities => ESCAPE_NO_ENTITIES_RE,
|
||||
:text => ESCAPE_NORMAL
|
||||
}
|
||||
|
||||
# Escape the special HTML characters in the string +str+. The parameter +type+ specifies what
|
||||
# is escaped: <tt>:all</tt> - all special HTML characters as well as entities,
|
||||
# <tt>:no_entities</tt> - all special HTML characters but no entities, <tt>:text</tt> - all
|
||||
# special HTML characters except the quotation mark but no entities.
|
||||
def escape_html(str, type = :all)
|
||||
str.gsub(ESCAPE_RE_FROM_TYPE[type]) {|m| ESCAPE_MAP[m] || m}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
28
vim/plugin/vim-markdown-preview/kramdown/version.rb
Executable file
28
vim/plugin/vim-markdown-preview/kramdown/version.rb
Executable file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2009-2010 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown.
|
||||
#
|
||||
# kramdown is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
|
||||
# The kramdown version.
|
||||
VERSION = '0.9.0'
|
||||
|
||||
end
|
||||
44
vim/plugin/vim-markdown-preview/stylesheets/github.css
Executable file
44
vim/plugin/vim-markdown-preview/stylesheets/github.css
Executable file
@@ -0,0 +1,44 @@
|
||||
body div#container {
|
||||
margin : 0 auto;
|
||||
max-width : 920px;
|
||||
background-color : #f8f8f8;
|
||||
padding : .7em;
|
||||
font-size : 13.34px;
|
||||
font-family : verdana, sans-serif;
|
||||
border : 1px #E0E0E0 solid;
|
||||
}
|
||||
|
||||
body div#container h2, body div#container h3, body div#content h4 {
|
||||
padding-top : 10px;
|
||||
border-top : 4px solid #E0E0E0;
|
||||
}
|
||||
|
||||
body div#container pre {
|
||||
padding : 5px;
|
||||
border-style : solid;
|
||||
border-width : 1px;
|
||||
border-color : #E0E0E0;
|
||||
background-color : #F8F8FF;
|
||||
}
|
||||
|
||||
body div#container pre code {
|
||||
padding : 5px;
|
||||
background-color : #F8F8FF;
|
||||
border : none;
|
||||
}
|
||||
|
||||
body div#container code {
|
||||
font-family : courier, fixed;
|
||||
display : inline-block;
|
||||
padding : 0px 2px 0px 2px;
|
||||
background-color : #F8F8FF;
|
||||
border : 1px #E0E0E0 solid;
|
||||
}
|
||||
|
||||
body h4#title {
|
||||
font-family : verdana, sans-serif;
|
||||
display : block;
|
||||
margin : 0 auto;
|
||||
width : 920px;
|
||||
}
|
||||
|
||||
487
vim/plugin/vim-markdown-preview/stylesheets/safari-reader.css
Executable file
487
vim/plugin/vim-markdown-preview/stylesheets/safari-reader.css
Executable file
@@ -0,0 +1,487 @@
|
||||
@media print {
|
||||
/* print.css from blueprint CSS framework */
|
||||
.page {
|
||||
margin-left: 0.1in;
|
||||
margin-right: 0.1in;
|
||||
margin-top: 2in;
|
||||
}
|
||||
body {
|
||||
line-height:1.5;
|
||||
font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-family: Georgia, Times, serif;
|
||||
color:#000;
|
||||
background:none;
|
||||
font-size:12pt;
|
||||
}
|
||||
.container {
|
||||
background:none;
|
||||
}
|
||||
hr {
|
||||
background:#ccc;
|
||||
color:#ccc;
|
||||
width:100%;
|
||||
height:2px;
|
||||
margin:2em 0;
|
||||
padding:0;
|
||||
border:none;
|
||||
}
|
||||
hr.space {
|
||||
background:#fff;
|
||||
color:#fff;
|
||||
visibility:hidden;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;
|
||||
}
|
||||
code {
|
||||
font:.9em "Courier New", Monaco, Courier, monospace;
|
||||
}
|
||||
pre {
|
||||
line-height:0.8;
|
||||
}
|
||||
a img {
|
||||
border:none;
|
||||
}
|
||||
p img.top {
|
||||
margin-top:0;
|
||||
}
|
||||
blockquote {
|
||||
margin:1.5em;
|
||||
padding:1em;
|
||||
font-style:italic;
|
||||
font-size:.9em;
|
||||
}
|
||||
.small {
|
||||
font-size:.9em;
|
||||
}
|
||||
.large {
|
||||
font-size:1.1em;
|
||||
}
|
||||
.quiet {
|
||||
color:#999;
|
||||
}
|
||||
.hide {display:none;}
|
||||
a:link, a:visited {
|
||||
background:transparent;font-weight:700;text-decoration:underline;
|
||||
}
|
||||
a:link:after, a:visited:after {
|
||||
content:" (" attr(href) ")";font-size:90%;
|
||||
}
|
||||
table {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen {
|
||||
/* screen.css from Safari Reader */
|
||||
h1.title {
|
||||
font-family: Palatino, Georgia, Times, "Times New Roman", serif;
|
||||
font-weight: bold;
|
||||
font-size: 1.33em;
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.125em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.05em;
|
||||
}
|
||||
|
||||
.page a {
|
||||
text-decoration: none;
|
||||
color: rgb(32, 0, 127);
|
||||
}
|
||||
|
||||
.page a:visited {
|
||||
color: rgb(32, 0, 127);
|
||||
}
|
||||
|
||||
#article img {
|
||||
/* Float images to the left, so that text will nicely flow around them. */
|
||||
float: left;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
#article img.reader-image-tiny {
|
||||
/* Don't float very small images -- let them display where they occur in the text. */
|
||||
float: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#article img.reader-image-large {
|
||||
float: none;
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.float {
|
||||
margin: 8px 0;
|
||||
font-size: 65%;
|
||||
line-height: 1.4;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.float.left {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.float.right {
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.float.full-width {
|
||||
float: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page {
|
||||
font: 20px Palatino, Georgia, Times, "Times New Roman", serif;
|
||||
line-height: 160%;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.page:first-of-type .title {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.page table {
|
||||
font-size: 0.9em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.page.rtl table {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: none;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.cached embed, .cached applet, .cached object {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#background {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
-webkit-transform: translateZ(0);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin-left: -431px;
|
||||
left: 50%;
|
||||
width: 862px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#centered {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.preloading #background {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.preloading #centered {
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
.activating #background {
|
||||
-webkit-transition: opacity 0.40s ease-out;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.activating #fade-top {
|
||||
-webkit-animation-name: fadeTopActivationFadeIn;
|
||||
-webkit-animation-duration: 0.40s;
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.activating.skip-transition #fade-top {
|
||||
-webkit-animation: none !important;
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeTopActivationFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
80% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.activating.skip-transition #background {
|
||||
-webkit-transition: none !important;
|
||||
}
|
||||
|
||||
.activating #centered {
|
||||
-webkit-transition: -webkit-transform 0.40s ease-out;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.activating.skip-transition #centered {
|
||||
-webkit-transition: none !important;
|
||||
}
|
||||
|
||||
.deactivating #background {
|
||||
-webkit-transition: opacity 0.40s ease-in;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.deactivating #fade-top {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.deactivating #fade-bottom {
|
||||
-webkit-transition: opacity 0.40s ease-in;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.deactivating #centered {
|
||||
-webkit-transition: -webkit-transform 0.40s ease-in;
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
.deactivating #hud {
|
||||
-webkit-transition: opacity 0.25s ease-in;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
#drop-shadow {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 800px;
|
||||
left: 10px;
|
||||
border-width: 24px 24px;
|
||||
-webkit-border-image: url(safari-resource:/ReaderDropShadow.png) 24 24 24 24 stretch stretch;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
#hud {
|
||||
position: fixed;
|
||||
width: 314px;
|
||||
height: 72px;
|
||||
left: 50%;
|
||||
margin-left: -157px;
|
||||
bottom: 30px;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
-webkit-border-radius: 12px;
|
||||
z-index: 100;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.75s;
|
||||
pointer-events: auto;
|
||||
zoom: reset;
|
||||
}
|
||||
|
||||
#hud button {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
margin: 12px 5px;
|
||||
}
|
||||
|
||||
#hud button:first-of-type {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
#hud button:last-of-type {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
#hud-zoom-out {
|
||||
background: url(safari-resource:/ReaderHUDZoomOutInactive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-zoom-out:active {
|
||||
background: url(safari-resource:/ReaderHUDZoomOutActive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-zoom-in {
|
||||
background: url(safari-resource:/ReaderHUDZoomInInactive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-zoom-in:active {
|
||||
background: url(safari-resource:/ReaderHUDZoomInActive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-mail {
|
||||
background: url(safari-resource:/ReaderHUDMailContentsInactive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-mail:active {
|
||||
background: url(safari-resource:/ReaderHUDMailContentsActive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-print {
|
||||
background: url(safari-resource:/ReaderHUDPrintInactive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-print:active {
|
||||
background: url(safari-resource:/ReaderHUDPrintActive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-exit {
|
||||
background: url(safari-resource:/ReaderHUDCloseInactive.png) no-repeat;
|
||||
}
|
||||
|
||||
#hud-exit:active {
|
||||
background: url(safari-resource:/ReaderHUDCloseActive.png) no-repeat;
|
||||
}
|
||||
|
||||
#article {
|
||||
/* The width of 819px here includes 19px for the WebKit scrollbar's width. */
|
||||
/* The padding-right of 8px separates the scrollbar from the article itself. */
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
left: 34px;
|
||||
width: 819px;
|
||||
padding-right: 8px;
|
||||
overflow: scroll;
|
||||
z-index: 0;
|
||||
outline: none;
|
||||
pointer-events: auto;
|
||||
-webkit-user-select: auto;
|
||||
-webkit-transform: translateZ(0);
|
||||
}
|
||||
|
||||
.article-fade {
|
||||
position: absolute;
|
||||
left: 34px;
|
||||
height: 36px;
|
||||
width: 800px;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#fade-top {
|
||||
top: 0;
|
||||
background: url(safari-resource:/ReaderFadeTop.png) repeat-x;
|
||||
}
|
||||
|
||||
#fade-bottom {
|
||||
bottom: 0;
|
||||
background: url(safari-resource:/ReaderFadeBottom.png) repeat-x;
|
||||
}
|
||||
|
||||
#resize-indicator {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: url(safari-resource:/TopSitesCornerResize.png);
|
||||
}
|
||||
|
||||
.page:only-of-type .page-number {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
display: block;
|
||||
font: bold 11px Helvetica, sans-serif;
|
||||
margin-left: 12px;
|
||||
color: #B2B2B2;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.page:first-of-type {
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.page:last-of-type {
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 658px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10px;
|
||||
padding: 45px 70px;
|
||||
color: black;
|
||||
background: white;
|
||||
border: 1px solid #c3c3c3;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
-webkit-transition: height .5s ease-out;
|
||||
}
|
||||
|
||||
.page.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
#incoming-page-placeholder {
|
||||
height: 30px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#incoming-page-corner {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
#incoming-page-spinner {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
float: right;
|
||||
background: url(safari-resource:/ReaderSpinner.png);
|
||||
}
|
||||
|
||||
#incoming-page-text {
|
||||
float: right;
|
||||
margin-top: 2px;
|
||||
margin-left: 8px;
|
||||
color: #B2B2B2;
|
||||
font: bold 11px Helvetica, sans-serif;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
#next-page-container {
|
||||
position:absolute;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.no-transition {
|
||||
-webkit-transition: none !important;
|
||||
}
|
||||
}
|
||||
50
vim/plugin/vim-markdown-preview/stylesheets/simple-print.css
Executable file
50
vim/plugin/vim-markdown-preview/stylesheets/simple-print.css
Executable file
@@ -0,0 +1,50 @@
|
||||
body {
|
||||
font-size:13px;
|
||||
font-family:verdana, sans-serif;
|
||||
line-height:1.5em;
|
||||
}
|
||||
|
||||
h1 { font-size:1.6em; }
|
||||
h2 { font-size:1.5em; }
|
||||
h3 { font-size:1.4em; font-weight:300; }
|
||||
h4 { font-size:1em; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
margin-top:20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-top:5px;
|
||||
border-top:1px solid #AAA;
|
||||
margin-top:40px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin:15px 15px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding:5px;
|
||||
border:1px solid #EEEEEE;
|
||||
background-color:#F6F6F6;
|
||||
margin:0 25px;
|
||||
}
|
||||
|
||||
pre code {
|
||||
padding:5px;
|
||||
background-color:#F6F6F6;
|
||||
border:none;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family:courier, fixed;
|
||||
display:inline-block;
|
||||
padding:0px 2px 0px 2px;
|
||||
background-color: #F6F6F6;
|
||||
border:1px #E0E0E0 solid;
|
||||
}
|
||||
ul li {
|
||||
margin:2px 0 0 0;
|
||||
}
|
||||
|
||||
96
vim/plugin/vmp.vim
Executable file
96
vim/plugin/vmp.vim
Executable file
@@ -0,0 +1,96 @@
|
||||
|
||||
if !exists('g:VMPoutputformat')
|
||||
let g:VMPoutputformat = 'html'
|
||||
endif
|
||||
|
||||
if !exists('g:VMPoutputdirectory')
|
||||
let g:VMPoutputdirectory = '/tmp'
|
||||
endif
|
||||
|
||||
if !exists('g:VMPhtmlreader')
|
||||
if has('mac')
|
||||
let g:VMPhtmlreader = 'open'
|
||||
elseif has('win32') || has('win64')
|
||||
let g:VMPhtmlreader = 'start'
|
||||
elseif has('unix') && executable('xdg-open')
|
||||
let g:VMPhtmlreader = 'xdg-open'
|
||||
else
|
||||
let g:VMPhtmlreader = ''
|
||||
end
|
||||
endif
|
||||
|
||||
if !exists('g:VMPstylesheet')
|
||||
let g:VMPstylesheet = 'github.css'
|
||||
endif
|
||||
|
||||
|
||||
function! PreviewMKD()
|
||||
|
||||
ruby << RUBY
|
||||
|
||||
runtime = Vim.evaluate('&runtimepath').split(',')
|
||||
runtime.each { |path| $LOAD_PATH.unshift(File.join(path, 'plugin', 'vim-markdown-preview')) }
|
||||
|
||||
css_base = runtime.detect { |path| File.exists? File.join(path, 'plugin', 'vmp.vim') }
|
||||
stylesheet = File.join(css_base, 'plugin', 'vim-markdown-preview', 'stylesheets',
|
||||
Vim.evaluate('g:VMPstylesheet'))
|
||||
name = Vim::Buffer.current.name.nil? ? 'Untitled' : File.basename(Vim::Buffer.current.name)
|
||||
output_dir = Vim.evaluate('g:VMPoutputdirectory')
|
||||
|
||||
|
||||
contents = Array.new(VIM::Buffer.current.count) { |i| VIM::Buffer.current[i + 1] }.join("\n")
|
||||
|
||||
require('kramdown/kramdown')
|
||||
|
||||
layout = <<-LAYOUT
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="#{stylesheet}">
|
||||
</link>
|
||||
|
||||
<title> #{name} </title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
<div id="centered">
|
||||
<div id="article">
|
||||
<div class="page">
|
||||
#{Kramdown::Document.new(contents).to_html}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
LAYOUT
|
||||
|
||||
case Vim.evaluate('g:VMPoutputformat')
|
||||
when 'html'
|
||||
reader = Vim.evaluate('g:VMPhtmlreader')
|
||||
|
||||
if reader == ''
|
||||
Vim.message('No suitable HTML reader found! Please set g:VMPhtmlreader.')
|
||||
else
|
||||
file = File.join(output_dir, name + '.html')
|
||||
File.open(file, 'w') { |f| f.write(layout) }
|
||||
Vim.command("silent ! #{reader} '%s'" % [ file ])
|
||||
Vim.command 'redraw!'
|
||||
end
|
||||
when 'pdf'
|
||||
Vim.message('output format not implemented yet.')
|
||||
else
|
||||
Vim.message('Unrecongized output format! Check g:VMPoutputformat.')
|
||||
end
|
||||
|
||||
RUBY
|
||||
endfunction
|
||||
|
||||
:command! Mm :call PreviewMKD()
|
||||
Reference in New Issue
Block a user