| 707 | 1 " ============================================================================= | 
|  | 2 " File:          autoload/ctrlp/autoignore.vim | 
|  | 3 " Description:   Auto-ignore Extension | 
|  | 4 " Author:        Ludovic Chabant <github.com/ludovicchabant> | 
|  | 5 " ============================================================================= | 
|  | 6 | 
|  | 7 | 
|  | 8 " Global Settings {{{ | 
|  | 9 | 
|  | 10 if exists('g:ctrlp_autoignore_loaded') && g:ctrlp_autoignore_loaded | 
|  | 11 		\ && !g:ctrlp_autoignore_debug | 
|  | 12 	finish | 
|  | 13 endif | 
|  | 14 let g:ctrlp_autoignore_loaded = 1 | 
|  | 15 | 
|  | 16 if !exists('g:ctrlp_autoignore_debug') | 
|  | 17 	let g:ctrlp_autoignore_debug = 0 | 
|  | 18 endif | 
|  | 19 | 
|  | 20 if !exists('g:ctrlp_autoignore_trace') | 
|  | 21 	let g:ctrlp_autoignore_trace = 0 | 
|  | 22 endif | 
|  | 23 | 
|  | 24 " }}} | 
|  | 25 | 
|  | 26 " Initialization {{{ | 
|  | 27 | 
|  | 28 if !exists('g:ctrlp_custom_ignore') | 
|  | 29 	let g:ctrlp_custom_ignore = {} | 
|  | 30 endif | 
|  | 31 let g:ctrlp_custom_ignore['func'] = 'ctrlp#autoignore#ignore' | 
|  | 32 let g:ctrlp_custom_ignore['func-init'] = 'ctrlp#autoignore#ignore_init' | 
|  | 33 let g:ctrlp_custom_ignore['func-close'] = 'ctrlp#autoignore#ignore_close' | 
|  | 34 | 
|  | 35 if !exists('g:ctrlp_root_markers') | 
|  | 36 	let g:ctrlp_root_markers = [] | 
|  | 37 endif | 
|  | 38 call add(g:ctrlp_root_markers, '.ctrlpignore') | 
|  | 39 | 
|  | 40 " }}} | 
|  | 41 | 
|  | 42 " Internals {{{ | 
|  | 43 | 
|  | 44 function! s:trace(message) abort | 
|  | 45     if g:ctrlp_autoignore_trace | 
|  | 46         echom "ctrlp_autoignore: " . a:message | 
|  | 47     endif | 
|  | 48 endfunction | 
|  | 49 | 
|  | 50 let s:proj_cache = {} | 
|  | 51 let s:active_cwd = '' | 
|  | 52 let s:active_cwd_len = 0 | 
|  | 53 let s:active_patterns = [] | 
|  | 54 let s:changed_wildignore = 0 | 
|  | 55 let s:prev_wildignore = '' | 
|  | 56 | 
|  | 57 function! s:load_project_patterns(root_dir) abort | 
|  | 58 	let l:ign_path = a:root_dir . '/.ctrlpignore' | 
|  | 59 	if !filereadable(l:ign_path) | 
|  | 60 		call s:trace("No pattern file at: " . l:ign_path) | 
|  | 61 		return [] | 
|  | 62 	endif | 
|  | 63 	let l:cursyntax = 'regexp' | 
|  | 64 	let l:knownsyntaxes = ['regexp', 'wildignore'] | 
|  | 65 	let l:patterns = [] | 
|  | 66 	let l:lines = readfile(l:ign_path) | 
|  | 67 	for line in l:lines | 
|  | 68 		" Comment line? | 
|  | 69 		if match(line, '\v^\s*$') >= 0 || match(line, '\v^\s*#') >= 0 | 
|  | 70 			continue | 
|  | 71 		endif | 
|  | 72 		" Syntax change? | 
|  | 73 		let l:matches = matchlist(line, '\v^syntax:\s?(\w+)\s*$') | 
|  | 74 		if len(l:matches) > 0 | 
|  | 75 			let l:cursyntax = l:matches[1] | 
|  | 76 			if index(l:knownsyntaxes, l:cursyntax) < 0 | 
|  | 77 				echoerr "ctrlp_autoignore: Unknown syntax '".l:cursyntax."' in: ".l:ign_path | 
|  | 78 			endif | 
|  | 79 			continue | 
|  | 80 		endif | 
|  | 81 		" Patterns! | 
|  | 82 		let l:matches = matchlist(line, '\v^((dir|file|link)\:)?(.*)') | 
|  | 83 		let l:mtype = l:matches[2] | 
|  | 84 		let l:mpat = l:matches[3] | 
|  | 85 		call add(l:patterns, {'syn': l:cursyntax, 'type': l:mtype, 'pat': l:mpat}) | 
|  | 86 	endfor | 
|  | 87 	call s:trace("Loaded " . len(l:patterns) . " patterns from: " . l:ign_path) | 
|  | 88 	return l:patterns | 
|  | 89 endfunction | 
|  | 90 | 
|  | 91 function! s:get_project_patterns(root_dir) abort | 
|  | 92 	let l:ign_path = a:root_dir . '/.ctrlpignore' | 
|  | 93 	let l:ign_mtime = getftime(l:ign_path) | 
|  | 94 	let l:patterns = get(s:proj_cache, a:root_dir) | 
|  | 95 	if type(l:patterns) == type({}) | 
|  | 96 		" Check that these patterns are still valid. | 
|  | 97 		if l:ign_mtime < 0 | 
|  | 98 			" File got deleted! :( | 
|  | 99 			let l:patterns['pats'] = [] | 
|  | 100 			return l:patterns['pats'] | 
|  | 101 		elseif l:ign_mtime <= l:patterns['mtime'] | 
|  | 102 			" File hasn't changed! :) | 
|  | 103 			return l:patterns['pats'] | 
|  | 104 		endif | 
|  | 105 	endif | 
|  | 106 | 
|  | 107 	call s:trace("Loading patterns for project: " . a:root_dir) | 
|  | 108 	let l:loaded = s:load_project_patterns(a:root_dir) | 
|  | 109 	let s:proj_cache[a:root_dir] = { | 
|  | 110 	\'mtime': localtime(), | 
|  | 111 	\'pats': l:loaded} | 
|  | 112 	return l:loaded | 
|  | 113 endfunction | 
|  | 114 | 
|  | 115 " The custom ignore function that CtrlP will be using in addition to | 
|  | 116 " normal pattern-based matching. | 
|  | 117 function! ctrlp#autoignore#ignore(item, type) abort | 
|  | 118 	let l:cnv_item = tr(strpart(a:item, s:active_cwd_len), "\\", "/") | 
|  | 119 	for pat in s:active_patterns | 
|  | 120 		if pat['syn'] != 'regexp' | 
|  | 121 			continue | 
|  | 122 		endif | 
|  | 123 		if pat['type'] == '' || pat['type'] == a:type | 
|  | 124 			if match(l:cnv_item, pat['pat']) >= 0 | 
|  | 125 				call s:trace("Ignoring ".l:cnv_item." because of ".pat['pat']) | 
|  | 126 				return 1 | 
|  | 127 			endif | 
|  | 128 		endif | 
|  | 129 	endfor | 
|  | 130 	return 0 | 
|  | 131 endfunction | 
|  | 132 | 
|  | 133 function! ctrlp#autoignore#ignore_init() abort | 
|  | 134 	let l:root = getcwd() | 
|  | 135 	let s:active_cwd = l:root | 
|  | 136 	" len+1 is for including the next separator after the root. | 
|  | 137 	let s:active_cwd_len = len(l:root) + 1 | 
|  | 138 	let s:active_patterns = s:get_project_patterns(l:root) | 
|  | 139 	call s:trace("Got ".len(s:active_patterns)." patterns for ".l:root) | 
|  | 140 | 
|  | 141 	let s:changed_wildignore = 0 | 
|  | 142 	let s:prev_wildignore = &wildignore | 
|  | 143 	for pat in s:active_patterns | 
|  | 144 		if pat['syn'] == 'wildignore' | 
|  | 145 			execute 'set wildignore+='.pat['pat'] | 
|  | 146 			let s:changed_wildignore = 1 | 
|  | 147 		endif | 
|  | 148 	endfor | 
|  | 149 	if s:changed_wildignore | 
|  | 150 		call s:trace("Set wildignore to ".&wildignore) | 
|  | 151 	endif | 
|  | 152 endfunction | 
|  | 153 | 
|  | 154 function! ctrlp#autoignore#ignore_close() abort | 
|  | 155 	if s:changed_wildignore | 
|  | 156 		execute 'set wildignore='.s:prev_wildignore | 
|  | 157 		let s:prev_wildignore = '' | 
|  | 158 		call s:trace("Set wildignore back to ".&wildignore) | 
|  | 159 	endif | 
|  | 160 endfunction | 
|  | 161 | 
|  | 162 " List patterns for a given project's root. | 
|  | 163 function! ctrlp#autoignore#get_patterns(root_dir) abort | 
|  | 164 	let l:patterns = s:get_project_patterns(a:root_dir) | 
|  | 165 	for pat in l:patterns | 
|  | 166 		let l:prefix = pat['type'] == '' ? '(all)' : pat['type'] | 
|  | 167 		echom l:prefix . ':' . pat['pat'] | 
|  | 168 	endfor | 
|  | 169 endfunction | 
|  | 170 | 
|  | 171 " }}} | 
|  | 172 | 
|  | 173 " vim:fen:fdm=marker:fmr={{{,}}}:fdl=0:fdc=1:ts=2:sw=2:sts=2 |