Vim 5 compatibility.
[profile.git] / .vim / plugin / diffchanges.vim
1 " Filename:      diffchanges.vim
2 " Description:   Shows the changes made to the current buffer in a diff format
3 " Maintainer:    Jeremy Cantrell <jmcantrell@gmail.com>
4 " Last Modified: Fri 2008-02-29 14:17:06 (-0500)
5
6 if v:version < 700
7   finish
8 endif
9
10 if exists("loaded_diffchanges")
11         finish
12 endif
13
14 let loaded_diffchanges = 1
15
16 let g:diffchanges_diff = []
17 let g:diffchanges_patch = []
18 let s:diffchanges_modes = ['diff', 'patch']
19
20 if !exists('g:diffchanges_patch_cmd')
21         let g:diffchanges_patch_cmd = 'diff -u'
22 endif
23
24 " Save settings {{{1
25 let s:save_cpo = &cpo
26 set cpo&vim
27
28 " Mappings {{{1
29 if !hasmapto('<Plug>DiffChangesDiffToggle')
30         nmap <silent> <unique> <leader>dcd <Plug>DiffChangesDiffToggle
31 endif
32
33 if !hasmapto('<Plug>DiffChangesPatchToggle')
34         nmap <silent> <unique> <leader>dcp <Plug>DiffChangesPatchToggle
35 endif
36
37 nnoremap <unique> <script> <Plug>DiffChangesDiffToggle  <SID>DiffChangesDiffToggle
38 nnoremap <unique> <script> <Plug>DiffChangesPatchToggle <SID>DiffChangesPatchToggle
39
40 nnoremap <SID>DiffChangesDiffToggle  :DiffChangesDiffToggle<cr>
41 nnoremap <SID>DiffChangesPatchToggle :DiffChangesPatchToggle<cr>
42
43 command -bar DiffChangesDiffToggle  :call s:DiffChangesToggle('diff')
44 command -bar DiffChangesPatchToggle :call s:DiffChangesToggle('patch')
45
46 nnoremenu <script> &Plugin.&DiffChanges.&Diff\ Toggle  <SID>DiffChangesDiffToggle
47 nnoremenu <script> &Plugin.&DiffChanges.&Patch\ Toggle <SID>DiffChangesPatchToggle
48
49 function! s:DiffChangesToggle(mode) "{{{1
50         if count(s:diffchanges_modes, a:mode) == 0
51                 call s:Warn("Invalid mode '".a:mode."'")
52                 return
53         endif
54         if len(expand('%')) == 0
55                 call s:Warn("Unable to show changes for unsaved buffer")
56                 return
57         endif
58         let [dcm, pair] = s:DiffChangesPair(bufnr('%'))
59         if count(s:diffchanges_modes, dcm) == 0
60                 call s:DiffChangesOn(a:mode)
61         else
62                 call s:DiffChangesOff()
63         endif
64 endfunction
65
66 function! s:DiffChangesOn(mode) "{{{1
67         if count(s:diffchanges_modes, a:mode) == 0
68                 return
69         endif
70         let filename = expand('%')
71         let diffname = tempname()
72         let buforig = bufnr('%')
73         if a:mode == 'diff'
74                 call writefile(readfile(filename, 'b'), diffname, 'b')
75                 let b:diffchanges_savefdm = &fdm
76                 let b:diffchanges_savefdl = &fdl
77                 let save_ft=&ft
78                 diffthis
79                 vert new
80                 let &ft=save_ft
81                 execute '-read '.filename
82                 diffthis
83                 let bufdiff = bufnr('%')
84         elseif a:mode == 'patch'
85                 execute 'silent w! '.diffname
86                 let diff = system(g:diffchanges_patch_cmd.' '.filename.' '.diffname)
87                 call delete(diffname)
88                 if len(diff) == 0
89                         call s:Warn('No changes found')
90                         return
91                 endif
92                 below new
93                 setlocal filetype=diff
94                 setlocal foldmethod=manual
95                 silent 0put=diff
96                 1
97         endif
98         set buftype=nofile
99         let bufname = "Changes made to '".filename."'"
100         silent file `=bufname`
101         autocmd BufUnload <buffer> call s:DiffChangesOff()
102         let bufdiff = bufnr('%')
103         call add(g:diffchanges_{a:mode}, [buforig, bufdiff])
104 endfunction
105
106 function! s:DiffChangesOff() "{{{1
107         let [dcm, pair] = s:DiffChangesPair(bufnr('%'))
108         execute 'autocmd! BufUnload <buffer='.pair[1].'>'
109         execute 'bdelete! '.pair[1]
110         execute bufwinnr(pair[0]).'wincmd w'
111         if dcm == 'diff'
112                 diffoff
113                 let &fdm = b:diffchanges_savefdm
114                 let &fdl = b:diffchanges_savefdl
115         endif
116         let dcp = g:diffchanges_{dcm}
117         call remove(dcp, index(dcp, pair))
118 endfunction
119
120 function! s:DiffChangesPair(buf_num) "{{{1
121         for dcm in s:diffchanges_modes
122                 let pairs = g:diffchanges_{dcm}
123                 for pair in pairs
124                         if count(pair, a:buf_num) > 0
125                                 return [dcm, pair]
126                         endif
127                 endfor
128         endfor
129         return [0, 0]
130 endfunction
131
132 function! s:Warn(message) "{{{1
133         echohl WarningMsg | echo a:message | echohl None
134 endfunction
135
136 function! s:Error(message) "{{{1
137         echohl ErrorMsg | echo a:message | echohl None
138 endfunction
139
140 " Restore settings "{{{1
141 let &cpo = s:save_cpo