| 707 | 1 " ============================================================================= | 
|  | 2 " File:          autoload/ctrlp/undo.vim | 
|  | 3 " Description:   Undo extension | 
|  | 4 " Author:        Kien Nguyen <github.com/kien> | 
|  | 5 " ============================================================================= | 
|  | 6 | 
|  | 7 " Init {{{1 | 
|  | 8 if ( exists('g:loaded_ctrlp_undo') && g:loaded_ctrlp_undo ) | 
|  | 9 	fini | 
|  | 10 en | 
|  | 11 let g:loaded_ctrlp_undo = 1 | 
|  | 12 | 
|  | 13 cal add(g:ctrlp_ext_vars, { | 
|  | 14 	\ 'init': 'ctrlp#undo#init()', | 
|  | 15 	\ 'accept': 'ctrlp#undo#accept', | 
|  | 16 	\ 'lname': 'undo', | 
|  | 17 	\ 'sname': 'udo', | 
|  | 18 	\ 'enter': 'ctrlp#undo#enter()', | 
|  | 19 	\ 'exit': 'ctrlp#undo#exit()', | 
|  | 20 	\ 'type': 'line', | 
|  | 21 	\ 'sort': 0, | 
|  | 22 	\ 'nolim': 1, | 
|  | 23 	\ }) | 
|  | 24 | 
|  | 25 let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) | 
|  | 26 | 
|  | 27 let s:text = map(['second', 'seconds', 'minutes', 'hours', 'days', 'weeks', | 
|  | 28 	\ 'months', 'years'], '" ".v:val." ago"') | 
|  | 29 " Utilities {{{1 | 
|  | 30 fu! s:getundo() | 
|  | 31 	if exists('*undotree') | 
|  | 32 		\ && ( v:version > 703 || ( v:version == 703 && has('patch005') ) ) | 
|  | 33 		retu [1, undotree()] | 
|  | 34 	el | 
|  | 35 		redi => result | 
|  | 36 		sil! undol | 
|  | 37 		redi END | 
|  | 38 		retu [0, split(result, "\n")[1:]] | 
|  | 39 	en | 
|  | 40 endf | 
|  | 41 | 
|  | 42 fu! s:flatten(tree, cur) | 
|  | 43 	let flatdict = {} | 
|  | 44 	for each in a:tree | 
|  | 45 		let saved = has_key(each, 'save') ? 'saved' : '' | 
|  | 46 		let current = each['seq'] == a:cur ? 'current' : '' | 
|  | 47 		cal extend(flatdict, { each['seq'] : [each['time'], saved, current] }) | 
|  | 48 		if has_key(each, 'alt') | 
|  | 49 			cal extend(flatdict, s:flatten(each['alt'], a:cur)) | 
|  | 50 		en | 
|  | 51 	endfo | 
|  | 52 	retu flatdict | 
|  | 53 endf | 
|  | 54 | 
|  | 55 fu! s:elapsed(nr) | 
|  | 56 	let [text, time] = [s:text, localtime() - a:nr] | 
|  | 57 	let mins = time / 60 | 
|  | 58 	let hrs  = time / 3600 | 
|  | 59 	let days = time / 86400 | 
|  | 60 	let wks  = time / 604800 | 
|  | 61 	let mons = time / 2592000 | 
|  | 62 	let yrs  = time / 31536000 | 
|  | 63 	if yrs > 1 | 
|  | 64 		retu yrs.text[7] | 
|  | 65 	elsei mons > 1 | 
|  | 66 		retu mons.text[6] | 
|  | 67 	elsei wks > 1 | 
|  | 68 		retu wks.text[5] | 
|  | 69 	elsei days > 1 | 
|  | 70 		retu days.text[4] | 
|  | 71 	elsei hrs > 1 | 
|  | 72 		retu hrs.text[3] | 
|  | 73 	elsei mins > 1 | 
|  | 74 		retu mins.text[2] | 
|  | 75 	elsei time == 1 | 
|  | 76 		retu time.text[0] | 
|  | 77 	elsei time < 120 | 
|  | 78 		retu time.text[1] | 
|  | 79 	en | 
|  | 80 endf | 
|  | 81 | 
|  | 82 fu! s:syntax() | 
|  | 83 	if ctrlp#nosy() | retu | en | 
|  | 84 	for [ke, va] in items({'T': 'Directory', 'Br': 'Comment', 'Nr': 'String', | 
|  | 85 		\ 'Sv': 'Comment', 'Po': 'Title'}) | 
|  | 86 		cal ctrlp#hicheck('CtrlPUndo'.ke, va) | 
|  | 87 	endfo | 
|  | 88 	sy match CtrlPUndoT '\v\d+ \zs[^ ]+\ze|\d+:\d+:\d+' | 
|  | 89 	sy match CtrlPUndoBr '\[\|\]' | 
|  | 90 	sy match CtrlPUndoNr '\[\d\+\]' contains=CtrlPUndoBr | 
|  | 91 	sy match CtrlPUndoSv 'saved' | 
|  | 92 	sy match CtrlPUndoPo 'current' | 
|  | 93 endf | 
|  | 94 | 
|  | 95 fu! s:dict2list(dict) | 
|  | 96 	for ke in keys(a:dict) | 
|  | 97 		let a:dict[ke][0] = s:elapsed(a:dict[ke][0]) | 
|  | 98 	endfo | 
|  | 99 	retu map(keys(a:dict), 'eval(''[v:val, a:dict[v:val]]'')') | 
|  | 100 endf | 
|  | 101 | 
|  | 102 fu! s:compval(...) | 
|  | 103 	retu a:2[0] - a:1[0] | 
|  | 104 endf | 
|  | 105 | 
|  | 106 fu! s:format(...) | 
|  | 107 	let saved = !empty(a:1[1][1]) ? ' '.a:1[1][1] : '' | 
|  | 108 	let current = !empty(a:1[1][2]) ? ' '.a:1[1][2] : '' | 
|  | 109 	retu a:1[1][0].' ['.a:1[0].']'.saved.current | 
|  | 110 endf | 
|  | 111 | 
|  | 112 fu! s:formatul(...) | 
|  | 113 	let parts = matchlist(a:1, | 
|  | 114 		\ '\v^\s+(\d+)\s+\d+\s+([^ ]+\s?[^ ]+|\d+\s\w+\s\w+)(\s*\d*)$') | 
|  | 115 	retu parts == [] ? '----' | 
|  | 116 		\ : parts[2].' ['.parts[1].']'.( parts[3] != '' ? ' saved' : '' ) | 
|  | 117 endf | 
|  | 118 " Public {{{1 | 
|  | 119 fu! ctrlp#undo#init() | 
|  | 120 	let entries = s:undos[0] ? s:undos[1]['entries'] : s:undos[1] | 
|  | 121 	if empty(entries) | retu [] | en | 
|  | 122 	if !exists('s:lines') | 
|  | 123 		if s:undos[0] | 
|  | 124 			let entries = s:dict2list(s:flatten(entries, s:undos[1]['seq_cur'])) | 
|  | 125 			let s:lines = map(sort(entries, 's:compval'), 's:format(v:val)') | 
|  | 126 		el | 
|  | 127 			let s:lines = map(reverse(entries), 's:formatul(v:val)') | 
|  | 128 		en | 
|  | 129 	en | 
|  | 130 	cal s:syntax() | 
|  | 131 	retu s:lines | 
|  | 132 endf | 
|  | 133 | 
|  | 134 fu! ctrlp#undo#accept(mode, str) | 
|  | 135 	let undon = matchstr(a:str, '\[\zs\d\+\ze\]') | 
|  | 136 	if empty(undon) | retu | en | 
|  | 137 	cal ctrlp#exit() | 
|  | 138 	exe 'u' undon | 
|  | 139 endf | 
|  | 140 | 
|  | 141 fu! ctrlp#undo#id() | 
|  | 142 	retu s:id | 
|  | 143 endf | 
|  | 144 | 
|  | 145 fu! ctrlp#undo#enter() | 
|  | 146 	let s:undos = s:getundo() | 
|  | 147 endf | 
|  | 148 | 
|  | 149 fu! ctrlp#undo#exit() | 
|  | 150 	unl! s:lines | 
|  | 151 endf | 
|  | 152 "}}} | 
|  | 153 | 
|  | 154 " vim:fen:fdm=marker:fmr={{{,}}}:fdl=0:fdc=1:ts=2:sw=2:sts=2 |