diff --git a/vim/indent/html.vim b/vim/indent/html.vim new file mode 100644 index 0000000..ada5cc3 --- /dev/null +++ b/vim/indent/html.vim @@ -0,0 +1,254 @@ + +" Description: html indenter +" Author: Johannes Zellner +" Last Change: Mo, 05 Jun 2006 22:32:41 CEST +" Restoring 'cpo' and 'ic' added by Bram 2006 May 5 +" Globals: g:html_indent_tags -- indenting tags +" g:html_indent_strict -- inhibit 'O O' elements +" g:html_indent_strict_table -- inhibit 'O -' elements + +" Only load this indent file when no other was loaded. +"if exists("b:did_indent") + "finish +"endif +"let b:did_indent = 1 + +if exists("g:js_indent") + so g:js_indent +else + ru! indent/javascript.vim +endif + +echo "Sourcing html indent" + + +" [-- local settings (must come before aborting the script) --] +setlocal indentexpr=HtmlIndentGetter(v:lnum) +setlocal indentkeys=o,O,*,<>>,{,} + + +if exists('g:html_indent_tags') + unlet g:html_indent_tags +endif + +" [-- helper function to assemble tag list --] +fun! HtmlIndentPush(tag) + if exists('g:html_indent_tags') + let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag + else + let g:html_indent_tags = a:tag + endif +endfun + + +" [-- --] +call HtmlIndentPush('a') +call HtmlIndentPush('abbr') +call HtmlIndentPush('acronym') +call HtmlIndentPush('address') +call HtmlIndentPush('b') +call HtmlIndentPush('bdo') +call HtmlIndentPush('big') +call HtmlIndentPush('blockquote') +call HtmlIndentPush('button') +call HtmlIndentPush('caption') +call HtmlIndentPush('center') +call HtmlIndentPush('cite') +call HtmlIndentPush('code') +call HtmlIndentPush('colgroup') +call HtmlIndentPush('del') +call HtmlIndentPush('dfn') +call HtmlIndentPush('dir') +call HtmlIndentPush('div') +call HtmlIndentPush('dl') +call HtmlIndentPush('em') +call HtmlIndentPush('fieldset') +call HtmlIndentPush('font') +call HtmlIndentPush('form') +call HtmlIndentPush('frameset') +call HtmlIndentPush('h1') +call HtmlIndentPush('h2') +call HtmlIndentPush('h3') +call HtmlIndentPush('h4') +call HtmlIndentPush('h5') +call HtmlIndentPush('h6') +call HtmlIndentPush('i') +call HtmlIndentPush('iframe') +call HtmlIndentPush('ins') +call HtmlIndentPush('kbd') +call HtmlIndentPush('label') +call HtmlIndentPush('legend') +call HtmlIndentPush('map') +call HtmlIndentPush('menu') +call HtmlIndentPush('noframes') +call HtmlIndentPush('noscript') +call HtmlIndentPush('object') +call HtmlIndentPush('ol') +call HtmlIndentPush('optgroup') +" call HtmlIndentPush('pre') +call HtmlIndentPush('q') +call HtmlIndentPush('s') +call HtmlIndentPush('samp') +call HtmlIndentPush('script') +call HtmlIndentPush('select') +call HtmlIndentPush('small') +call HtmlIndentPush('span') +call HtmlIndentPush('strong') +call HtmlIndentPush('style') +call HtmlIndentPush('sub') +call HtmlIndentPush('sup') +call HtmlIndentPush('table') +call HtmlIndentPush('textarea') +call HtmlIndentPush('title') +call HtmlIndentPush('tt') +call HtmlIndentPush('u') +call HtmlIndentPush('ul') +call HtmlIndentPush('var') + + +" [-- --] +if !exists('g:html_indent_strict') + call HtmlIndentPush('body') + call HtmlIndentPush('head') + call HtmlIndentPush('html') + call HtmlIndentPush('tbody') +endif + + +" [-- --] +if !exists('g:html_indent_strict_table') + call HtmlIndentPush('th') + call HtmlIndentPush('td') + call HtmlIndentPush('tr') + call HtmlIndentPush('tfoot') + call HtmlIndentPush('thead') +endif + +delfun HtmlIndentPush + +let s:cpo_save = &cpo +set cpo-=C + +" [-- count indent-increasing tags of line a:lnum --] +fun! HtmlIndentOpen(lnum, pattern) + let s = substitute('x'.getline(a:lnum), + \ '.\{-}\(\(<\)\('.a:pattern.'\)\>\)', "\1", 'g') + let s = substitute(s, "[^\1].*$", '', '') + return strlen(s) +endfun + +" [-- count indent-decreasing tags of line a:lnum --] +fun! HtmlIndentClose(lnum, pattern) + let s = substitute('x'.getline(a:lnum), + \ '.\{-}\(\(<\)/\('.a:pattern.'\)\>>\)', "\1", 'g') + let s = substitute(s, "[^\1].*$", '', '') + return strlen(s) +endfun + +" [-- count indent-increasing '{' of (java|css) line a:lnum --] +fun! HtmlIndentOpenAlt(lnum) + return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) +endfun + +" [-- count indent-decreasing '}' of (java|css) line a:lnum --] +fun! HtmlIndentCloseAlt(lnum) + return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) +endfun + +" [-- return the sum of indents respecting the syntax of a:lnum --] +fun! HtmlIndentSum(lnum, style) + if a:style == match(getline(a:lnum), '^\s*') + let open = HtmlIndentOpen(a:lnum, g:html_indent_tags) + let close = HtmlIndentClose(a:lnum, g:html_indent_tags) + if 0 != open || 0 != close + return open - close + endif + endif + endif + if '' != &syntax && + \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && + \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)), 1), 'name') + \ =~ '\(css\|java\).*' + if a:style == match(getline(a:lnum), '^\s*}') + return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) + endif + endif + return 0 +endfun + +fun! HtmlIndentGetter(lnum) + + echo "Grabbing html indent for line: " . a:lnum + " 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 + + let restore_ic = &ic + setlocal ic " ignore case + + " [-- special handling for
: no indenting --]
+    if getline(a:lnum) =~ '\c
' + \ || 0 < searchpair('\c
', '', '\c
', 'nWb') + \ || 0 < searchpair('\c
', '', '\c
', 'nW') + " we're in a line with or inside
 ... 
