| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | " Language:	xml | 
					
						
							|  |  |  | " Maintainer:	Johannes Zellner <johannes@zellner.org> | 
					
						
							| 
									
										
										
										
											2012-07-25 17:49:10 +02:00
										 |  |  | " Last Change:	2012 Jul 25 | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | " Notes:	1) does not indent pure non-xml code (e.g. embedded scripts) | 
					
						
							|  |  |  | "		2) will be confused by unbalanced tags in comments | 
					
						
							|  |  |  | "		or CDATA sections. | 
					
						
							| 
									
										
										
										
											2010-01-06 20:54:52 +01:00
										 |  |  | "		2009-05-26 patch by Nikolai Weibull | 
					
						
							|  |  |  | " TODO: 	implement pre-like tags, see xml_indent_open / xml_indent_close | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | " Only load this indent file when no other was loaded. | 
					
						
							|  |  |  | if exists("b:did_indent") | 
					
						
							|  |  |  |     finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | let b:did_indent = 1 | 
					
						
							| 
									
										
										
										
											2012-05-18 21:49:28 +02:00
										 |  |  | let s:keepcpo= &cpo | 
					
						
							|  |  |  | set cpo&vim | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | " [-- local settings (must come before aborting the script) --] | 
					
						
							|  |  |  | setlocal indentexpr=XmlIndentGet(v:lnum,1) | 
					
						
							|  |  |  | setlocal indentkeys=o,O,*<Return>,<>>,<<>,/,{,} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if !exists('b:xml_indent_open') | 
					
						
							|  |  |  |     let b:xml_indent_open = '.\{-}<\a' | 
					
						
							|  |  |  |     " pre tag, e.g. <address> | 
					
						
							|  |  |  |     " let b:xml_indent_open = '.\{-}<[/]\@!\(address\)\@!' | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if !exists('b:xml_indent_close') | 
					
						
							|  |  |  |     let b:xml_indent_close = '.\{-}</' | 
					
						
							|  |  |  |     " end pre tag, e.g. </address> | 
					
						
							|  |  |  |     " let b:xml_indent_close = '.\{-}</\(address\)\@!' | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-25 17:49:10 +02:00
										 |  |  | let &cpo = s:keepcpo | 
					
						
							|  |  |  | unlet s:keepcpo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | " [-- finish, if the function already exists --] | 
					
						
							| 
									
										
										
										
											2012-07-25 17:49:10 +02:00
										 |  |  | if exists('*XmlIndentGet') | 
					
						
							|  |  |  |   finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let s:keepcpo= &cpo | 
					
						
							|  |  |  | set cpo&vim | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | fun! <SID>XmlIndentWithPattern(line, pat) | 
					
						
							|  |  |  |     let s = substitute('x'.a:line, a:pat, "\1", 'g') | 
					
						
							|  |  |  |     return strlen(substitute(s, "[^\1].*$", '', '')) | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " [-- check if it's xml --] | 
					
						
							|  |  |  | fun! <SID>XmlIndentSynCheck(lnum) | 
					
						
							|  |  |  |     if '' != &syntax | 
					
						
							|  |  |  | 	let syn1 = synIDattr(synID(a:lnum, 1, 1), 'name') | 
					
						
							|  |  |  | 	let syn2 = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name') | 
					
						
							|  |  |  | 	if '' != syn1 && syn1 !~ 'xml' && '' != syn2 && syn2 !~ 'xml' | 
					
						
							|  |  |  | 	    " don't indent pure non-xml code | 
					
						
							|  |  |  | 	    return 0 | 
					
						
							| 
									
										
										
										
											2010-01-06 20:54:52 +01:00
										 |  |  | 	elseif syn1 =~ '^xmlComment' && syn2 =~ '^xmlComment' | 
					
						
							|  |  |  | 	    " indent comments specially | 
					
						
							|  |  |  | 	    return -1 | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | 	endif | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |     return 1 | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " [-- return the sum of indents of a:lnum --] | 
					
						
							|  |  |  | fun! <SID>XmlIndentSum(lnum, style, add) | 
					
						
							|  |  |  |     let line = getline(a:lnum) | 
					
						
							|  |  |  |     if a:style == match(line, '^\s*</') | 
					
						
							|  |  |  | 	return (&sw * | 
					
						
							|  |  |  | 	\  (<SID>XmlIndentWithPattern(line, b:xml_indent_open) | 
					
						
							|  |  |  | 	\ - <SID>XmlIndentWithPattern(line, b:xml_indent_close) | 
					
						
							|  |  |  | 	\ - <SID>XmlIndentWithPattern(line, '.\{-}/>'))) + a:add | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  | 	return a:add | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fun! XmlIndentGet(lnum, use_syntax_check) | 
					
						
							|  |  |  |     " Find a non-empty line above the current line. | 
					
						
							|  |  |  |     let lnum = prevnonblank(a:lnum - 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     " Hit the start of the file, use zero indent. | 
					
						
							|  |  |  |     if lnum == 0 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if a:use_syntax_check | 
					
						
							| 
									
										
										
										
											2010-01-06 20:54:52 +01:00
										 |  |  | 	let check_lnum = <SID>XmlIndentSynCheck(lnum) | 
					
						
							|  |  |  | 	let check_alnum = <SID>XmlIndentSynCheck(a:lnum) | 
					
						
							|  |  |  | 	if 0 == check_lnum || 0 == check_alnum | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | 	    return indent(a:lnum) | 
					
						
							| 
									
										
										
										
											2010-01-06 20:54:52 +01:00
										 |  |  | 	elseif -1 == check_lnum || -1 == check_alnum | 
					
						
							|  |  |  | 	    return -1 | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | 	endif | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let ind = <SID>XmlIndentSum(lnum, -1, indent(lnum)) | 
					
						
							|  |  |  |     let ind = <SID>XmlIndentSum(a:lnum, 0, ind) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ind | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-18 21:49:28 +02:00
										 |  |  | let &cpo = s:keepcpo | 
					
						
							|  |  |  | unlet s:keepcpo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-13 20:20:40 +00:00
										 |  |  | " vim:ts=8 |