PageRenderTime 48ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/vim/archive/vcscommand/plugin/vcscvs.vim

https://bitbucket.org/omairabdullah/config
Vim Script | 453 lines | 265 code | 54 blank | 134 comment | 52 complexity | 1ca3daaf71877cf56de667925c4c0dca MD5 | raw file
  1. " vim600: set foldmethod=marker:
  2. "
  3. " CVS extension for VCSCommand.
  4. "
  5. " Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
  6. " License:
  7. " Copyright (c) Bob Hiestand
  8. "
  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:
  15. "
  16. " The above copyright notice and this permission notice shall be included in
  17. " all copies or substantial portions of the Software.
  18. "
  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.
  26. "
  27. " Section: Documentation {{{1
  28. "
  29. " Command documentation {{{2
  30. "
  31. " The following commands only apply to files under CVS source control.
  32. "
  33. " CVSEdit Performs "cvs edit" on the current file.
  34. "
  35. " CVSEditors Performs "cvs editors" on the current file.
  36. "
  37. " CVSUnedit Performs "cvs unedit" on the current file.
  38. "
  39. " CVSWatch Takes an argument which must be one of [on|off|add|remove].
  40. " Performs "cvs watch" with the given argument on the current
  41. " file.
  42. "
  43. " CVSWatchers Performs "cvs watchers" on the current file.
  44. "
  45. " CVSWatchAdd Alias for "CVSWatch add"
  46. "
  47. " CVSWatchOn Alias for "CVSWatch on"
  48. "
  49. " CVSWatchOff Alias for "CVSWatch off"
  50. "
  51. " CVSWatchRemove Alias for "CVSWatch remove"
  52. "
  53. " Mapping documentation: {{{2
  54. "
  55. " By default, a mapping is defined for each command. User-provided mappings
  56. " can be used instead by mapping to <Plug>CommandName, for instance:
  57. "
  58. " nnoremap ,ce <Plug>CVSEdit
  59. "
  60. " The default mappings are as follow:
  61. "
  62. " <Leader>ce CVSEdit
  63. " <Leader>cE CVSEditors
  64. " <Leader>ct CVSUnedit
  65. " <Leader>cwv CVSWatchers
  66. " <Leader>cwa CVSWatchAdd
  67. " <Leader>cwn CVSWatchOn
  68. " <Leader>cwf CVSWatchOff
  69. " <Leader>cwr CVSWatchRemove
  70. "
  71. " Options documentation: {{{2
  72. "
  73. " VCSCommandCVSExec
  74. " This variable specifies the CVS executable. If not set, it defaults to
  75. " 'cvs' executed from the user's executable path.
  76. "
  77. " VCSCommandCVSDiffOpt
  78. " This variable, if set, determines the options passed to the cvs diff
  79. " command. If not set, it defaults to 'u'.
  80. " Section: Plugin header {{{1
  81. if exists('VCSCommandDisableAll')
  82. finish
  83. endif
  84. if v:version < 700
  85. echohl WarningMsg|echomsg 'VCSCommand requires at least VIM 7.0'|echohl None
  86. finish
  87. endif
  88. if !exists('g:loaded_VCSCommand')
  89. runtime plugin/vcscommand.vim
  90. endif
  91. if !executable(VCSCommandGetOption('VCSCommandCVSExec', 'cvs'))
  92. " CVS is not installed
  93. finish
  94. endif
  95. let s:save_cpo=&cpo
  96. set cpo&vim
  97. " Section: Variable initialization {{{1
  98. let s:cvsFunctions = {}
  99. " Section: Utility functions {{{1
  100. " Function: s:Executable() {{{2
  101. " Returns the executable used to invoke cvs suitable for use in a shell
  102. " command.
  103. function! s:Executable()
  104. return VCSCommandGetOption('VCSCommandCVSExec', 'cvs')
  105. endfunction
  106. " Function: s:DoCommand(cmd, cmdName, statusText, options) {{{2
  107. " Wrapper to VCSCommandDoCommand to add the name of the CVS executable to the
  108. " command argument.
  109. function! s:DoCommand(cmd, cmdName, statusText, options)
  110. if VCSCommandGetVCSType(expand('%')) == 'CVS'
  111. let fullCmd = s:Executable() . ' ' . a:cmd
  112. let ret = VCSCommandDoCommand(fullCmd, a:cmdName, a:statusText, a:options)
  113. if ret > 0
  114. if getline(line('$')) =~ '^cvs \w\+: closing down connection'
  115. $d
  116. 1
  117. endif
  118. endif
  119. return ret
  120. else
  121. throw 'CVS VCSCommand plugin called on non-CVS item.'
  122. endif
  123. endfunction
  124. " Function: s:GetRevision() {{{2
  125. " Function for retrieving the current buffer's revision number.
  126. " Returns: Revision number or an empty string if an error occurs.
  127. function! s:GetRevision()
  128. if !exists('b:VCSCommandBufferInfo')
  129. let b:VCSCommandBufferInfo = s:cvsFunctions.GetBufferInfo()
  130. endif
  131. if len(b:VCSCommandBufferInfo) > 0
  132. return b:VCSCommandBufferInfo[0]
  133. else
  134. return ''
  135. endif
  136. endfunction
  137. " Section: VCS function implementations {{{1
  138. " Function: s:cvsFunctions.Identify(buffer) {{{2
  139. function! s:cvsFunctions.Identify(buffer)
  140. let fileName = resolve(bufname(a:buffer))
  141. if isdirectory(fileName)
  142. let directoryName = fileName
  143. else
  144. let directoryName = fnamemodify(fileName, ':h')
  145. endif
  146. if strlen(directoryName) > 0
  147. let CVSRoot = directoryName . '/CVS/Root'
  148. else
  149. let CVSRoot = 'CVS/Root'
  150. endif
  151. if filereadable(CVSRoot)
  152. return 1
  153. else
  154. return 0
  155. endif
  156. endfunction
  157. " Function: s:cvsFunctions.Add(argList) {{{2
  158. function! s:cvsFunctions.Add(argList)
  159. return s:DoCommand(join(['add'] + a:argList, ' '), 'add', join(a:argList, ' '), {})
  160. endfunction
  161. " Function: s:cvsFunctions.Annotate(argList) {{{2
  162. function! s:cvsFunctions.Annotate(argList)
  163. if len(a:argList) == 0
  164. if &filetype ==? 'cvsannotate'
  165. " This is a CVSAnnotate buffer. Perform annotation of the version
  166. " indicated by the current line.
  167. let caption = matchstr(getline('.'),'\v^[0-9.]+')
  168. if VCSCommandGetOption('VCSCommandCVSAnnotateParent', 0) != 0
  169. if caption != '1.1'
  170. let revmaj = matchstr(caption,'\v[0-9.]+\ze\.[0-9]+')
  171. let revmin = matchstr(caption,'\v[0-9.]+\.\zs[0-9]+') - 1
  172. if revmin == 0
  173. " Jump to ancestor branch
  174. let caption = matchstr(revmaj,'\v[0-9.]+\ze\.[0-9]+')
  175. else
  176. let caption = revmaj . "." . revmin
  177. endif
  178. endif
  179. endif
  180. let options = ['-r' . caption]
  181. else
  182. " CVS defaults to pulling HEAD, regardless of current branch.
  183. " Therefore, always pass desired revision.
  184. let caption = ''
  185. let options = ['-r' . s:GetRevision()]
  186. endif
  187. elseif len(a:argList) == 1 && a:argList[0] !~ '^-'
  188. let caption = a:argList[0]
  189. let options = ['-r' . caption]
  190. else
  191. let caption = join(a:argList)
  192. let options = a:argList
  193. endif
  194. let resultBuffer = s:DoCommand(join(['-q', 'annotate'] + options), 'annotate', caption, {})
  195. if resultBuffer > 0
  196. " Remove header lines from standard error
  197. silent v/^\d\+\%(\.\d\+\)\+/d
  198. endif
  199. return resultBuffer
  200. endfunction
  201. " Function: s:cvsFunctions.Commit(argList) {{{2
  202. function! s:cvsFunctions.Commit(argList)
  203. let resultBuffer = s:DoCommand('commit -F "' . a:argList[0] . '"', 'commit', '', {})
  204. if resultBuffer == 0
  205. echomsg 'No commit needed.'
  206. endif
  207. return resultBuffer
  208. endfunction
  209. " Function: s:cvsFunctions.Delete() {{{2
  210. " By default, use the -f option to remove the file first. If options are
  211. " passed in, use those instead.
  212. function! s:cvsFunctions.Delete(argList)
  213. let options = ['-f']
  214. let caption = ''
  215. if len(a:argList) > 0
  216. let options = a:argList
  217. let caption = join(a:argList, ' ')
  218. endif
  219. return s:DoCommand(join(['remove'] + options, ' '), 'delete', caption, {})
  220. endfunction
  221. " Function: s:cvsFunctions.Diff(argList) {{{2
  222. function! s:cvsFunctions.Diff(argList)
  223. if len(a:argList) == 0
  224. let revOptions = []
  225. let caption = ''
  226. elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
  227. let revOptions = ['-r' . join(a:argList, ' -r')]
  228. let caption = '(' . a:argList[0] . ' : ' . get(a:argList, 1, 'current') . ')'
  229. else
  230. " Pass-through
  231. let caption = join(a:argList, ' ')
  232. let revOptions = a:argList
  233. endif
  234. let cvsDiffOpt = VCSCommandGetOption('VCSCommandCVSDiffOpt', 'u')
  235. if cvsDiffOpt == ''
  236. let diffOptions = []
  237. else
  238. let diffOptions = ['-' . cvsDiffOpt]
  239. endif
  240. return s:DoCommand(join(['diff'] + diffOptions + revOptions), 'diff', caption, {'allowNonZeroExit': 1})
  241. endfunction
  242. " Function: s:cvsFunctions.GetBufferInfo() {{{2
  243. " Provides version control details for the current file. Current version
  244. " number and current repository version number are required to be returned by
  245. " the vcscommand plugin. This CVS extension adds branch name to the return
  246. " list as well.
  247. " Returns: List of results: [revision, repository, branch]
  248. function! s:cvsFunctions.GetBufferInfo()
  249. let originalBuffer = VCSCommandGetOriginalBuffer(bufnr('%'))
  250. let fileName = bufname(originalBuffer)
  251. if isdirectory(fileName)
  252. let tag = ''
  253. if filereadable(fileName . '/CVS/Tag')
  254. let tagFile = readfile(fileName . '/CVS/Tag')
  255. if len(tagFile) == 1
  256. let tag = substitute(tagFile[0], '^T', '', '')
  257. endif
  258. endif
  259. return [tag]
  260. endif
  261. let realFileName = fnamemodify(resolve(fileName), ':t')
  262. if !filereadable(fileName)
  263. return ['Unknown']
  264. endif
  265. let oldCwd = VCSCommandChangeToCurrentFileDir(fileName)
  266. try
  267. let statusText=s:VCSCommandUtility.system(s:Executable() . ' status -- "' . realFileName . '"')
  268. if(v:shell_error)
  269. return []
  270. endif
  271. let revision=substitute(statusText, '^\_.*Working revision:\s*\(\d\+\%(\.\d\+\)\+\|New file!\)\_.*$', '\1', '')
  272. " We can still be in a CVS-controlled directory without this being a CVS
  273. " file
  274. if match(revision, '^New file!$') >= 0
  275. let revision='New'
  276. elseif match(revision, '^\d\+\.\d\+\%(\.\d\+\.\d\+\)*$') <0
  277. return ['Unknown']
  278. endif
  279. let branch=substitute(statusText, '^\_.*Sticky Tag:\s\+\(\d\+\%(\.\d\+\)\+\|\a[A-Za-z0-9-_]*\|(none)\).*$', '\1', '')
  280. let repository=substitute(statusText, '^\_.*Repository revision:\s*\(\d\+\%(\.\d\+\)\+\|New file!\|No revision control file\)\_.*$', '\1', '')
  281. let repository=substitute(repository, '^New file!\|No revision control file$', 'New', '')
  282. return [revision, repository, branch]
  283. finally
  284. call VCSCommandChdir(oldCwd)
  285. endtry
  286. endfunction
  287. " Function: s:cvsFunctions.Log() {{{2
  288. function! s:cvsFunctions.Log(argList)
  289. if len(a:argList) == 0
  290. let options = []
  291. let caption = ''
  292. elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
  293. let options = ['-r' . join(a:argList, ':')]
  294. let caption = options[0]
  295. else
  296. " Pass-through
  297. let options = a:argList
  298. let caption = join(a:argList, ' ')
  299. endif
  300. return s:DoCommand(join(['log'] + options), 'log', caption, {})
  301. endfunction
  302. " Function: s:cvsFunctions.Revert(argList) {{{2
  303. function! s:cvsFunctions.Revert(argList)
  304. return s:DoCommand('update -C', 'revert', '', {})
  305. endfunction
  306. " Function: s:cvsFunctions.Review(argList) {{{2
  307. function! s:cvsFunctions.Review(argList)
  308. if len(a:argList) == 0
  309. let versiontag = '(current)'
  310. let versionOption = ''
  311. else
  312. let versiontag = a:argList[0]
  313. let versionOption = ' -r ' . versiontag . ' '
  314. endif
  315. return s:DoCommand('-q update -p' . versionOption, 'review', versiontag, {})
  316. endfunction
  317. " Function: s:cvsFunctions.Status(argList) {{{2
  318. function! s:cvsFunctions.Status(argList)
  319. return s:DoCommand(join(['status'] + a:argList, ' '), 'status', join(a:argList, ' '), {})
  320. endfunction
  321. " Function: s:cvsFunctions.Update(argList) {{{2
  322. function! s:cvsFunctions.Update(argList)
  323. return s:DoCommand('update', 'update', '', {})
  324. endfunction
  325. " Section: CVS-specific functions {{{1
  326. " Function: s:CVSEdit() {{{2
  327. function! s:CVSEdit()
  328. return s:DoCommand('edit', 'cvsedit', '', {})
  329. endfunction
  330. " Function: s:CVSEditors() {{{2
  331. function! s:CVSEditors()
  332. return s:DoCommand('editors', 'cvseditors', '', {})
  333. endfunction
  334. " Function: s:CVSUnedit() {{{2
  335. function! s:CVSUnedit()
  336. return s:DoCommand('unedit', 'cvsunedit', '', {})
  337. endfunction
  338. " Function: s:CVSWatch(onoff) {{{2
  339. function! s:CVSWatch(onoff)
  340. if a:onoff !~ '^\c\%(on\|off\|add\|remove\)$'
  341. echoerr 'Argument to CVSWatch must be one of [on|off|add|remove]'
  342. return -1
  343. end
  344. return s:DoCommand('watch ' . tolower(a:onoff), 'cvswatch', '', {})
  345. endfunction
  346. " Function: s:CVSWatchers() {{{2
  347. function! s:CVSWatchers()
  348. return s:DoCommand('watchers', 'cvswatchers', '', {})
  349. endfunction
  350. " Annotate setting {{{2
  351. let s:cvsFunctions.AnnotateSplitRegex = '): '
  352. " Section: Command definitions {{{1
  353. " Section: Primary commands {{{2
  354. com! CVSEdit call s:CVSEdit()
  355. com! CVSEditors call s:CVSEditors()
  356. com! CVSUnedit call s:CVSUnedit()
  357. com! -nargs=1 CVSWatch call s:CVSWatch(<f-args>)
  358. com! CVSWatchAdd call s:CVSWatch('add')
  359. com! CVSWatchOn call s:CVSWatch('on')
  360. com! CVSWatchOff call s:CVSWatch('off')
  361. com! CVSWatchRemove call s:CVSWatch('remove')
  362. com! CVSWatchers call s:CVSWatchers()
  363. " Section: Plugin command mappings {{{1
  364. let s:cvsExtensionMappings = {}
  365. if !exists("no_plugin_maps")
  366. let mappingInfo = [
  367. \['CVSEdit', 'CVSEdit', 'e'],
  368. \['CVSEditors', 'CVSEditors', 'E'],
  369. \['CVSUnedit', 'CVSUnedit', 't'],
  370. \['CVSWatchers', 'CVSWatchers', 'wv'],
  371. \['CVSWatchAdd', 'CVSWatch add', 'wa'],
  372. \['CVSWatchOff', 'CVSWatch off', 'wf'],
  373. \['CVSWatchOn', 'CVSWatch on', 'wn'],
  374. \['CVSWatchRemove', 'CVSWatch remove', 'wr']
  375. \]
  376. for [pluginName, commandText, shortCut] in mappingInfo
  377. execute 'nnoremap <silent> <Plug>' . pluginName . ' :' . commandText . '<CR>'
  378. if !hasmapto('<Plug>' . pluginName)
  379. let s:cvsExtensionMappings[shortCut] = commandText
  380. endif
  381. endfor
  382. endif
  383. " Section: Plugin Registration {{{1
  384. let s:VCSCommandUtility = VCSCommandRegisterModule('CVS', expand('<sfile>'), s:cvsFunctions, s:cvsExtensionMappings)
  385. " Section: Menu items {{{1
  386. for [s:shortcut, s:command] in [
  387. \['CVS.&Edit', '<Plug>CVSEdit'],
  388. \['CVS.Ed&itors', '<Plug>CVSEditors'],
  389. \['CVS.Unedi&t', '<Plug>CVSUnedit'],
  390. \['CVS.&Watchers', '<Plug>CVSWatchers'],
  391. \['CVS.WatchAdd', '<Plug>CVSWatchAdd'],
  392. \['CVS.WatchOn', '<Plug>CVSWatchOn'],
  393. \['CVS.WatchOff', '<Plug>CVSWatchOff'],
  394. \['CVS.WatchRemove', '<Plug>CVSWatchRemove']
  395. \]
  396. call s:VCSCommandUtility.addMenuItem(s:shortcut, s:command)
  397. endfor
  398. unlet s:shortcut s:command
  399. let &cpo = s:save_cpo