" allml.vim - useful XML/HTML mappings
" Author: Tim Pope
" $Id: allml.vim,v 1.8 2007/05/13 05:32:01 tpope Exp $
" These are my personal mappings for XML/XHTML editing, particularly with
" dynamic content like PHP/ASP/eRuby. Because they are personal, less effort
" has been put into customizability (if you like these mappings but the lack
" of customizability poses an issue for you, let me know). Examples shown are
" for eRuby.
"
" The table below shows what happens if the binding is pressed on the end of a
" line consisting of "foo".
"
" Mapping Changed to (cursor = ^)
" = foo<%= ^ %>
" + <%= foo^ %>
" - foo<% ^ %>
" _ <% foo^ %>
" ' foo<%# ^ %> (mnemonic: ' is a comment in ASP with VBS)
" " <%# foo^ %>
" ^
" \n^\n
" / Last HTML tag closed (requires Vim 7)
" ! / (Vim 7 allows selection from menu)
" @
" (mnemonic: @ is used for importing in a CSS file)
" #
" $
" (mnemonic: $ is valid in javascript identifiers)
"
" For the bindings that generate HTML tag pairs, in a few cases, attributes
" will be automatically added. For example, script becomes
" O
else
imap ] >O
endif
" <% %>
if &ft == "eruby"
inoremap - <%-%>3hi
inoremap _ I<%A-%>Fs
"let b:surround_45 = "<% \r -%>"
elseif &ft == "cf"
inoremap -
inoremap _
else
imap - >2hi
imap _ IA>Fs
endif
" Comments
if &ft =~ '^asp'
imap ' '>2hi
imap " I'A>Fs
let b:surround_35 = maparg("","i")."' \r ".maparg(">","i")
elseif &ft == "jsp"
inoremap ' %----%>4hi
inoremap " I<%--A--%>Fs
let b:surround_35 = "<%-- \r --%>"
elseif &ft == "cf"
inoremap ' !------>4hi
inoremap " IFs
setlocal commentstring=
let b:surround_35 = ""
elseif &ft == "html" || &ft == "xml" || &ft == "xhtml"
inoremap ' !---->3hi
inoremap " IFs
let b:surround_35 = ""
elseif &ft == "django"
inoremap ' {##}2hi
inoremap " I{#A#}Fs
let b:surround_35 = "{# \r #}"
else
imap ' #>2hi
imap " I#A>Fs
let b:surround_35 = maparg("","i")."# \r ".maparg(">","i")
endif
map eu allmlUrlEncode
map du allmlUrlDecode
map ex allmlXmlEncode
map dx allmlXmlDecode
nmap euu allmlLineUrlEncode
nmap duu allmlLineUrlDecode
nmap exx allmlLineXmlEncode
nmap dxx allmlLineXmlDecode
"if has("spell")
"setlocal spell
"endif
if !exists("b:did_indent")
if s:subtype() == "xml"
runtime! indent/xml.vim
else
runtime! indent/html.vim
endif
endif
" Pet peeve
if exists("g:html_indent_tags") && g:html_indent_tags !~ '\\|p\>'
let g:html_indent_tags = g:html_indent_tags.'\|p\|li'
endif
set indentkeys+=!^F
let b:surround_indent = 1
silent doautocmd User allml
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:allml_doctype_index")
if &ft == 'xhtml' || &ft == 'eruby'
let b:allml_doctype_index = 10
elseif &ft != 'xml'
let b:allml_doctype_index = 7
endif
endif
let index = b:allml_doctype_index - 1
return (index < 0 ? s:repeat("\",-index) : s:repeat("\",index))
endfunction
function! s:stylesheetTag()
if !exists("b:allml_stylesheet_link_tag")
if &ft == "eruby" && expand('%:p') =~ '\'
" This will ultimately be factored into rails.vim
let b:allml_stylesheet_link_tag = "<%= stylesheet_link_tag '\r' %>"
else
let b:allml_stylesheet_link_tag = ""
endif
endif
return s:insertTag(b:allml_stylesheet_link_tag)
endfunction
function! s:javascriptIncludeTag()
if !exists("b:allml_javascript_include_tag")
if &ft == "eruby" && expand('%:p') =~ '\'
" This will ultimately be factored into rails.vim
let b:allml_javascript_include_tag = "<%= jaaaavascript_include_tag :\rdefaults\r %>"
else
let b:allml_javascript_include_tag = ""
endif
endif
return s:insertTag(b:allml_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("\",s:length(after))
endfunction
function! s:htmlEn()
let b:allml_omni = &l:omnifunc
let b:allml_isk = &l:isk
" : is for namespaced xml attributes
setlocal omnifunc=htmlcomplete#CompleteTags isk+=:
return ""
endfunction
function! s:htmlDis()
if exists("b:allml_omni")
let &l:omnifunc = b:allml_omni
unlet b:allml_omni
endif
if exists("b:allml_isk")
let &l:isk = b:allml_isk
unlet b:allml_isk
endif
return ""
endfunction
function! s:subtype()
let top = getline(1)."\n".getline(2)
if (top =~ '' && &ft !~? 'html') || &ft =~? '^\%(xml\|xsd\|xslt\)$'
return "xml"
elseif top =~? '\'
return 'xhtml'
elseif top =~ '[^<]\'
return "html"
elseif &ft == "xhtml" || &ft == "eruby"
return "xhtml"
elseif exists("b:loaded_allml")
return "html"
else
return ""
endif
endfunction
function! s:closetagback()
if s:subtype() == "html"
return ">\"
else
return " />\\\"
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
function! s:UrlEncode(str)
return substitute(a:str,'[^A-Za-z0-9_.-]','\="%".printf("%02X",char2nr(submatch(0)))','g')
endfunction
function! s:UrlDecode(str)
let str = substitute(substitute(substitute(a:str,'%0[Aa]\n$','%0A',''),'%0[Aa]','\n','g'),'+',' ','g')
return substitute(str,'%\(\x\x\)','\=nr2char("0x".submatch(1))','g')
endfunction
let s:entities = "\u00a0nbsp\n\u00a9copy\n\u00ablaquo\n\u00aereg\n\u00b5micro\n\u00b6para\n\u00bbraquo\n\u00dfszlig\n"
function! s:XmlEncode(str)
let str = a:str
let str = substitute(str,'&','\&','g')
let str = substitute(str,'<','\<','g')
let str = substitute(str,'>','\>','g')
let str = substitute(str,'"','\"','g')
if s:subtype() == 'xml'
let str = substitute(str,"'",'\'','g')
elseif s:subtype() =~ 'html'
let changes = s:entities
while changes != ""
let orig = matchstr(changes,'.')
let repl = matchstr(changes,'^.\zs.\{-\}\ze\%(\n\|$\)')
let changes = substitute(changes,'^.\{-\}\%(\n\|$\)','','')
let str = substitute(str,'\M'.orig,'\&'.repl.';','g')
endwhile
endif
return str
endfunction
function! s:XmlDecode(str)
let str = a:str
let changes = s:entities
while changes != ""
let orig = matchstr(changes,'.')
let repl = matchstr(changes,'^.\zs.\{-\}\ze\%(\n\|$\)')
let changes = substitute(changes,'^.\{-\}\%(\n\|$\)','','')
let str = substitute(str,'&'.repl.';',orig == '&' ? '\&' : orig,'g')
endwhile
let str = substitute(str,'\(\d\+\);','\=nr2char(submatch(1))','g')
let str = substitute(str,'\(x\x\+\);','\=nr2char("0".submatch(1))','g')
let str = substitute(str,''',"'",'g')
let str = substitute(str,'"','"','g')
let str = substitute(str,'>','>','g')
let str = substitute(str,'<','<','g')
return substitute(str,'&','\&','g')
endfunction
function! s:opfuncUrlEncode(type)
return s:opfunc("UrlEncode",a:type)
endfunction
function! s:opfuncUrlDecode(type)
return s:opfunc("UrlDecode",a:type)
endfunction
function! s:opfuncXmlEncode(type)
return s:opfunc("XmlEncode",a:type)
endfunction
function! s:opfuncXmlDecode(type)
return s:opfunc("XmlDecode",a:type)
endfunction
function! s:opfunc(algorithm,type)
let sel_save = &selection
let &selection = "inclusive"
let reg_save = @@
if a:type =~ '^\d\+$'
silent exe 'norm! ^v'.a:type.'$hy'
elseif a:type =~ '^.$'
silent exe "normal! `<" . a:type . "`>y"
elseif a:type == 'line'
silent exe "normal! '[V']y"
elseif a:type == 'block'
silent exe "normal! `[\`]y"
else
silent exe "normal! `[v`]y"
endif
let @@ = s:{a:algorithm}(@@)
norm! gvp
let &selection = sel_save
let @@ = reg_save
endfunction
nnoremap allmlUrlEncode :set opfunc=opfuncUrlEncodeg@
vnoremap allmlUrlEncode :call opfuncUrlEncode(visualmode())
nnoremap allmlLineUrlEncode :call opfuncUrlEncode(v:count1)
nnoremap allmlUrlDecode :set opfunc=opfuncUrlDecodeg@
vnoremap allmlUrlDecode :call opfuncUrlDecode(visualmode())
nnoremap allmlLineUrlDecode :call opfuncUrlDecode(v:count1)
nnoremap allmlXmlEncode :set opfunc=opfuncXmlEncodeg@
vnoremap allmlXmlEncode :call opfuncXmlEncode(visualmode())
nnoremap allmlLineXmlEncode :call opfuncXmlEncode(v:count1)
nnoremap