+ if restore_ic == 0 + setlocal noic + endif + return -1 + endif + + " [-- special handling for : use cindent --] + let js = ', 05 Jun 2006 + " ZDR: This needs to be an AND (we are 'after the start of the pair' AND + " we are 'before the end of the pair'). Otherwise, indentation + " before the start of the script block will be affected; the end of + " the pair will still match if we are before the beginning of the + " pair. + " + if 0 < searchpair(js, '', '', 'nWb') + \ && 0 < searchpair(js, '', '', 'nW') + " we're inside javascript + + if getline(lnum) !~ js && getline(a:lnum) !~ '' + if restore_ic == 0 + setlocal noic + endif + return GetJsIndent(a:lnum) + endif + endif + + if getline(lnum) =~ '\c' + " line before the current line a:lnum contains + " a closing . --> search for line before + " starting
 to restore the indent.
+	let preline = prevnonblank(search('\c
', 'bW') - 1)
+	if preline > 0
+	    if restore_ic == 0
+	      setlocal noic
+	    endif
+	    return indent(preline)
+	endif
+    endif
+
+    let ind = HtmlIndentSum(lnum, -1)
+    let ind = ind + HtmlIndentSum(a:lnum, 0)
+
+    if restore_ic == 0
+	setlocal noic
+    endif
+
+    return indent(lnum) + (&sw * ind)
+endfun
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" [-- EOF /indent/html.vim --]
diff --git a/vim/indent/javascript.vim b/vim/indent/javascript.vim
new file mode 100644
index 0000000..fda205f
--- /dev/null
+++ b/vim/indent/javascript.vim
@@ -0,0 +1,331 @@
+" Vim indent file
+" Language:		JavaScript
+" Author: 		Preston Koprivica (pkopriv2@gmail.com)	
+" URL:
+" Last Change: 	April 30, 2010
+
+" 0. Standard Stuff
+" =================
+
+" Only load one indent script per buffer
+if exists('b:did_indent')
+  finish
+endif
+let b:did_indent = 1
+
+" Set the global log variable 1 = logging enabled, 0 = logging disabled
+if !exists("g:js_indent_log")
+	let g:js_indent_log = 1
+endif
+
+setlocal indentexpr=GetJsIndent(v:lnum)
+setlocal indentkeys=0{,0},o,O,e,!,*
+
+" 1. Variables
+" ============
+
+
+" Inline comments (for anchoring other statements)
+let s:js_line_comment = '\s*\(//.*\)*'
+
+" Simple Objects
+let s:js_object_beg = '[{\[]\s*'
+let s:js_object_end = '^[^][{}]*[}\]][;,]\=\s*'
+
+" Simple control blocks (those not beginngin with "{")
+let s:js_s_cntrl_beg = '^\s*\(\(\(if\|for\|with\|while\)\s*(.*)\)\|\(try\|do\)\)\s*' 		
+let s:js_s_cntrl_mid = '^\s*\(\(\(else\s*if\|catch\)\s*(.*)\)\|\(finally\|else\)\)\s*'
+
+" Multi line control blocks (those beginning with "{")
+let s:js_m_cntrl_beg = s:js_s_cntrl_beg . '\s*{\s*'
+let s:js_m_cntrl_mid = '}\=\s*' . s:js_s_cntrl_mid . '\s*{\s*'
+let s:js_m_cntrl_end = '^[^{]*}\s*\(while\s*(.*)\)\=\s*;\=\s*'
+
+" Multi line declarations & invocations
+let s:js_multi_beg = '([^()]*\s*'
+let s:js_s_multi_end = '^[^()]*)\s*'
+let s:js_m_multi_end = s:js_s_multi_end . '\s*{\s*'
+
+" Multi line invocation
+let s:js_multi_invok_beg = s:js_multi_beg
+let s:js_multi_invok_end = s:js_s_multi_end . '[;,]\{1}\s*'
+
+" Special switch control
+let s:js_s_switch_beg = 'switch\s*(.*)\s*' "Actually not allowed. 
+let s:js_m_switch_beg = s:js_s_switch_beg . '\s*{\s*'
+let s:js_switch_mid = '^.*\(case.*\|default\)\s*:\s*'
+
+" Single line comment (// xxx)
+let s:syn_comment = '\(Comment\|String\)'
+
+" 2. Aux. Functions
+" =================
+
+
+" = Method: GetNonCommentLine
+"
+" Grabs the nearest non-commented line
+function! s:GetNonCommentLine(lnum)
+	let lnum = prevnonblank(a:lnum)
+
+	while lnum > 0
+		if s:IsComment(lnum)
+			let lnum = prevnonblank(lnum - 1)
+		else
+			return lnum
+		endif
+	endwhile
+
+	return lnum
+endfunction
+
+
+
+" = Method: IsInComment
+"
+" Determines whether the specified position is contained in a comment. "Note:
+" This depends on a 
+function! s:IsInComment(lnum, cnum) 
+	return synIDattr(synID(a:lnum, a:cnum, 1), 'name') =~? s:syn_comment
+endfunction
+
+
+
+" = Method: IsComment
+" 
+" Determines whether a line is a comment or not.
+function! s:IsComment(lnum)
+	let line = getline(a:lnum)
+
+	return s:IsInComment(a:lnum, 1) && s:IsInComment(a:lnum, strlen(line)) "Doesn't absolutely work.  Only Probably!
+endfunction
+
+
+
+" = Method: Log
+"
+" Logs a message to the stdout.
+function! s:Log(msg)
+	if g:js_indent_log
+		echo "LOG: " . a:msg
+	endif
+endfunction
+
+
+
+" 3. Indenter
+" ===========
+function! GetJsIndent(lnum)
+	" Grab the first non-comment line prior to this line
+	let pnum = s:GetNonCommentLine(a:lnum-1)
+
+	" First line, start at indent = 0
+	if pnum == 0
+		call s:Log("No, noncomment lines prior to: ")
+		return 0
+	endif
+
+	" Grab the second non-comment line prior to this line
+	let ppnum = s:GetNonCommentLine(pnum-1)
+
+	call s:Log("Line: " . a:lnum)
+	call s:Log("PLine: " . pnum)
+	call s:Log("PPLine: " . ppnum)
+
+	" Grab the lines themselves.
+	let line = getline(a:lnum)
+	let pline = getline(pnum)
+	let ppline = getline(ppnum)
+
+	" Determine the current level of indentation
+	let ind = indent(pnum)
+
+	" Handle: Mutli-Line Block Invocation/Function Declaration
+	" ========================================================
+	if pline =~ s:js_multi_beg . s:js_line_comment . '$'
+		if line !~ s:js_multi_invok_end
+			call s:Log("Pline matched multi invoke/declare")
+			return ind + &sw
+		endif 
+	endif
+
+	if pline =~ s:js_s_multi_end . s:js_line_comment . '$'
+		call s:Log("Pline matched multi end without inline {")
+		if line =~ s:js_object_beg . s:js_line_comment . '$'
+			call s:Log("Line matched object beg")
+			return ind - &sw
+		else
+			call s:Log("line didn't match object beginning")
+			return ind 
+		endif
+	endif
+
+	if pline =~ s:js_m_multi_end . s:js_line_comment . '$'
+		call s:Log("Pline matched multi end with inline {")
+		if line =~ s:js_object_end . s:js_line_comment . '$'
+			call s:Log("Line matched object end")
+			return ind - &sw
+		else
+			call s:Log("Line didn't matched object end")
+			return ind
+		endif
+	endif
+
+	if ppline =~ s:js_s_multi_end . s:js_line_comment . '$' &&
+				\ pline !~ s:js_object_beg . s:js_line_comment . '$'
+		call s:Log("PPLine matched multi invoke/declaration end without inline {")
+		return ind - &sw
+	endif
+
+	" Handle: Multi-Line Invocation
+	" =============================
+	if pline =~ s:js_multi_invok_beg . s:js_line_comment . '$'
+		call s:Log("PLine matched multi line invoke")
+		if line =~ s:js_multi_invok_end . s:js_line_comment . '$'
+			call s:Log("Pline matched multi line invoke end")
+			return ind
+		else 
+			call s:Log("Pline didn't match multi line invoke end")
+			return ind + &sw
+		endif 
+	endif
+
+	if line =~ s:js_multi_invok_end . s:js_line_comment . '$'
+		call s:Log("Pline matched multi invocation end")
+		return ind - &sw
+	endif
+
+
+	" Handle: Switch Control Blocks
+	" =============================
+	if pline =~ s:js_m_switch_beg . s:js_line_comment . '$'
+		call s:Log("PLine matched switch cntrl beginning")
+		return ind
+	endif
+
+	if pline =~ s:js_switch_mid
+		call s:Log("PLine matched switch cntrl mid")
+		if line =~ s:js_switch_mid || line =~ s:js_object_end . s:js_line_comment . '$'
+			call s:Log("Line matched a cntrl mid")
+			return ind
+		else
+			call s:Log("Line didnt match a cntrl mid")
+			return ind + &sw
+		endif 
+	endif
+
+	if line =~ s:js_switch_mid " Doesn't need end anchor
+		call s:Log("Line matched switch cntrl mid")
+		return ind - &sw
+	endif
+
+	" Handle: Single Line Control Blocks
+	" ==========================
+	if pline =~ s:js_s_cntrl_beg . s:js_line_comment . '$'
+		call s:Log("Pline matched single line control beg")
+		if line =~ s:js_s_cntrl_mid. s:js_line_comment . '$' || line =~ s:js_object_beg. s:js_line_comment . '$'
+			call s:Log("Line matched single line control mid")
+			return ind
+		else
+			call s:Log("Line didn't match single line control mid")
+			return ind + &sw
+		endif
+	endif
+
+	if pline =~ s:js_s_cntrl_mid . s:js_line_comment . '$'
+		call s:Log("Pline matched single line control mid")
+		if line =~ s:js_s_cntrl_mid . s:js_line_comment . '$' || line =~ s:js_object_beg . s:js_line_comment . '$' 
+			call s:Log("Line matched single line control mid")
+			return ind
+		else
+			call s:Log("Line didn't match single line control mid")
+			return ind + &sw
+		endif
+	endif
+
+	if line =~ s:js_s_cntrl_mid . s:js_line_comment . '$'
+		call s:Log("Line matched single line control mid")
+		if pline =~ s:js_m_cntrl_end . s:js_line_comment . '$'
+			call s:Log("PLine matched multi line control end")
+			return ind
+		else
+			call s:Log("Pline didn't match object end")
+			return ind - &sw
+		endif
+	endif
+
+	if ( ppline =~ s:js_s_cntrl_beg . s:js_line_comment . '$' || ppline =~ s:js_s_cntrl_mid . s:js_line_comment . '$' ) &&
+				\ pline !~ s:js_object_beg . s:js_line_comment . '$'
+		call s:Log("PPLine matched single line control beg or mid")
+		return ind - &sw
+	endif
+
+
+	" Handle: {}
+	" ==========
+	if line =~ '^[^{]*}' && !s:IsComment(a:lnum) && line !~ '"[^}]*}[^}]*"'
+		call s:Log("Line matched closing bracket")
+
+		" Save the cursor position.
+		let curpos = getpos(".")
+
+		" Set the cursor position to the beginning of the line (default
+		" behavior when using ==)
+		call setpos(".", [0, a:lnum, 1, 0])
+
+		" Search for the opening tag
+		let mnum = searchpair('{', '', '}', 'bW', 
+					\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? s:syn_comment' )
+		
+		"Restore the cursor position
+		call setpos(".", curpos)
+
+		let mind = indent(mnum)
+		let mline = getline(mnum)
+
+		call s:Log("Matched found at: " . mnum)
+
+		if mline =~ s:js_m_multi_end " Fixes multi line invocation
+			call s:Log("MLine matched multi line invocation")
+			return mind - &sw
+		else
+			return mind
+		endif
+	endif
+
+	if pline =~ '{[^}]*$' && pline !~ '"[^{]*{[^{]*"'
+		call s:Log("Pline matched opening {")
+		return ind + &sw
+	endif
+
+	" Handle: []
+	" ==========
+	if line =~ '^[^\[]*\]' && !s:IsComment(a:lnum) && line !~ '"[^\]]*\][^\]]*"'
+		call s:Log("Line matched closing ]")
+		
+		" Save the cursor position.
+		let curpos = getpos(".")
+
+		" Set the cursor position to the beginning of the line (default
+		" behavior when using ==)
+		call setpos(".", [0, a:lnum, 1, 0])
+
+		" Search for the opening tag
+		let mnum = searchpair('\[', '', '\]', 'bW', 
+					\ 'synIDattr(synID(line("."), col("."), 0), "name") =~? s:syn_comment' )
+		
+		"Restore the cursor position
+		call setpos(".", curpos)
+
+		call s:Log("Matched found at: " . mnum)
+		return indent(mnum)
+	endif
+
+	if pline =~ '\[[^\]]*$' && pline !~ '"[^\[]*\[[^\[]*"'
+		call s:Log("Pline matched opening [")
+		return ind + &sw
+	endif
+
+	call s:Log("Line didn't match anything.  Retaining indent")
+	return ind
+endfunction