Don't allow to unrecord past the branch point
[vng.git] / integration / vng.vim
blobbbf4fedeb23324ebba3133d00dcba813161c16c3
1 " ==============================================================================
2 "        File: vng.vim
3 "      Author: Srinath Avadhanula (srinathava [AT] gmail [DOT] com)
4 "        Help: vng.vim is a plugin which implements some simple mappings
5 "              to make it easier to use vng, David Roundy's distributed
6 "              revisioning system.
7 "   Copyright: Srinath Avadhanula
8 "     License: Vim Charityware license. (:help uganda)
10 " As of right now, this script provides the following mappings:
12 "       <Plug>VngVertDiffsplit
13 "               This mapping vertically diffsplit's the current window with the
14 "               last recorded version.
16 "               Default map: <leader>dkv
18 "       <Plug>VngIneractiveDiff
19 "               This mapping displays the changes for the current file. The user
20 "               can then choose two revisions from the list using the 'f' (from)
21 "               and 't' (to) keys. After choosing two revisions, the user can press
22 "               'g' at which point, the delta between those two revisions is
23 "               displayed in two veritcally diffsplit'ted windows.
25 "               Default map: <leader>dki
27 "       <Plug>VngStartCommitSession
28 "               This mapping starts an interactive commit console using which the
29 "               user can choose which hunks to include in the record and then also
30 "               write out a patch name and commit message.
32 "               Default map: <leader>dkc
33 " ==============================================================================
35 " ==============================================================================
36 " Main functions
37 " ==============================================================================
38 " Functions related to diffsplitting current file with last recorded {{{
40 nmap <Plug>VngVertDiffsplit :call Vng_DiffSplit()<CR>
41 if !hasmapto('<Plug>VngVertDiffsplit')
42         nmap <unique> <leader>dkv <Plug>VngVertDiffsplit
43 endif
45 " Vng_DiffSplit: diffsplits the current file with last recorded version {{{
46 function! Vng_DiffSplit()
47         let origDir = getcwd()
48         call Vng_CD(expand('%:p:h'))
50         " first find out the location of the repository by searching upwards
51         " from the current directory for a _vng* directory.
52         if Vng_SetVngDirectory() < 0
53         return -1
54     endif
56         " Find out if the current file has any changes.
57         if Vng_System('vng whatsnew '.expand('%')) =~ '\(^\|\n\)No changes'
58                 echomsg "vng says there are no changes"
59                 return 0
60         endif
62     " Find out the relative path name from the parent dir of the _vng
63     " directory to the location of the presently edited file
64     let relPath = strpart(expand('%:p'), strlen(b:vng_repoDirectory))
66     " The last recorded file lies in
67     "   $DIR/_vng/current/relative/path/to/file
68     " where
69     "   $DIR/relative/path/to/file
70     " is the actual path of the file
71     let lastRecFile = b:vng_repoDirectory . '/'
72         \ . '_vng/current' . relPath
74         call Vng_Debug(':Vng_DiffSplit: lastRecFile = '.lastRecFile)
76         call Vng_NoteViewState()
78         execute 'vert diffsplit '.lastRecFile
79         " The file in _vng/current should not be edited by the user.
80         setlocal readonly
82         nmap <buffer> q <Plug>VngRestoreViewAndQuit
84         call Vng_CD(origDir)
85 endfunction
87 " }}}
88 " Vng_SetVngDirectory: finds which _vng directory contains this file {{{
89 " Description: This function searches upwards from the current directory for a
90 "              _vng directory.
91 function! Vng_SetVngDirectory()
92         let filename = expand('%:p')
93         let origDir = getcwd()
94         let foundFile = 0
96         call Vng_CD(expand('%:p:h'))
97         let lastDir = getcwd()
98     while glob('_vng*') == ''
99         lcd ..
100         " If we cannot go up any further, then break
101         if lastDir == getcwd()
102             break
103         endif
104                 let lastDir = getcwd()
105     endwhile
107     " If a _vng directory was never found, then quit...
108     if glob('_vng*') == ''
109         echohl Error
110         echo "_vng directory not found in or above current directory"
111         echohl None
112         return -1
113     endif
115         let b:vng_repoDirectory = getcwd()
116         
117         call Vng_CD(origDir)
119     return 0
120 endfunction
122 " }}}
124 " }}}
125 " Functions related to interactive diff splitting {{{
127 nmap <Plug>VngIneractiveDiff :call Vng_StartInteractiveDiffSplit()<CR>
128 if !hasmapto('<Plug>VngIneractiveDiff')
129         nmap <unique> <leader>dki <Plug>VngIneractiveDiff
130 endif
132 " Vng_StartInteractiveDiffSplit: initializes the interactive diffsplit session {{{
133 function! Vng_StartInteractiveDiffSplit()
134         let origdir = getcwd()
135         let filedir = expand('%:p:h')
136         let filename = expand('%:p:t')
137         let filetype = &l:ft
139         call Vng_CD(filedir)
140         call Vng_OpenScratchBuffer()
142         let changelog = Vng_FormatChangelog(filename)
143         if changelog == ''
144                 echomsg "vng does not know about this file"
145                 return
146         endif
147         0put=Vng_FormatChangelog(filename)
149         call Vng_CD(origdir)
151         set ft=changelog
152         " reading in stuff creates an extra line ending
153         $ d _
155         let header = 
156                 \ '====[ Vng diff console: Mappings ]==========================' . "\n" .
157                 \ "\n" .
158                 \ 'j/k  : next/previous patch' . "\n" .
159                 \ 'f    : set "from" patch' . "\n" .
160                 \ 't    : set "to" patch' . "\n" .
161                 \ 'g    : proceed with diff (Go)' . "\n" .
162                 \ 'q    : quit without doing anything further'. "\n" .
163                 \ '=============================================================='
164         0put=header
165         normal! gg
166         
167         let b:vng_FROM_hash = ''
168         let b:vng_TO_hash = ''
169         let b:vng_orig_ft = filetype
170         let b:vng_orig_file = filename
171         let b:vng_orig_dir = filedir
173         nmap <buffer> j <Plug>VngGotoNextChange
174         nmap <buffer> k <Plug>VngGotoPreviousChange
175         nmap <buffer> f <Plug>VngSetFromHash
176         nmap <buffer> t <Plug>VngSetToHash
177         nmap <buffer> g <Plug>VngProceedWithDiffSplit
178         nmap <buffer> q :q<CR>:<BS>
180         call search('^\s*\*')
181 endfunction
183 " }}}
184 " Vng_FormatChangelog: creates a Changelog with hash for a file {{{
185 function! Vng_FormatChangelog(filename)
187         " remove the first <created_as ../> entry
188         let xmloutput = Vng_System('vng changes --xml-output '.a:filename)
189         " TODO: We need to see if there were any errors generated by vng or
190         " if the xmloutput is empty.
191         
192         let idx = match(xmloutput, '<\/created_as>')
193         let xmloutput = strpart(xmloutput, idx + strlen('</created_as>'))
195         let changelog = ""
197         " For each patch in the xml output
198         let idx = match(xmloutput, '</patch>')
199         while idx != -1
200                 " extract the actual patch.
201                 let patch = strpart(xmloutput, 0, idx)
203                 " From the patch, extract the various fields.
204                 let name = matchstr(patch, '<name>\zs.*\ze<\/name>')
205                 let comment = matchstr(patch, '<comment>\zs.*\ze</comment>')
207                 let pattern = ".*<patch author='\\(.\\{-}\\)' date='\\(.\\{-}\\)' local_date='\\(.\\{-}\\)' inverted='\\(True\\|False\\)' hash='\\(.\\{-}\\)'>.*"
209                 let author = substitute(patch, pattern, '\1', '')
210                 let date = substitute(patch, pattern, '\2', '')
211                 let local_date = substitute(patch, pattern, '\3', '')
212                 let inverted = substitute(patch, pattern, '\4', '')
213                 let hash = substitute(patch, pattern, '\5', '')
215                 " Create the formatted changelog entry for this patch.
216                 " Unfortunately, we do not have the +M -5 +10 kind of line in this
217                 " output. Price to pay...
218                 let formatted = "[hash ".hash."]\n".local_date.' '.author."\n  * ".name."\n".
219                                         \ substitute(comment, "\n", "\n  ", 'g')."\n\n"
221                 let changelog = changelog.formatted
223                 " Once the patch has been processed, snip if from the xml output.
224                 let xmloutput = strpart(xmloutput, idx + strlen('</patch>'))
225                 let idx = match(xmloutput, '</patch>')
226         endwhile
227         
228         if changelog != ''
229                 let changelog = "Changes in ".a:filename.":\n\n".changelog
231                 let s:sub_{'&apos;'} = "'"
232                 let s:sub_{'&quot;'} = '"'
233                 let s:sub_{'&amp;'} = '&'
234                 let s:sub_{'&lt;'} = '<'
235                 let s:sub_{'&gt;'} = '>'
237                 function! Eval(expr)
238                         if exists("s:sub_{'".a:expr."'}")
239                                 return s:sub_{a:expr}
240                         else
241                                 return a:expr
242                         endif
243                 endfunction
245                 let changelog = substitute(changelog, '&\w\{2,4};', '\=Eval(submatch(0))', 'g')
247                 return changelog
249         else
250                 return ""
251         endif
253 endfunction
255 " }}}
256 " Vng_SetHash: remembers the user's from/to hashs for the diff {{{
258 nnoremap <Plug>VngSetToHash :call Vng_SetHash('TO')<CR>
259 nnoremap <Plug>VngSetFromHash :call Vng_SetHash('FROM')<CR>
261 function! Vng_SetHash(fromto)
262         normal! $
263         call search('^\s*\*', 'bw')
265         " First remove any previous mark set.
266         execute '% s/'.a:fromto.'$//e'
268         " remember the present line's hash
269         let b:vng_{a:fromto}_hash = matchstr(getline(line('.')-2), '\[hash \zs.\{-}\ze\]')
271         call setline(line('.')-1, getline(line('.')-1).'  '.a:fromto)
272 endfunction
274 " }}}
275 " Vng_GotoChange: goes to the next previous change {{{
277 nnoremap <Plug>VngGotoPreviousChange :call Vng_GotoChange('b')<CR>
278 nnoremap <Plug>VngGotoNextChange :call Vng_GotoChange('')<CR>
280 function! Vng_GotoChange(dirn)
281         call search('^\s*\*', a:dirn.'w')
282 endfunction
284 " }}}
285 " Vng_ProceedWithDiff: proceeds with the actual diff between requested versions {{{
286 " Description: 
288 nnoremap <Plug>VngProceedWithDiffSplit :call Vng_ProceedWithDiff()<CR>
290 function! Vng_ProceedWithDiff()
291         call Vng_Debug('+Vng_ProceedWithDiff')
293         if b:vng_FROM_hash == '' && b:vng_TO_hash == ''
294                 echohl Error
295                 echo "You need to set at least one of the FROM or TO hashes"
296                 echohl None
297                 return -1
298         endif
300         let origDir = getcwd()
302         call Vng_CD(b:vng_orig_dir)
304         let ft = b:vng_orig_ft
305         let filename = b:vng_orig_file
306         let fromhash = b:vng_FROM_hash
307         let tohash = b:vng_TO_hash
309         " quit the window which shows the Changelog
310         q
312         " First copy the present file into a temporary location
313         let tmpfile = tempname().'__present'
315         call Vng_System('cp '.filename.' '.tmpfile)
317         if fromhash != ''
318                 let tmpfilefrom = tempname().'__from'
319                 call Vng_RevertToState(filename, fromhash, tmpfilefrom)
320                 let file1 = tmpfilefrom
321         else
322                 let file1 = filename
323         endif
325         if tohash != ''
326                 let tmpfileto = tempname().'__to'
327                 call Vng_RevertToState(filename, tohash, tmpfileto)
328                 let file2 = tmpfileto
329         else
330                 let file2 = filename
331         endif
333         call Vng_Debug(':Vng_ProceedWithDiff: file1 = '.file1.', file2 = '.file2)
335         execute 'split '.file1
336         execute "nnoremap <buffer> q :q\<CR>:e ".file2."\<CR>:q\<CR>"
337         let &l:ft = ft
338         execute 'vert diffsplit '.file2
339         let &l:ft = ft
340         execute "nnoremap <buffer> q :q\<CR>:e ".file1."\<CR>:q\<CR>"
341         
342         call Vng_CD(origDir)
344         call Vng_Debug('-Vng_ProceedWithDiff')
345 endfunction 
347 " }}}
348 " Vng_RevertToState: reverts a file to a previous state {{{
349 function! Vng_RevertToState(filename, patchhash, tmpfile)
350         call Vng_Debug('+Vng_RevertToState: pwd = '.getcwd())
352         let syscmd = "vng diff --from-match \"hash ".a:patchhash."\" ".a:filename.
353                 \ " | patch -R ".a:filename." -o ".a:tmpfile
354         call Vng_Debug(':Vng_RevertToState: syscmd = '.syscmd)
355         call Vng_System(syscmd)
357         let syscmd = "vng diff --match \"hash ".a:patchhash."\" ".a:filename.
358                 \ " | patch ".a:tmpfile
359         call Vng_Debug(':Vng_RevertToState: syscmd = '.syscmd)
360         call Vng_System(syscmd)
362         call Vng_Debug('-Vng_RevertToState')
363 endfunction 
365 " }}}
367 " }}}
368 " Functions related to interactive comitting {{{
370 nmap <Plug>VngStartCommitSession :call Vng_StartCommitSession()<CR>
371 if !hasmapto('<Plug>VngStartCommitSession')
372         nmap <unique> <leader>dkc <Plug>VngStartCommitSession
373 endif
375 " Vng_StartCommitSession: start an interactive commit "console" {{{
376 function! Vng_StartCommitSession()
378         let origdir = getcwd()
379         let filename = expand('%:p:t')
380         let filedir = expand('%:p:h')
381         
382         call Vng_CD(filedir)
383         let wn = Vng_System('vng whatsnew --no-summary --dont-look-for-adds')
384         call Vng_CD(origdir)
386         if wn =~ '^No changes!'
387                 echo "No changes seen by vng"
388                 return
389         endif
391         " read in the contents of the `vng whatsnew` command
392         call Vng_SetSilent('silent')
394         " opens a scratch buffer for the commit console
395         " Unfortunately, it looks like the temporary file has to exist in the
396         " present directory because at least on Windows, vng doesn't want to
397         " handle absolute path names containing ':' correctly.
398         exec "top split ".Vng_GetTempName(expand('%:p:h'))
399         0put=wn
401         " Delete the end and beginning markers
402         g/^[{}]$/d _
403         " Put an additional four spaces in front of all lines and a little
404         " checkbox in front of the hunk specifier lines
405         % s/^/    /
406         % s/^    hunk/[ ] hunk/
408         let header = 
409                 \ '====[ Vng commit console: Mappings ]========================' . "\n" .
410                 \ "\n" .
411                 \ 'J/K  : next/previous hunk' . "\n" .
412                 \ 'Y/N  : accept/reject this hunk' . "\n" .
413                 \ 'F/S  : accept/reject all hunks from this file' . "\n" .
414                 \ 'A/U  : accept/reject all (remaining) hunks' . "\n" .
415                 \ 'q    : quit this session without committing' . "\n" .
416                 \ 'L    : goto log area to record description'. "\n" .
417                 \ 'R    : done! finish record' . "\n" .
418                 \ '=============================================================='
419         0put=header
421         let footer = 
422                 \ '====[ Vng commit console: Commit log description ]==========' . "\n" .
423                 \ "\n" .
424                 \ '***VNG***'. "\n".
425                 \ 'Write the long patch description in this area.'. "\n".
426                 \ 'The first line in this area will be the patch name.'. "\n".
427                 \ 'Everything in this area from the above ***VNG*** line on '."\n".
428                 \ 'will be ignored.'. "\n" .
429                 \ '=============================================================='
430         $put=footer
432         set nomodified
433         call Vng_SetSilent('notsilent')
435         " Set the fold expression so that things get folded up nicely.
436         set fdm=expr
437         set foldexpr=Vng_WhatsNewFoldExpr(v:lnum)
439         " Finally goto the first hunk
440         normal! G
441         call search('^\[ ', 'w')
443         nnoremap <buffer> J :call Vng_GotoHunk('')<CR>:<BS>
444         nnoremap <buffer> K :call Vng_GotoHunk('b')<CR>:<BS>
446         nnoremap <buffer> Y :call Vng_SetHunkVal('y')<CR>:<BS>
447         nnoremap <buffer> N :call Vng_SetHunkVal('n')<CR>:<BS>
449         nnoremap <buffer> A :call Vng_SetRemainingHunkVals('y')<CR>:<BS>
450         nnoremap <buffer> U :call Vng_SetRemainingHunkVals('n')<CR>:<BS>
452         nnoremap <buffer> F :call Vng_SetFileHunkVals('y')<CR>:<BS>
453         nnoremap <buffer> S :call Vng_SetFileHunkVals('n')<CR>:<BS>
455         nnoremap <buffer> L :call Vng_GotoLogArea()<CR>
456         nnoremap <buffer> R :call Vng_FinishCommitSession()<CR>
458         nnoremap <buffer> q :call Vng_DeleteTempFile(expand('%:p'))<CR>
460         let b:vng_orig_file = filename
461         let b:vng_orig_dir = filedir
462 endfunction
464 " }}}
465 " Vng_WhatsNewFoldExpr: foldexpr function for a commit console {{{
466 function! Vng_WhatsNewFoldExpr(lnum)
467         if matchstr(getline(a:lnum), '^\[[yn ]\]') != ''
468                 return '>1'
469         elseif matchstr(getline(a:lnum+1), '^====\[ .* log description') != ''
470                 return '<1'
471         else
472                 return '='
473         endif
474 endfunction
476 " }}}
477 " Vng_GotoHunk: goto next/previous hunk in a commit console {{{
478 function! Vng_GotoHunk(dirn)
479         call search('^\[[yn ]\]', a:dirn.'w')
480 endfunction
482 " }}}
483 " Vng_SetHunkVal: accept/reject a hunk for committing {{{
484 function! Vng_SetHunkVal(yesno)
485         if matchstr(getline('.'), '\[[yn ]\]') == ''
486                 return
487         end
488         execute "s/^\\[.\\]/[".a:yesno."]"
489         call Vng_GotoHunk('')
490 endfunction
492 " }}}
493 " Vng_SetRemainingHunkVals: accept/reject all remaining hunks {{{
494 function! Vng_SetRemainingHunkVals(yesno)
495         execute "% s/^\\[ \\]/[".a:yesno."]/e"
496 endfunction 
498 " }}}
499 " Vng_SetFileHunkVals: accept/reject all hunks from this file {{{
500 function! Vng_SetFileHunkVals(yesno)
501         " If we are not on a hunk line for some reason, then do not do
502         " anything.
503         if matchstr(getline('.'), '\[[yn ]\]') == ''
504                 return
505         end
507         " extract the file name from the current line
508         let filename = matchstr(getline('.'), 
509                 \ '^\[[yn ]\] hunk \zs\f\+\ze')
510         if filename == ''
511                 return
512         endif
514         " mark all hunks belonging to the file with yes/no
515         execute '% s/^\[\zs[yn ]\ze\] hunk '.escape(filename, "\\/").'/'.a:yesno.'/e'
517         call Vng_GotoHunk('')
518 endfunction 
520 " }}}
521 " Vng_GotoLogArea: records the log description of the commit {{{
522 function! Vng_GotoLogArea()
523         if search('^\[ \]')
524                 echohl WarningMsg
525                 echo "There are still some hunks which are neither accepted or rejected"
526                 echo "Please set the status of all hunks before proceeding to log"
527                 echohl None
529                 return
530         endif
532         call search('\M^***VNG***')
533         normal! k
534         startinsert
535 endfunction 
537 " }}}
538 " Vng_FinishCommitSession: finishes the interactive commit session {{{
539 function! Vng_FinishCommitSession()
541         " First make sure that all hunks have been set as accpeted or rejected.
542         if search('^\[ \]')
544                 echohl WarningMsg
545                 echo "There are still some hunks which are neither accepted or rejected"
546                 echo "Please set the status of all hunks before proceeding to log"
547                 echohl None
549                 return
550         endif
552         " Then make a list of the form "ynyy..." from the choices made by the
553         " user.
554         let yesnolist = ''
555         g/^\[[yn]\]/let yesnolist = yesnolist.matchstr(getline('.'), '^\[\zs.\ze\]')
557         " make sure that a valid log message has been written.
558         call search('====\[ Vng commit console: Commit log description \]', 'w')
559         normal! j
560         let _k = @k
561         execute "normal! V/\\M***VNG***/s\<CR>k\"ky"
563         let logMessage = @k
564         let @k = _k
566         call Vng_Debug(':Vng_FinishCommitSession: logMessage = '.logMessage)
567         call Vng_Debug(':Vng_FinishCommitSession: yesnolist = ['.yesnolist.']')
569         if logMessage !~ '[[:graph:]]'
571                 echohl WarningMsg
572                 echo "The log message is either ill formed or empty"
573                 echo "Please repair the mistake and retry"
574                 echohl None
576                 return
577         endif
579         " Remove everything from the file except the log file.
580         % d _
581         0put=logMessage
582         $ d _
583         w
585         let origDir = getcwd()
586         call Vng_CD(b:vng_orig_dir)
588         let vngOut = Vng_System('echo '.yesnolist.' | vng record --logfile='.expand('%:p:t'))
590         call Vng_CD(origDir)
592         % d _
593         0put=vngOut
595         let footer = 
596                 \ "=================================================================\n".
597                 \ "Press q to delete this temporary file and quit the commit session\n".
598                 \ "If you quit this using :q, then a temp file will remain in the \n".
599                 \ "present directory\n".
600                 \ "================================================================="
601         $put=footer
603         set nomodified
605 endfunction 
607 " }}}
608 " Vng_DeleteTempFile: deletes temp file created during commit session {{{
609 function! Vng_DeleteTempFile(fname)
610         call Vng_Debug('+Vng_DeleteTempFile: fname = '.a:fname.', bufnr = '.bufnr(a:fname))
611         if bufnr(a:fname) > 0
612                 execute 'bdelete! '.bufnr(a:fname)
613         endif
614         let sysout = Vng_System('rm '.a:fname)
615 endfunction 
617 " }}}
619 " }}}
621 " ==============================================================================
622 " Helper functions
623 " ==============================================================================
624 " Vng_System: runs a system command escaping quotes {{{
626 " By default we will use python if available.
627 if !exists('g:Vng_UsePython')
628         let g:Vng_UsePython = 1
629 endif
631 function! Vng_System(syscmd)
632         if has('python') && g:Vng_UsePython == 1
633                 execute 'python pySystem(r"""'.a:syscmd.'""")'
634                 return retval
635         else
636                 if &shellxquote =~ '"'
637                         return system(escape(a:syscmd, '"'))
638                 else
639                         return system(a:syscmd)
640                 endif
641         endif
642 endfunction 
644 if has('python') && g:Vng_UsePython == 1
645 python << EOF
647 import vim, os, re
649 def pySystem(command):
650         (cstdin, cstdout) = os.popen2(command)
652         out = cstdout.read()
654         vim.command("""let retval = "%s" """ % re.sub(r'"|\\', r'\\\g<0>', out))
657 endif
659 " }}}
660 " Vng_CD: cd's to a directory {{{
661 function! Vng_CD(dirname)
662         execute "cd ".escape(a:dirname, ' ')
663 endfunction
665 " }}}
666 " Vng_OpenScratchBuffer: opens a scratch buffer {{{
667 function! Vng_OpenScratchBuffer()
668         new
669         set buftype=nofile
670         set noswapfile
671         set filetype=
672 endfunction
674 " }}}
675 " Vng_NoteViewState: notes the current fold related settings of the buffer {{{
676 function! Vng_NoteViewState()
677         let b:vng_old_diff         = &l:diff 
678         let b:vng_old_foldcolumn   = &l:foldcolumn
679         let b:vng_old_foldenable   = &l:foldenable
680         let b:vng_old_foldmethod   = &l:foldmethod
681         let b:vng_old_scrollbind   = &l:scrollbind
682         let b:vng_old_wrap         = &l:wrap
683 endfunction
685 " }}}
686 " Vng_ResetViewState: restores the fold related settings of a buffer {{{
687 function! Vng_ResetViewState()
688         let &l:diff         = b:vng_old_diff 
689         let &l:foldcolumn   = b:vng_old_foldcolumn
690         let &l:foldenable   = b:vng_old_foldenable
691         let &l:foldmethod   = b:vng_old_foldmethod
692         let &l:scrollbind   = b:vng_old_scrollbind
693         let &l:wrap         = b:vng_old_wrap
694 endfunction
696 nnoremap <Plug>VngRestoreViewAndQuit :q<CR>:call Vng_ResetViewState()<CR>:<BS> 
698 " }}}
699 " Vng_GetTempName: get the name of a temporary file in specified directory {{{
700 " Description: Unlike vim's native tempname(), this function returns the name
701 "              of a temporary file in the directory specified. This enables
702 "              us to create temporary files in a specified directory.
703 function! Vng_GetTempName(dirname)
704         let prefix = 'vngVimTemp'
705         let slash = (a:dirname =~ '\\\|/$' ? '' : '/')
706         let i = 0
707         while filereadable(a:dirname.slash.prefix.i.'.tmp') && i < 1000
708                 let i = i + 1
709         endwhile
710         if filereadable(a:dirname.slash.prefix.i.'.tmp')
711                 echoerr "Temporary file could not be created in ".a:dirname
712                 return ''
713         endif
714         return expand(a:dirname.slash.prefix.i.'.tmp', ':p')
715 endfunction
716 " }}}
717 " Vng_SetSilent: sets options to make vim "silent" {{{
718 function! Vng_SetSilent(isSilent)
719         if a:isSilent == 'silent'
720                 let s:_showcmd = &showcmd
721                 let s:_lz = &lz
722                 let s:_report = &report
723                 set noshowcmd
724                 set lz
725                 set report=999999
726         else
727                 let &showcmd = s:_showcmd
728                 let &lz = s:_lz
729                 let &report = s:_report
730         endif
731 endfunction " }}}
732 " Vng_Debug: appends the argument into s:debugString {{{
733 if !exists('g:Vng_Debug')
734         let g:Vng_Debug = 1
735         let s:debugString = ''
736 endif
737 function! Vng_Debug(str)
738         let s:debugString = s:debugString.a:str."\n"
739 endfunction " }}}
740 " Vng_PrintDebug: prings s:debugString {{{
741 function! Vng_PrintDebug()
742         echo s:debugString
743 endfunction " }}}
744 " Vng_ClearDebug: clears the s:debugString string {{{
745 function! Vng_ClearDebug(...)
746         let s:debugString = ''
747 endfunction " }}}
749 " vim:fdm=marker