" 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 allmlXmlDecode :set opfunc=opfuncXmlDecodeg@ vnoremap allmlXmlDecode :call opfuncXmlDecode(visualmode()) nnoremap allmlLineXmlDecode :call opfuncXmlDecode(v:count1) if exists("g:allml_global_maps") imap H allmlHtmlComplete imap / allmlHtmlComplete map eu allmlUrlEncode map du allmlUrlDecode map ex allmlXmlEncode map dx allmlXmlDecode nmap euu allmlLineUrlEncode nmap duu allmlLineUrlDecode nmap exx allmlLineXmlEncode nmap dxx allmlLineXmlDecode endif