work with NERDTree
[vcscommand.git] / plugin / vcssvn.vim
blob7661701088f82cfba1e7ad6c043b658b553cf679
1 " vim600: set foldmethod=marker:
3 " SVN extension for VCSCommand.
5 " Maintainer:    Bob Hiestand <bob.hiestand@gmail.com>
6 " License:
7 " Copyright (c) Bob Hiestand
9 " Permission is hereby granted, free of charge, to any person obtaining a copy
10 " of this software and associated documentation files (the "Software"), to
11 " deal in the Software without restriction, including without limitation the
12 " rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
13 " sell copies of the Software, and to permit persons to whom the Software is
14 " furnished to do so, subject to the following conditions:
16 " The above copyright notice and this permission notice shall be included in
17 " all copies or substantial portions of the Software.
19 " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 " FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 " IN THE SOFTWARE.
27 " Section: Documentation {{{1
29 " Options documentation: {{{2
31 " VCSCommandSVNExec
32 "   This variable specifies the SVN executable.  If not set, it defaults to
33 "   'svn' executed from the user's executable path.
35 " VCSCommandSVNDiffExt
36 "   This variable, if set, sets the external diff program used by Subversion.
38 " VCSCommandSVNDiffOpt
39 "   This variable, if set, determines the options passed to the svn diff
40 "   command (such as 'u', 'w', or 'b').
42 " Section: Plugin header {{{1
44 if exists('VCSCommandDisableAll')
45         finish
46 endif
48 if v:version < 700
49         echohl WarningMsg|echomsg 'VCSCommand requires at least VIM 7.0'|echohl None
50         finish
51 endif
53 runtime plugin/vcscommand.vim
55 if !executable(VCSCommandGetOption('VCSCommandSVNExec', 'svn'))
56         " SVN is not installed
57         finish
58 endif
60 let s:save_cpo=&cpo
61 set cpo&vim
63 " Section: Variable initialization {{{1
65 let s:svnFunctions = {}
67 " Section: Utility functions {{{1
69 " Function: s:Executable() {{{2
70 " Returns the executable used to invoke git suitable for use in a shell
71 " command.
72 function! s:Executable()
73         return VCSCommandGetOption('VCSCommandSVNExec', 'svn')
74 endfunction
76 " Function: s:DoCommand(cmd, cmdName, statusText, options) {{{2
77 " Wrapper to VCSCommandDoCommand to add the name of the SVN executable to the
78 " command argument.
79 function! s:DoCommand(cmd, cmdName, statusText, options)
80         if VCSCommandGetVCSType(expand('%')) == 'SVN'
81                 let fullCmd = s:Executable() . ' ' . a:cmd
82                 return VCSCommandDoCommand(fullCmd, a:cmdName, a:statusText, a:options)
83         else
84                 throw 'SVN VCSCommand plugin called on non-SVN item.'
85         endif
86 endfunction
88 " Section: VCS function implementations {{{1
90 " Function: s:svnFunctions.Identify(buffer) {{{2
91 function! s:svnFunctions.Identify(buffer)
92         let fileName = resolve(bufname(a:buffer))
93         if isdirectory(fileName)
94                 let directoryName = fileName
95         elseif VCSIsNERDTreeBuffer(a:buffer)
96                 let directoryName = VCSGetNERDTreeBufferName(a:buffer)
97         else
98                 let directoryName = fnamemodify(fileName, ':h')
99         endif
100         if strlen(directoryName) > 0
101                 let svnDir = directoryName . '/.svn'
102         else
103                 let svnDir = '.svn'
104         endif
105         if isdirectory(svnDir)
106                 return 1
107         else
108                 return 0
109         endif
110 endfunction
112 " Function: s:svnFunctions.Add() {{{2
113 function! s:svnFunctions.Add(argList)
114         return s:DoCommand(join(['add'] + a:argList, ' '), 'add', join(a:argList, ' '), {})
115 endfunction
117 " Function: s:svnFunctions.Annotate(argList) {{{2
118 function! s:svnFunctions.Annotate(argList)
119         if len(a:argList) == 0
120                 if &filetype == 'SVNannotate'
121                         " Perform annotation of the version indicated by the current line.
122                         let caption = matchstr(getline('.'),'\v^\s+\zs\d+')
123                         let options = ' -r' . caption
124                 else
125                         let caption = ''
126                         let options = ''
127                 endif
128         elseif len(a:argList) == 1 && a:argList[0] !~ '^-'
129                 let caption = a:argList[0]
130                 let options = ' -r' . caption
131         else
132                 let caption = join(a:argList, ' ')
133                 let options = ' ' . caption
134         endif
136         return s:DoCommand('blame --non-interactive' . options, 'annotate', caption, {})
137 endfunction
139 " Function: s:svnFunctions.Commit(argList) {{{2
140 function! s:svnFunctions.Commit(argList)
141         let resultBuffer = s:DoCommand('commit --non-interactive -F "' . a:argList[0] . '"', 'commit', '', {})
142         if resultBuffer == 0
143                 echomsg 'No commit needed.'
144         endif
145 endfunction
147 " Function: s:svnFunctions.Delete() {{{2
148 function! s:svnFunctions.Delete(argList)
149         return s:DoCommand(join(['delete --non-interactive'] + a:argList, ' '), 'delete', join(a:argList, ' '), {})
150 endfunction
152 " Function: s:svnFunctions.Diff(argList) {{{2
153 function! s:svnFunctions.Diff(argList)
154         if len(a:argList) == 0
155                 let revOptions = []
156                 let caption = ''
157         elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
158                 let revOptions = ['-r' . join(a:argList, ':')]
159                 let caption = '(' . a:argList[0] . ' : ' . get(a:argList, 1, 'current') . ')'
160         else
161                 " Pass-through
162                 let caption = join(a:argList, ' ')
163                 let revOptions = a:argList
164         endif
166         let svnDiffExt = VCSCommandGetOption('VCSCommandSVNDiffExt', '')
167         if svnDiffExt == ''
168                 let diffExt = []
169         else
170                 let diffExt = ['--diff-cmd ' . svnDiffExt]
171         endif
173         let svnDiffOpt = VCSCommandGetOption('VCSCommandSVNDiffOpt', '')
174         if svnDiffOpt == ''
175                 let diffOptions = []
176         else
177                 let diffOptions = ['-x -' . svnDiffOpt]
178         endif
180         return s:DoCommand(join(['diff --non-interactive'] + diffExt + diffOptions + revOptions), 'diff', caption, {})
181 endfunction
183 " Function: s:svnFunctions.GetBufferInfo() {{{2
184 " Provides version control details for the current file.  Current version
185 " number and current repository version number are required to be returned by
186 " the vcscommand plugin.
187 " Returns: List of results:  [revision, repository, branch]
189 function! s:svnFunctions.GetBufferInfo()
190         let originalBuffer = VCSCommandGetOriginalBuffer(bufnr('%'))
191         let fileName = bufname(originalBuffer)
192         let statusText = s:VCSCommandUtility.system(s:Executable() . ' status --non-interactive -vu -- "' . fileName . '"')
193         if(v:shell_error)
194                 return []
195         endif
197         " File not under SVN control.
198         if statusText =~ '^?'
199                 return ['Unknown']
200         endif
202         let [flags, revision, repository] = matchlist(statusText, '^\(.\{9}\)\s*\(\d\+\)\s\+\(\d\+\)')[1:3]
203         if revision == ''
204                 " Error
205                 return ['Unknown']
206         elseif flags =~ '^A'
207                 return ['New', 'New']
208         elseif flags =~ '*'
209                 return [revision, repository, '*']
210         else
211                 return [revision, repository]
212         endif
213 endfunction
215 " Function: s:svnFunctions.Info(argList) {{{2
216 function! s:svnFunctions.Info(argList)
217         return s:DoCommand(join(['info --non-interactive'] + a:argList, ' '), 'info', join(a:argList, ' '), {})
218 endfunction
220 " Function: s:svnFunctions.Lock(argList) {{{2
221 function! s:svnFunctions.Lock(argList)
222         return s:DoCommand(join(['lock --non-interactive'] + a:argList, ' '), 'lock', join(a:argList, ' '), {})
223 endfunction
225 " Function: s:svnFunctions.Log(argList) {{{2
226 function! s:svnFunctions.Log(argList)
227         if len(a:argList) == 0
228                 let options = []
229                 let caption = ''
230         elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
231                 let options = ['-r' . join(a:argList, ':')]
232                 let caption = options[0]
233         else
234                 " Pass-through
235                 let options = a:argList
236                 let caption = join(a:argList, ' ')
237         endif
239         let resultBuffer = s:DoCommand(join(['log --non-interactive', '-v'] + options), 'log', caption, {})
240         return resultBuffer
241 endfunction
243 " Function: s:svnFunctions.Revert(argList) {{{2
244 function! s:svnFunctions.Revert(argList)
245         return s:DoCommand('revert', 'revert', '', {})
246 endfunction
248 " Function: s:svnFunctions.Review(argList) {{{2
249 function! s:svnFunctions.Review(argList)
250         if len(a:argList) == 0
251                 let versiontag = '(current)'
252                 let versionOption = ''
253         else
254                 let versiontag = a:argList[0]
255                 let versionOption = ' -r ' . versiontag . ' '
256         endif
258         return s:DoCommand('cat --non-interactive' . versionOption, 'review', versiontag, {})
259 endfunction
261 " Function: s:svnFunctions.Status(argList) {{{2
262 function! s:svnFunctions.Status(argList)
263         let options = ['-u', '-v']
264         if len(a:argList) != 0
265                 let options = a:argList
266         endif
267         return s:DoCommand(join(['status --non-interactive'] + options, ' '), 'status', join(options, ' '), {})
268 endfunction
270 " Function: s:svnFunctions.Unlock(argList) {{{2
271 function! s:svnFunctions.Unlock(argList)
272         return s:DoCommand(join(['unlock --non-interactive'] + a:argList, ' '), 'unlock', join(a:argList, ' '), {})
273 endfunction
275 " Function: s:svnFunctions.Update(argList) {{{2
276 function! s:svnFunctions.Update(argList)
277         return s:DoCommand('update --non-interactive', 'update', '', {})
278 endfunction
280 " Annotate setting {{{2
281 let s:svnFunctions.AnnotateSplitRegex = '\s\+\S\+\s\+\S\+ '
283 " Section: Plugin Registration {{{1
284 let s:VCSCommandUtility = VCSCommandRegisterModule('SVN', expand('<sfile>'), s:svnFunctions, [])
286 let &cpo = s:save_cpo