CTRLP
[my-vim-dotfolder.git] / PACKAGES / myprojects.vba
blob3fc8ecd313ffe6a74658d9c82f64b914e9cb8cf7
1 " Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
2 UseVimball
3 finish
4 plugin/myprojects.vim   [[[1
5 3258
6 "=============================================================================
7 " File:                                         myprojects.vim
8 " Author:                                       Frédéric Hardy - http://blog.mageekbox.net
9 " Date:                                         Tue Jun  2 12:44:12 CEST 2009
10 " Licence:                                      GPL version 2.0 license
11 " GetLatestVimScripts:  2556 10039 :AutoInstall: myprojects.vim
12 "=============================================================================
13 " Check version {{{1
14 if v:version < 700
15     echoerr "myprojects.vim requires vim >= 7. DOWNLOAD IT! You'll thank me later."
16 " Check folding {{{1
17 elseif !has('folding')
18     echoerr "myprojects.vim requires folding."
19 " Check compatible mode {{{1
20 elseif &cp
21     echoerr "myprojects.vim requires no compatible mode."
22 " plug-in's code {{{1
23 elseif !exists('myprojects_enable')
24         " Save cpo {{{2
25         let s:keepCpo= &cpo
26         setlocal cpo&vim
28         " Initialize variables {{{2
29         " Initialize script variables {{{3
30         let s:plugin = 'myprojects'
31         let s:version = '0.0.106'
32         let s:copyright = '2009'
33         let s:author = 'Frédéric Hardy'
34         let s:email = 'myprojects.vim@mageekbox.net'
35         let s:webSite = 'http://blog.mageekbox.net'
36         let s:prompt = '[' . s:plugin . '] '
37         let s:oldWidth = 0
38         let s:windowsOs = has('win16') || has('win32') || has('win64')
39         let s:osSlash = s:windowsOs ? '\' : '/'
40         let s:home = expand('$HOME', ':p')
41         let s:quitVimIfMyProjectsIsAlone = 1
42         let s:refreshProjectBuffers = 1
43         let s:loadAttributes = 1
44         let s:diffBuffers = []
45         let s:preferences = {}
47         " Function s:initVariable() {{{3
48         function s:initVariable(name, value)
49                 if !exists(a:name)
50                         let {a:name} = a:value
51                 endif
52         endfunction
54         " Initialize global variables {{{3
55         call s:initVariable('g:myprojects_width', 30)
56         call s:initVariable('g:myprojects_file', s:home . s:osSlash . '.' . s:plugin)
57         call s:initVariable('g:myprojects_tags_file', '.tags')
58         call s:initVariable('g:myprojects_auto_close', 0)
59         call s:initVariable('g:myprojects_auto_resize', 0)
60         call s:initVariable('g:myprojects_auto_open', 1)
61         call s:initVariable('g:myprojects_version_at_startup', 1)
62         call s:initVariable('g:myprojects_resize_step', 10)
63         call s:initVariable('g:myprojects_syntax', 1)
64         call s:initVariable('g:myprojects_display_empty_folder', 0)
65         call s:initVariable('g:myprojects_version_control_system', 'svn')
66         call s:initVariable('g:myprojects_display_number', 0)
67         call s:initVariable('g:myprojects_cursorline', 1)
68         call s:initVariable('g:myprojects_cursorcolumn', 1)
69         call s:initVariable('g:myprojects_foldcolumn', 0)
70         call s:initVariable('g:myprojects_display_path_in_statusline', 1)
71         call s:initVariable('g:myprojects_tags_generator', '')
72         call s:initVariable('g:myprojects_sessions_directory', s:home . s:osSlash . '.vim' . s:osSlash . 'plugin/myprojects/sessions')
73         call s:initVariable('g:myprojects_preferences_file', s:home . s:osSlash . '.vim' . s:osSlash . 'plugin/myprojects/preferences')
74         call s:initVariable('g:myprojects_new_file_on_bottom', 1)
75         call s:initVariable('g:myprojects_sort_svn', 1)
76         call s:initVariable('g:myprojects_sort_buffers', 1)
77         call s:initVariable('g:myprojects_quit_vim_if_alone', 1)
78         call s:initVariable('g:myprojects_autowrite', 1)
80         " Initialize command {{{2
81         command -nargs=? -complete=file MyProjectsToggle call <SID>toggleMyProjectsWindow()
83         if !hasmapto('<Plug>MyProjectsToggle')
84                 map <unique> <silent> <Leader>p <Plug>MyProjectsToggle
85         endif
87         noremap <unique> <script> <Plug>MyProjectsToggle <SID>toggle
88         noremap <SID>toggle :call <SID>toggleMyProjectsWindow()<CR>
90         command -nargs=? -complete=file MyProjectsGoTo call <SID>goToMyProjectsWindow()
92         if !hasmapto('<Plug>MyProjectsGoTo')
93                 map <unique> <silent> <Leader>P <Plug>MyProjectsGoTo
94         endif
96         noremap <unique> <script> <Plug>MyProjectsGoTo <SID>goTo
97         noremap <SID>goTo :call <SID>goToMyProjectsWindow()<CR>
99         if g:myprojects_auto_open
100                 autocmd VimEnter * nested call <SID>toggleMyProjectsWindow()
101         endif
103         " Function s:goToMyProjectsWindow() {{{2
104         function s:goToMyProjectsWindow()
105                 let window = bufwinnr(g:myprojects_file)
107                 if window == -1
108                         return 0
109                 else
110                         silent execute window . 'wincmd w'
111                         return 1
112                 endif
113         endfunction
115         " Function s:writeMyProjectsPreferences() {{{2
116         function s:writeMyProjectsPreferences()
117                 let preferencesDirectory = fnamemodify(g:myprojects_preferences_file, ':h')
118                 let type = getftype(preferencesDirectory)
120                 if type == ''
121                         call s:mkdir(preferencesDirectory)
122                 elseif type != 'dir'
123                         throw 'Path ''' . preferencesDirectory . ''' exists but it is not a directory.'
124                 endif
126                 if !filewritable(preferencesDirectory)
127                         throw 'Unable to write in ''' . preferencesDirectory . '''.'
128                 else
129                         call writefile([string(s:preferences)], g:myprojects_preferences_file)
130                 endif
131         endfunction
133         " Function s:readMyProjectsPreferences() {{{2
134         function s:readMyProjectsPreferences()
135                 if getftype(g:myprojects_preferences_file) == 'file' && filereadable(g:myprojects_preferences_file)
136                         let preferencesFileContent = readfile(g:myprojects_preferences_file, '', 1)
138                         if len(preferencesFileContent) == 1 && preferencesFileContent[0] =~ '^{.*}$'
139                                 execute 'let preferences =  ' . preferencesFileContent[0]
141                                 if type(preferences) == 4
142                                         let s:preferences = preferences
143                                 endif
144                         endif
145                 endif
146         endfunction
148         " Function s:definePreferences()
149         function s:definePreferences()
150                 let type = s:input('Preferences for type: ', '')
152                 if type == ''
153                         call s:error('Preferences type must not be empty.')
154                 else
155                         call s:readMyProjectsPreferences()
157                         let mappings = {'1': '', '2': '', '3': '', '4': '', '5': '', '6': '', '7': '', '8': '', '9': '', '10': '', '11': '', '12': ''}
159                         if !has_key(s:preferences, type)
160                                 let s:preferences[type] = {'path': '', 'cd': '', 'filter': '', 'make': '', 'errorFormat': '', 'test': '', 'mappings': mappings}
161                         else
162                                 let s:preferences[type]['path'] = !has_key(s:preferences[type], 'path') ? '': s:preferences[type]['path']
163                                 let s:preferences[type]['cd'] = !has_key(s:preferences[type], 'cd') ? '': s:preferences[type]['cd']
164                                 let s:preferences[type]['filter'] = !has_key(s:preferences[type], 'filter') ? '': s:preferences[type]['filter']
165                                 let s:preferences[type]['make'] = !has_key(s:preferences[type], 'make') ? '': s:preferences[type]['make']
166                                 let s:preferences[type]['errorFormat'] = !has_key(s:preferences[type], 'errorFormat') ? '': s:preferences[type]['errorFormat']
167                                 let s:preferences[type]['test'] = !has_key(s:preferences[type], 'test') ? '': s:preferences[type]['test']
169                                 if has_key(s:preferences[type], 'mappings')
170                                         for [key, mapping] in items(s:preferences[type]['mappings'])
171                                                 let mappings[key] = mapping
172                                         endfor
173                                 endif
174                         endif
176                         let s:preferences[type]['path'] = s:inputRealPath('Path for type ''' . type . ''': ', s:preferences[type]['path'], 0)
177                         let s:preferences[type]['cd'] = s:inputCd('Working directory for type ''' . type . ''': ', s:preferences[type]['cd'], s:preferences[type]['cd'])
178                         let s:preferences[type]['filter'] = s:inputFilter('Filter for type ''' . type . ''': ', s:preferences[type]['filter'])
179                         let s:preferences[type]['make'] = s:inputMake('Make for type ''' . type . ''': ', s:preferences[type]['make'])
180                         let s:preferences[type]['errorformat'] = s:inputErrorFormat('Error format for type ''' . type . ''': ', s:preferences[type]['errorFormat'])
181                         let s:preferences[type]['test'] = s:inputTest('Test extension for type ''' . type . ''': ', s:preferences[type]['test'])
182                         let s:preferences[type]['mappings'] = {'1': '', '2': '', '3': '', '4': '', '5': '', '6': '', '7': '', '8': '', '9': '', '10': '', '11': '', '12': ''}
184                         let mappings = s:inputMappings('Mappings for type ''' . type . ''': ', mappings)
186                         for [key, mapping] in items(mappings)
187                                         let s:preferences[type]['mappings'][key] = mapping
188                         endfor
190                         call s:message('Save preferences for type ''' . type . '''...')
191                         call s:writeMyProjectsPreferences()
192                         call s:message('Preferences saved for type ''' . type . '''.')
193                 endif
194         endfunction
196         " Function s:openMyProjectsWindow() {{{2
197         function s:openMyProjectsWindow()
198                 if !s:goToMyProjectsWindow()
199                         silent execute 'leftabove vertical new'
201                         call s:moveWindowToTopLeftCorner()
202                         call s:setWindowWidth(g:myprojects_width)
204                         let myprojects_file = fnameescape(g:myprojects_file)
206                         if bufexists(g:myprojects_file)
207                                 silent execute 'buffer ' . myprojects_file
208                         else
209                                 silent execute 'edit ' . myprojects_file
211                                 nnoremap <silent> <buffer> <LeftMouse> <LeftMouse>:echo<CR>
212                                 nnoremap <silent> <buffer> <S-LeftMouse> <LeftMouse>:echo<CR>
213                                 nnoremap <silent> <buffer> <Return> :call <SID>open('edit')<CR>
214                                 nnoremap <silent> <buffer> <2-Leftmouse> :call <SID>open('edit')<CR>
215                                 nnoremap <silent> <buffer> <S-Return> :call <SID>open('sp')<CR>
216                                 nnoremap <silent> <buffer> <S-2-Leftmouse> :call <SID>open('sp')<CR>
217                                 nnoremap <silent> <buffer> <C-Return> :call <SID>open('vs')<CR>
218                                 nnoremap <silent> <buffer> <C-2-Leftmouse> :call <SID>open('vs')<CR>
219                                 nnoremap <silent> <buffer> <C-Tab> :call <SID>goToAnEditionWindow()<CR>
220                                 nnoremap <silent> <buffer> <C-Right> :call <SID>setWindowWidth(winwidth(0) + g:myprojects_resize_step)<CR>
221                                 nnoremap <silent> <buffer> <C-l> :call <SID>setWindowWidth(winwidth(0) + g:myprojects_resize_step)<CR>
222                                 nnoremap <silent> <buffer> <C-Left> :call <SID>setWindowWidth(winwidth(0) - g:myprojects_resize_step)<CR>
223                                 nnoremap <silent> <buffer> <C-h> :call <SID>setWindowWidth(winwidth(0) - g:myprojects_resize_step)<CR>
224                                 nnoremap <silent> <buffer> <C-Space> :call <SID>toggleFullscreen()<CR>
225                                 nnoremap <silent> <buffer> <LocalLeader>b :call <SID>toggleProjectBuffers(<SID>getProjectName(line('.')), <SID>getProjectPath(line('.')), '')<CR>
226                                 nnoremap <silent> <buffer> <LocalLeader>c :call <SID>create(line('.'))<CR>
227                                 nnoremap <silent> <buffer> <LocalLeader>r :call <SID>refresh(line('.'), 0)<CR>
228                                 nnoremap <silent> <buffer> <LocalLeader>R :call <SID>refresh(line('.'), 1)<CR>
229                                 nnoremap <silent> <buffer> <LocalLeader>g :call <SID>grep(line('.'))<CR>
230                                 nnoremap <silent> <buffer> <LocalLeader>t :call <SID>generateTags(line('.'))<CR>
231                                 nnoremap <silent> <buffer> <LocalLeader>e :call <SID>explore('E')<CR>
232                                 nnoremap <silent> <buffer> <LocalLeader>E :call <SID>explore('Se')<CR>
233                                 nnoremap <silent> <buffer> <LocalLeader>a :call <SID>append(line('.'))<CR>
234                                 nnoremap <silent> <buffer> <LocalLeader>d :call <SID>delete(line('.'))<CR>
235                                 nnoremap <silent> <buffer> <LocalLeader>s :call <SID>saveSession(line('.'))<CR>
236                                 nnoremap <silent> <buffer> <LocalLeader>S :call <SID>loadSession(line('.'))<CR>
237                                 nnoremap <silent> <buffer> <LocalLeader><A-s> :call <SID>deleteSession(line('.'))<CR>
238                                 nnoremap <silent> <buffer> <LocalLeader>p :call <SID>setPath(line('.'))<CR>
239                                 nnoremap <silent> <buffer> <LocalLeader>P :call <SID>updatePath(line('.'))<CR>
240                                 nnoremap <silent> <buffer> <LocalLeader>f :call <SID>setFilter(line('.'))<CR>
241                                 nnoremap <silent> <buffer> <LocalLeader>F :call <SID>updateFilter(line('.'))<CR>
242                                 nnoremap <silent> <buffer> <LocalLeader>w :call <SID>setCd(line('.'))<CR>
243                                 nnoremap <silent> <buffer> <LocalLeader>W :call <SID>updateCd(line('.'))<CR>
244                                 nnoremap <silent> <buffer> <LocalLeader>m :call <SID>setMappings(line('.'))<CR>
245                                 nnoremap <silent> <buffer> <LocalLeader>M :call <SID>updateMappings(line('.'))<CR>
246                                 nnoremap <silent> <buffer> <LocalLeader>k :call <SID>setMake(line('.'))<CR>
247                                 nnoremap <silent> <buffer> <LocalLeader>K :call <SID>updateMake(line('.'))<CR>
248                                 nnoremap <silent> <buffer> <LocalLeader>ef :call <SID>setErrorFormat(line('.'))<CR>
249                                 nnoremap <silent> <buffer> <LocalLeader>Ef :call <SID>updateErrorFormat(line('.'))<CR>
250                                 nnoremap <silent> <buffer> <LocalLeader>te :call <SID>setTest(line('.'))<CR>
251                                 nnoremap <silent> <buffer> <LocalLeader>Te :call <SID>updateTest(line('.'))<CR>
252                                 nnoremap <silent> <buffer> <LocalLeader>i :call <SID>echo('Path: ' . <SID>getPath(line('.')))<CR>
253                                 nnoremap <silent> <buffer> <LocalLeader>v :call <SID>echoVersion()<CR>
254                                 nnoremap <silent> <buffer> <LocalLeader>V :call <SID>echoMyprojectsFile()<CR>
255                                 nnoremap <silent> <buffer> <LocalLeader>ss :call <SID>svnStatus(line('.'))<CR>
256                                 nnoremap <silent> <buffer> <LocalLeader>su :call <SID>svnUpdate(line('.'))<CR>
257                                 nnoremap <silent> <buffer> <LocalLeader>sa :call <SID>svnAddStepOne(line('.'))<CR>
258                                 nnoremap <silent> <buffer> <LocalLeader>sr :call <SID>svnRevertStepOne(line('.'))<CR>
259                                 nnoremap <silent> <buffer> <LocalLeader>sd :call <SID>svnDiff(line('.'))<CR>
260                                 nnoremap <silent> <buffer> <LocalLeader>sc :call <SID>svnCommitStepOne(line('.'))<CR>
261                                 nnoremap <silent> <buffer> <LocalLeader>sb :call <SID>svnBlame(line('.'))<CR>
262                                 nnoremap <silent> <buffer> <LocalLeader>si :call <SID>svnInfo(line('.'))<CR>
263                                 nnoremap <silent> <buffer> <LocalLeader>sC :call <SID>svnCheckout(line('.'))<CR>
264                                 nnoremap <silent> <buffer> <LocalLeader>src :call <SID>svnResolve(line('.'))<CR>
265                                 nnoremap <silent> <buffer> <LocalLeader>sl :call <SID>svnLog(line('.'))<CR>
266                                 nnoremap <silent> <buffer> <LocalLeader>df :call <SID>definePreferences()<CR>
268                                 if g:myprojects_display_path_in_statusline
269                                         nnoremap <silent> <buffer> <Down> <Down>:call <SID>echoPath()<CR>
270                                         nnoremap <silent> <buffer> j j:call <SID>echoPath()<CR>
271                                         nnoremap <silent> <buffer> <Up> <Up>:call <SID>echoPath()<CR>
272                                         nnoremap <silent> <buffer> k k:call <SID>echoPath()<CR>
273                                         nnoremap <silent> <buffer> <LeftMouse> <LeftMouse>:call <SID>echoPath()<CR>
274                                         nnoremap <silent> <buffer> <S-LeftMouse> <LeftMouse>:call <SID>echoPath()<CR>
275                                 endif
277                                 setlocal autoindent
278                                 setlocal autoread
279                                 setlocal cindent
280                                 setlocal expandtab
281                                 setlocal foldenable
282                                 setlocal foldlevel=0
283                                 setlocal foldmethod=expr
284                                 setlocal nobuflisted
285                                 setlocal noequalalways
286                                 setlocal noexpandtab
287                                 setlocal nolist
288                                 setlocal nomodeline
289                                 setlocal noruler
290                                 setlocal nospell
291                                 setlocal noswapfile
292                                 setlocal nowrap
293                                 setlocal shiftwidth=3
294                                 setlocal splitbelow
295                                 setlocal splitright
296                                 setlocal tabstop=3
297                                 setlocal winfixwidth
299                                 call s:setLocal('number', g:myprojects_display_number)
300                                 call s:setLocal('cursorcolumn', g:myprojects_cursorcolumn)
301                                 call s:setLocal('cursorline', g:myprojects_cursorline)
303                                 abclear <buffer>
305                                 let s:sid = s:sid()
307                                 silent execute 'setlocal statusline=' . escape(s:prompt, ' ') . '%=[%f\ %3p%%]'
308                                 silent execute 'setlocal foldtext=' . s:sid . 'foldtext()'
309                                 silent execute 'setlocal foldexpr=' . s:sid . 'foldexpr()'
310                                 silent execute 'setlocal foldcolumn=' . g:myprojects_foldcolumn
312                                 silent execute 'augroup ' . s:plugin
313                                 silent au!
315                                 if g:myprojects_cursorline
316                                         silent au WinEnter <buffer> set cursorline
317                                 else
318                                         silent au WinEnter <buffer> set nocursorline
319                                 endif
321                                 if g:myprojects_cursorcolumn
322                                         silent au WinEnter <buffer> set cursorcolumn
323                                 else
324                                         silent au WinEnter <buffer> set nocursorcolumn
325                                 endif
327                                 silent execute 'au BufEnter * let &titlestring = ''' . substitute(&titlestring, "'", "''", 'g') . ''''
328                                 silent execute 'au BufRead * call ' . s:sid . 'loadMyProjectsAttributes()'
329                                 silent execute 'au BufEnter <buffer> let &titlestring = ''' . substitute(s:prompt, "'", "''", 'g') . ''''
330                                 silent execute 'au WinEnter ' . g:myprojects_file . ' call ' . s:sid . 'quitVim()'
331                                 silent execute 'au WinEnter ' . s:sid . '* call ' . s:sid . 'quitVim()'
332                                 silent augroup END
334                                 silent execute 'setlocal filetype=' . s:plugin
336                                 if has('syntax') && g:myprojects_syntax
337                                         syntax on
338                                 endif
340                                 if foldlevel(line('.'))
341                                         silent normal! zo
342                                 endif
344                                 if g:myprojects_display_path_in_statusline
345                                         call <SID>echo(<SID>getPath(line('.')))
346                                 endif
348                                 if g:myprojects_version_at_startup
349                                         call s:echoVersion()
350                                 endif
352                                 let &titlestring = s:prompt
353                         endif
354                 endif
355         endfunction
357         " Function s:closeMyProjectsWindow() {{{2
358         function s:closeMyProjectsWindow()
359                 if s:goToMyProjectsWindow()
360                         hide
361                         echo
362                 endif
363         endfunction
365         " Function s:toggleMyProjectsWindow() {{{2
366         function s:toggleMyProjectsWindow()
367                 if s:goToMyProjectsWindow()
368                         call s:closeMyProjectsWindow()
369                 else
370                         call s:openMyProjectsWindow()
371                 endif
372         endfunction
374         " Function s:isOneOfMyProjectsWindow() {{{2
375         function s:isOneOfMyProjectsWindow(window)
376                 let windowBuffer = winbufnr(a:window)
378                 return windowBuffer == bufnr(g:myprojects_file) ? 1 : bufname(windowBuffer) =~ '^' . s:sid .'.\+$'
379         endfunction
380         
381         " Function s:isAnEditionWindow() {{{2
382         function s:isAnEditionWindow(window)
383                 return !s:isOneOfMyProjectsWindow(a:window) && getbufvar(a:window, '&buftype') == '' && getbufvar(a:window, '&previewwindow') == 0
384         endfunction
385         
386         " Function s:goToAnEditionWindow() {{{2
387         function s:goToAnEditionWindow()
388                 wincmd p
390                 let window = winnr()
392                 if !s:isAnEditionWindow(window)
393                         let window = 1
394                         let maxWindow = winnr('$')
396                         while window <= maxWindow
397                                 if !s:isAnEditionWindow(window)
398                                         let window += 1
399                                 else
400                                         silent execute window . 'wincmd w'
401                                         return window
402                                 endif
403                         endwhile
405                         let width = &columns - g:myprojects_width
407                         silent vnew
408                         call s:setWindowWidth(width)
410                         return winnr()
411                 endif
412         endfunction
414         " Function s:createMyProjectsWindow() {{{2
415         function s:createMyProjectsWindow(title, buffer, filetype)
416                 let buffer = bufnr(s:sid . a:buffer)
418                 if buffer != -1
419                         let window = bufwinnr(buffer)
421                         if window != -1
422                                 silent execute window . 'wincmd w'
423                         else
424                                 silent execute 'botright new ' . s:sid . a:buffer
426                                 let &titlestring = s:prompt . a:title
428                                 silent execute 'setlocal statusline=' . escape(&titlestring, ' ') . '%=[%3p%%]'
430                                 let buffer = -1
431                         endif
432                 else
433                         silent execute 'botright new ' . s:sid . a:buffer
435                         setlocal buftype=nofile
436                         setlocal nobuflisted
437                         setlocal nocursorcolumn
438                         setlocal noexpandtab
439                         setlocal nolist
440                         setlocal nomodeline
441                         setlocal number
442                         setlocal noruler
443                         setlocal nospell
444                         setlocal noswapfile
445                         setlocal nowrap
447                         call s:setLocal('cursorline', g:myprojects_cursorline)
449                         let &titlestring = s:prompt . a:title
451                         silent execute 'setlocal filetype=' . a:filetype
452                         silent execute 'setlocal statusline=' . escape(&titlestring, ' ') . '%=[%3p%%]'
454                         silent execute 'augroup ' . s:plugin
456                         if g:myprojects_cursorline
457                                 silent au! WinEnter <buffer> set cursorline nocursorcolumn
458                         else
459                                 silent au! WinEnter <buffer> set nocursorline nocursorcolumn
460                         endif
462                         silent execute 'au! BufEnter <buffer> let &titlestring = ''' . substitute(s:prompt . a:title, "'", "''", 'g') . ''''
463                         silent augroup END
465                         if has('syntax') && g:myprojects_syntax
466                                 syntax on
467                         endif
469                         abclear <buffer>
470                 endif
472                 call s:setWindowHeight(0)
474                 return buffer == -1
475         endfunction
477         " Function s:createSvnWindow() {{{2
478         function s:createSvnWindow(title)
479                 call s:createMyProjectsWindow(a:title, 'svn', s:plugin . 'Svn')
481                 setlocal modifiable
482                 silent! %d
483                 setlocal nomodifiable
485                 call s:setWindowHeight(line('$'))
487                 redraw
489                 nnoremap <buffer> <silent> <S-LeftMouse> <LeftMouse>
490                 nnoremap <buffer> <silent> <Return> :call <SID>openFromSvnWindow('edit')<CR>
491                 nnoremap <buffer> <silent> <2-Leftmouse> :call <SID>openFromSvnWindow('edit')<CR>
492                 nnoremap <buffer> <silent> <S-Return> :call <SID>openFromSvnWindow('sp')<CR>
493                 nnoremap <buffer> <silent> <S-2-Leftmouse> :call <SID>openFromSvnWindow('sp')<CR>
494                 nnoremap <buffer> <silent> <C-Return> :call <SID>openFromSvnWindow('vs')<CR>
495                 nnoremap <buffer> <silent> <C-2-Leftmouse> :call <SID>openFromSvnWindow('vs')<CR>
496                 nnoremap <buffer> <silent> <LocalLeader>sd :call <SID>svnDiffFromSvnWindow()<CR>
497         endfunction
499         " Function s:createSvnConflictWindow() {{{2
500         function s:createSvnConflictWindow(title, path)
501                 call s:createSvnWindow(a:title)
503                 nnoremap <buffer> <silent> <S-LeftMouse> <LeftMouse>
504                 silent execute 'noremap <buffer> <silent> <Return> :call <SID>resolveSvnConflict(''edit'', ''' . a:path . ''')<CR>'
505                 silent execute 'noremap <buffer> <silent> <2-Leftmouse> :call <SID>resolveSvnConflict(''edit'', ''' . a:path . ''')<CR>'
506                 silent execute 'noremap <buffer> <silent> <S-Return> :call <SID>resolveSvnConflict(''sp'', ''' . a:path . ''')<CR>'
507                 silent execute 'noremap <buffer> <silent> <S-2-Leftmouse> :call <SID>resolveSvnConflict(''sp'', ''' . a:path . ''')<CR>'
508                 silent execute 'noremap <buffer> <silent> <C-Return> :call <SID>resolveSvnConflict(''vs'', ''' . a:path . ''')<CR>'
509                 silent execute 'noremap <buffer> <silent> <C-2-Leftmouse> :call <SID>resolveSvnConflict(''vs'', ''' . a:path . ''')<CR>'
510         endfunction
512         " Function s:createBufferWindow() {{{2
513         function s:createBufferWindow(title, buffer, path)
514                 let bufferCreated = s:createMyProjectsWindow(a:title, a:buffer, s:plugin)
516                 if bufferCreated
517                         nnoremap <buffer> <silent> <S-LeftMouse> <LeftMouse>
518                         silent execute 'noremap <buffer> <silent> <Return> :call <SID>openFromBuffersWindow(''edit'', ''' . a:path . ''')<CR>'
519                         silent execute 'noremap <buffer> <silent> <2-Leftmouse> :call <SID>openFromBuffersWindow(''edit'', ''' . a:path . ''')<CR>'
520                         silent execute 'noremap <buffer> <silent> <S-Return> :call <SID>openFromBuffersWindow(''sp'', ''' . a:path . ''')<CR>'
521                         silent execute 'noremap <buffer> <silent> <S-2-Leftmouse> :call <SID>openFromBuffersWindow(''sp'', ''' . a:path . ''')<CR>'
522                         silent execute 'noremap <buffer> <silent> <C-Return> :call <SID>openFromBuffersWindow(''vs'', ''' . a:path . ''')<CR>'
523                         silent execute 'noremap <buffer> <silent> <C-2-Leftmouse> :call <SID>openFromBuffersWindow(''vs'', ''' . a:path . ''')<CR>'
524                         silent execute 'noremap <buffer> <silent> <LocalLeader>sd :call <SID>svnDiffFromBuffersWindow(''' . a:path . ''')<CR>'
525                 endif
527                 return bufferCreated
528         endfunction
531         " Function s:quitVim() {{{2
532         function s:quitVim()
533                 if !g:myprojects_quit_vim_if_alone
534                         if s:myProjectsIsAlone()
535                                 call s:goToAnEditionWindow()
536                         endif
538                         return 0
539                 elseif !s:quitVimIfMyProjectsIsAlone || !s:myProjectsIsAlone()
540                         return 0
541                 else
542                         confirm qall
543                         return 1
544                 endif
545         endfunction
547         " Function s:myProjectsIsAlone() {{{2
548         function s:myProjectsIsAlone()
549                 let windows = winnr('$')
551                 while windows > 0
552                         if s:isAnEditionWindow(windows)
553                                 return 0
554                         else
555                                 let windows -= 1
556                         endif
557                 endwhile
559                 return 1
560         endfunction
562         " Function s:toggleFullscreen() {{{2
563         function s:toggleFullscreen()
564                 if s:oldWidth == 0
565                         let s:oldWidth = winwidth(0)
566                         call s:setWindowWidth('')
567                 else
568                         call s:setWindowWidth(s:oldWidth)
569                         let s:oldWidth = 0
570                 endif
571         endfunction
573         " Function s:foldtext() {{{2
574         function s:foldtext()
575                 let text = repeat(' ', indent(v:foldstart)) . '+ ' . s:getName(v:foldstart) . '-[' . (v:foldend - v:foldstart) . ']'
577                 if foldclosed(line('.')) == - 1
578                         let virtcol = virtcol('.')
579                         let wincol = wincol()
581                         if virtcol > (wincol - &sidescrolloff)
582                                 let text = strpart(text, virtcol - wincol)
583                         endif
584                 endif
586                 return text
587         endfunction
589         " Function s:foldexpr() {{{2
590         function s:foldexpr()
591                 let currentIndent = indent(v:lnum)
592                 let nextIndent = indent(nextnonblank(v:lnum + 1))
593                 return currentIndent >= nextIndent ? currentIndent / &tabstop : '>' . nextIndent / &tabstop
594         endfunction
596         " Function s:isFolder() {{{2
597         function s:isFolder(line)
598                 return indent(a:line) < indent(nextnonblank(a:line + 1))
599         endfunction
601         " Function s:getFirstFolderLine() {{{2
602         function s:getFirstFolderLine(line)
603                 let line = 0
605                 let indent = s:indent(a:line)
607                 if indent > 0
608                         let oldPosition = s:setCursorPosition([0, a:line, 1])
609                         let line = search('^\t\{' . (indent - 1) . '}[^\t]\+$', 'bnW')
610                         call s:setCursorPosition(oldPosition)
611                 endif
613                 return line
614         endfunction
616         " Function s:getLastFolderLine() {{{2
617         function s:getLastFolderLine(line)
618                 let line = 0
620                 let firstFolderLine = a:line
622                 if !s:isFolder(firstFolderLine)
623                         let firstFolderLine = s:getFirstFolderLine(firstFolderLine)
624                 endif
626                 if firstFolderLine > 0
627                         let oldPosition = s:setCursorPosition([0, firstFolderLine, 1])
628                         let line = search('^\t\{0,' . s:indent(firstFolderLine) . '\}[^\t].*$', 'nW') - 1
629                         call s:setCursorPosition(oldPosition)
631                         if line <= 0
632                                 let line = line('$')
633                         endif
634                 endif
636                 return line
637         endfunction
639         " Function s:getName() {{{2
640         function s:getName(line)
641                 let name = ''
643                 let line = getline(a:line)
645                 if line != -1
646                         let name = substitute(line, '^\t*\([^\t].\{-}\)\%(\%(\\\)\@<!\%(=\| \).*\|$\)', '\1', '')
647                 endif
649                 return name
650         endfunction
652         " Function s:getPath() {{{2
653         function s:getPath(line)
654                 let path = s:extractPath(a:line)
656                 if !s:isAbsolutePath(path)
657                         let folderLine = s:getFirstFolderLine(a:line)
659                         while folderLine > 0
660                                 let path = s:extractPath(folderLine) . s:osSlash . path
661                                 let folderLine = s:getFirstFolderLine(folderLine)
662                         endwhile
663                 endif
665                 return !s:isAbsolutePath(path) ? '' : resolve(s:unescape(path))
666         endfunction
668         " Function s:getProjectLine() {{{2
669         function s:getProjectLine(line)
670                 let line = 0
672                 let indent = indent(a:line)
674                 if indent >= 0
675                         let line = indent == 0 ? a:line : search('^[^\t]\+$', 'bnW')
676                 endif
678                 return line
679         endfunction
681         " Function s:getProjectName() {{{2
682         function s:getProjectName(line)
683                 let line = a:line
685                 while indent(line) > 0
686                         let line = s:getFirstFolderLine(line)
687                 endwhile
689                 return s:getName(line)
690         endfunction
692         " Function s:getProjectPath() {{{2
693         function s:getProjectPath(line)
694                 let path = ''
696                 let line = s:getProjectLine(a:line)
698                 if line > 0
699                         let path = s:getPath(line)
700                 endif
702                 return path
703         endfunction
705         " Function s:extractAttributeFromLine() {{{2
706         function s:extractAttributeFromLine(name, line)
707                 return !s:hasAttribute(a:name, a:line) ? '' : substitute(getline(a:line), '.*\%(\%(\\\)\@<! \)\+' . a:name . '="\([^"]\{-}\)".*', '\1', '')
708         endfunction
710         " Function s:extractAttribute() {{{2
711         function s:extractAttribute(name, line)
712                 let attribute = ''
714                 let line = a:line
716                 while line > 0 && !s:hasAttribute(a:name, line)
717                         let line = s:getFirstFolderLine(line)
718                 endwhile
720                 if s:hasAttribute(a:name, line)
721                         let attribute = s:extractAttributeFromLine(a:name, line)
722                 endif
724                 return attribute
725         endfunction
727         " Function s:extractPathFromLine() {{{2
728         function s:extractPathFromLine(line)
729                 let path = ''
731                 if s:hasPath(a:line)
732                         let lineContent = substitute(getline(a:line), '^\t*[^\t].\{-}\%(\\\)\@<!\%( \|=\)', '', '')
734                         let path = substitute(lineContent, '^\(.\{-}\)\%(\\\)\@<! .*$', '\1', '')
735                 endif
737                 return path
738         endfunction
740         " Function s:extractPath() {{{2
741         function s:extractPath(line)
742                 let path = s:extractPathFromLine(a:line)
744                 if path == ''
745                         let path = s:getName(a:line)
746                 endif
748                 return path
749         endfunction
751         " Function s:extractCdFromLine() {{{2
752         function s:extractCdFromLine(line, resolveDot)
753                 let cd = s:extractAttributeFromLine('cd', a:line)
755                 return cd != '.' || !a:resolveDot ? cd : s:getPath(a:line)
756         endfunction
758         " Function s:extractCd() {{{2
759         function s:extractCd(line)
760                 let cd = ''
761                 let line = a:line
763                 while line > 0
764                         let cd = s:extractCdFromLine(line, 1)
765                         let line = cd != '' ? 0 : s:getFirstFolderLine(line)
766                 endwhile
768                 return cd
769         endfunction
771         " Function s:extractFilterFromLine() {{{2
772         function s:extractFilterFromLine(line)
773                 return s:extractAttributeFromLine('filter', a:line)
774         endfunction
776         " Function s:extractFilter() {{{2
777         function s:extractFilter(line)
778                 return s:extractAttribute('filter', a:line)
779         endfunction
781         " Function s:extractMappingsFromLine() {{{2
782         function s:extractMappingsFromLine(line)
783                 let mappings = {}
785                 let line = getline(a:line)
787                 if line != ''
788                         let index = 1
790                         while index <= 12
791                                 if s:hasMapping('F' . index, a:line)
792                                         let mapping = substitute(line, '.*\s\+F' . index . '="\([^"]\+\)".*', '\1', '')
794                                         if mapping != ''
795                                                 let mappings[index] = mapping
796                                         endif
797                                 endif
799                                 let index += 1
800                         endwhile
801                 endif
803                 return mappings
804         endfunction
806         " Function s:extractMappings() {{{2
807         function s:extractMappings(line)
808                 let mappings = {}
810                 let key = 1
812                 while key <= 12
813                         let mapping = ''
815                         let line = a:line
817                         while line > 0 && !s:hasMapping('F' . key, line)
818                                 let line = s:getFirstFolderLine(line)
819                         endwhile
821                         if line > 0
822                                 let mapping = s:extractAttributeFromLine('F' . key, line)
824                                 if has_key(mappings, line)
825                                         let mappings[line][key] = mapping
826                                 else
827                                         let mappings[line] = { key : mapping }
828                                 endif
829                         endif
831                         let key += 1
832                 endwhile
834                 return mappings
835         endfunction
837         " Function s:extractMakeFromLine() {{{2
838         function s:extractMakeFromLine(line)
839                 return s:extractAttributeFromLine('make', a:line)
840         endfunction
842         " Function s:extractMake() {{{2
843         function s:extractMake(line)
844                 return s:extractAttribute('make', a:line)
845         endfunction
847         " Function s:extractErrorFormatFromLine() {{{2
848         function s:extractErrorFormatFromLine(line)
849                 return s:extractAttributeFromLine('errorformat', a:line)
850         endfunction
852         " Function s:extractErrorFormat() {{{2
853         function s:extractErrorFormat(line)
854                 return s:extractAttribute('errorformat', a:line)
855         endfunction
857         " Function s:extractTestFromLine() {{{2
858         function s:extractTestFromLine(line)
859                 return s:extractAttributeFromLine('test', a:line)
860         endfunction
862         " Function s:extractTest() {{{2
863         function s:extractTest(line)
864                 return s:extractAttribute('test', a:line)
865         endfunction
867         " Function s:extractRefreshFromLine() {{{2
868         function s:extractRefreshFromLine(line)
869                 return s:extractAttributeFromLine('refresh', a:line)
870         endfunction
872         " Function s:extractRefresh() {{{2
873         function s:extractRefresh(line)
874                 return s:extractAttribute('refresh', a:line)
875         endfunction
877         " Function s:inputType() {{{2
878         function s:inputType(message)
879                 let type = ''
881                 return type
882         endfunction
884         " Function s:inputName() {{{2
885         function s:inputName(message)
886                 let name = s:input(a:message, '')
888                 if name == ''
889                         throw 'Name must not be empty.'
890                 else
891                         return name
892                 endif
893         endfunction
895         " Function s:isAbsolutePath() {{{2
896         function s:isAbsolutePath(path)
897                 return s:windowsOs ? a:path =~ '^.:\(\\\|\/\)' : a:path =~ '^/'
898         endfunction
900         " Function s:inputPath() {{{2
901         function s:inputPath(message, defaultPath, emptyPath)
902                 let path = s:input(a:message, a:defaultPath, 'file')
904                 if a:emptyPath == 0 && path == ''
905                         throw 'Path must not be empty.'
906                 else
907                         let path = expand(path, ':p')
909                         if !s:isAbsolutePath(path)
910                                 throw 'Path must be absolute.'
911                         else
912                                 return path
913                         endif
914                 endif
915         endfunction
917         " Function s:inputRealPath() {{{2
918         function s:inputRealPath(message, defaultPath, emptyPath)
919                 let path = s:inputPath(a:message, a:defaultPath, a:emptyPath)
921                 if !s:pathExists(path)
922                         throw 'Path ''' . path . ''' does not exist.'
923                 else
924                         return resolve(path)
925                 endif
926         endfunction
928         " Function s:inputCd() {{{2
929         function s:inputCd(message, path, value)
930                 let cd = s:input(a:message, a:value, 'file')
932                 if cd != ''
933                         if cd != '.'
934                                 let cd = fnamemodify(s:cleanPath(cd), ':p')
936                                 if cd == a:path
937                                         let cd = '.'
938                                 endif
939                         endif
941                         if cd != '.' && getftype(cd) != 'dir'
942                                 throw 'Working directory ' . cd . ' of project ' . a:project['name'] . ' is invalid.'
943                         else
944                                 let cd = resolve(cd)
945                         endif
946                 endif
948                 return cd
949         endfunction
951         " Function s:inputFilter() {{{2
952         function s:inputFilter(message, value)
953                 return s:input(a:message, a:value)
954         endfunction
956         " Function s:inputMappings() {{{2
957         function s:inputMappings(message, mappings)
958                 let mappings = {}
960                 let inputs = a:mappings
962                 if empty(inputs)
963                         let inputs = {1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: ''}
964                 endif
966                 let index = 1
968                 while index >= 1 && index <= 13
969                         let list = [a:message]
970                         let keys = {}
972                         let index = 1
974                         while index <= 12
975                                 if has_key(inputs, index)
976                                         let list = add(list, index . '. F' . index . ': ' . inputs[index])
977                                         let keys[index] = index
978                                 endif
980                                 let index += 1
981                         endwhile
983                         let index = inputlist(list)
985                         if has_key(keys, index)
986                                 let inputs[keys[index]] = s:input('Mapping for F' . keys[index] . ': ', !has_key(inputs, index) ? '' : inputs[index])
987                                 redraw
988                         endif
989                 endwhile
991                 for [key, mapping] in items(inputs)
992                         let mappings[key] = mapping
993                 endfor
995                 call filter(mappings, 'v:val != ''''')
997                 return mappings
998         endfunction
1000         " Function s:inputMake() {{{2
1001         function s:inputMake(message, value)
1002                 return s:input(a:message, a:value)
1003         endfunction
1005         " Function s:inputErrorFormat() {{{2
1006         function s:inputErrorFormat(message, value)
1007                 return s:input(a:message, a:value)
1008         endfunction
1010         " Function s:inputTest() {{{2
1011         function s:inputTest(message, value)
1012                 return s:input(a:message, a:value)
1013         endfunction
1015         "Function s:defineProject()
1016         function s:defineProject()
1017                 let myprojects = {}
1018                 let attributes = {'path': '', 'filter': '', 'make': '', 'errorFormat': '', 'mappings': {}, 'test': ''}
1020                 call s:readMyProjectsPreferences()
1022                 if len(s:preferences) > 0
1023                         let availableTypes = keys(s:preferences)
1024                         let index = 1
1025                         let types = ['Type of project: ']
1027                         for type in availableTypes
1028                                 call add(types, index . '. ' . type)
1029                                 let index += 1
1030                         endfor
1032                         try
1033                                 call extend(attributes, s:preferences[availableTypes[inputlist(types) - 1]], 'force')
1034                         catch /.*/
1035                                 throw 'Project type is invalid.'
1036                         endtry
1037                 endif
1039                 let name = s:inputName('Name of new project: ')
1040                 let myprojects[name] = {'attributes': {}, 'files': []}
1041                 let myprojects[name]['attributes']['path'] = s:inputRealPath('Path of project ''' . name . ''': ', attributes['path'], 0)
1042                 let myprojects[name]['attributes']['cd'] = s:inputCd('Working directory of project ''' . name . ''': ', myprojects[name]['attributes']['path'], myprojects[name]['attributes']['path'])
1043                 let myprojects[name]['attributes']['filter'] = s:inputFilter('Filter of project ''' . name . ''': ', attributes['filter'])
1044                 let myprojects[name]['attributes']['make'] = s:inputMake('Make of project ''' . name . ''': ', attributes['make'])
1045                 let myprojects[name]['attributes']['errorformat'] = s:inputErrorFormat('Error format of project ''' . name . ''': ', attributes['errorFormat'])
1046                 let myprojects[name]['attributes']['mappings'] = s:inputMappings('Mappings of project ''' . name . ''': ', attributes['mappings'])
1047                 let myprojects[name]['attributes']['test'] = s:inputTest('Test extension of project ''' . name . ''': ', attributes['test'])
1049                 return [name, myprojects]
1050         endfunction
1052         " Function s:create() {{{2
1053         function s:create(line)
1054                 let indent = s:indent(a:line)
1056                 if indent >= 0
1057                         try
1058                                 let project = s:defineProject()
1060                                 call s:echo('Create project ''' . project[0] . ''' from path ''' . project[1][project[0]]['attributes']['path'] . '''...')
1061                                 call s:put(s:buildMyProjects('', project[1][project[0]]['attributes']['path'], project[1], '', indent), a:line)
1062                                 call s:message('Project ''' . project[0] . ''' created.')
1063                                 call s:echo(s:getPath(a:line))
1064                         catch /.*/
1065                                 call s:error(v:exception)
1066                         endtry
1067                 endif
1068         endfunction
1070         " Function s:refresh() {{{2
1071         function s:refresh(line, refreshFolder)
1072                 let line = a:line
1074                 if a:refreshFolder
1075                         let line = s:isFolder(a:line) ? a:line : s:getFirstFolderLine(a:line)
1076                 endif
1078                 let path = s:getPath(line)
1080                 if path != ''
1081                         let indent = s:indent(line)
1083                         if indent >= 0
1084                                 call s:echo('Do refresh of ''' . path . ''' in project ''' . s:getProjectName(line) . '''...')
1086                                 let myprojects = s:buildMyProjects(substitute(path, '[^' . s:osSlash . ']\+$', '', ''), s:extractFilter(line), s:getMyProjects(line), s:extractRefresh(line), indent)
1088                                 let range = line
1089                                 let foldlevel = 0
1090                                 
1091                                 if s:isFolder(line)
1092                                         let range .= ',' . s:getLastFolderLine(line)
1093                                         let foldlevel = foldlevel(line)
1094                                 endif
1096                                 silent! execute ':' . range . 'd'
1098                                 if myprojects != ''
1099                                         call s:put(myprojects, line)
1101                                         silent! execute ':' . range . 'foldclose!'
1103                                         while foldlevel > 0
1104                                                 silent normal! zo
1105                                                 let foldlevel -= 1
1106                                         endwhile
1108                                 endif
1110                                 call s:autowrite()
1112                                 call s:echo('Refresh done for ''' . path . '''.')
1113                         endif
1114                 endif
1115         endfunction
1117         " Function s:open() {{{2
1118         function s:open(command)
1119                 let line = line('.')
1121                 if s:isFolder(line)
1122                         silent normal! za
1123                 else
1124                         try
1125                                 call s:edit(a:command, line)
1126                         catch /.*/
1127                                 call s:error(v:exception)
1128                         endtry
1129                 endif
1130         endfunction
1132         " Function s:delete() {{{2
1133         function s:delete(line)
1134                 let path = s:getPath(a:line)
1136                 if path != ''
1137                         if getftype(path) == 'file' && delete(path) == 0
1138                                 call s:refresh(a:line, 1)
1139                         else
1140                                 call s:error('Unable to delete ' . path . '.')
1141                         endif
1142                 endif
1143         endfunction
1145         " Function s:grep() {{{2
1146         function s:grep(line)
1147                 let path = s:getPath(a:line)
1149                 if path != ''
1150                         let pattern = s:input('Grep in ''' . path . ''': ', '')
1152                         if pattern != ''
1153                                 if s:isFolder(a:line)
1154                                         let files = s:getFiles(path, s:extractFilter(a:line))
1155                                 else
1156                                         let files = path
1157                                 endif
1159                                 if files != ''
1160                                         let s:loadAttributes = 0
1162                                         try
1163                                                 call s:echo('Do grep on ''' . path . ''' with pattern ''' . pattern . '''...')
1164                                                 mkview
1165                                                 silent execute 'vimgrep /' . escape(pattern, '/') . '/jg ' . files
1166                                                 loadview
1167                                                 call s:echo('Grep done on ''' . path . ''' with pattern ''' . pattern . '''.')
1168                                                 silent cw
1169                                         catch /E480/
1170                                                 call s:error('No match found for grep with ''' . pattern . ''' in ''' . path . '''.')
1171                                         catch
1172                                                 call s:error(v:exception)
1173                                         endtry
1175                                         let s:loadAttributes = 1
1176                                 endif
1177                         endif
1178                 endif
1179         endfunction
1181         " Function s:explore() {{{2
1182         function s:explore(mode)
1183                 let line = line('.')
1185                 if !s:isFolder(line)
1186                         let line = s:getFirstFolderLine(line)
1187                 endif
1189                 if line > 0
1190                         let path = s:getPath(line)
1192                         if path != ''
1193                                 call s:goToAnEditionWindow()
1194                                 silent execute a:mode . 'xplore ' . path
1195                         endif
1196                 endif
1197         endfunction
1199         " Function s:getTagsGenerator() {{{2
1200         function s:setTagsGenerator()
1201                 for generator in ['exuberant-ctags', 'exctags', 'ctags', 'ctags.exe', 'tags']
1202                         if executable(generator)
1203                                 let g:myprojects_tags_generator = generator
1204                                 break
1205                         endif
1206                 endfor
1207         endfunction
1209         " Function s:generateTags() {{{2
1210         function s:generateTags(line)
1211                 if g:myprojects_tags_file != ''
1212                         if g:myprojects_tags_generator == ''
1213                                 call s:setTagsGenerator()
1214                         endif
1216                         if !executable(g:myprojects_tags_generator)
1217                                 call s:error('Unable to find a tags generator, please define g:myprojects_tags_generator variable.')
1218                         else
1219                                 let rootPath = s:getProjectPath(a:line)
1221                                 if rootPath != ''
1222                                         let tagsPath = rootPath . s:osSlash . g:myprojects_tags_file
1224                                         try
1225                                                 call s:echo('Generate tags file in ''' . tagsPath . ''' for project ''' . s:getProjectName(a:line) . '''...')
1226                                                 call s:system(g:myprojects_tags_generator, '-f ' . tagsPath . ' -R ' . rootPath)
1227                                                 call s:message('Tags file generated for project ''' . s:getProjectName(a:line) . ''' and stored in ''' . tagsPath . '''.')
1229                                                 if &tags !~ '^' . tagsPath . ',\?'
1230                                                         silent execute 'set tags=' . tagsPath . ',' . &tags
1231                                                 endif
1232                                         catch /.*/
1233                                                 call s:message('Unable to generate tags file for project ''' . s:getProjectName(a:line) . ''' : ' . v:exception)
1234                                         endtry
1235                                 endif
1236                         endif
1237                 endif
1238         endfunction
1240         " Function s:edit() {{{2
1241         function s:edit(command, line)
1242                 let path = s:getPath(a:line)
1243                 let projectPath = s:getProjectPath(a:line)
1244                 let projectName = s:getProjectName(a:line)
1245                 let cd = s:extractCd(a:line)
1246                 let mappings = s:extractMappings(a:line)
1247                 let make = s:extractMake(a:line)
1248                 let errorFormat = s:extractErrorFormat(a:line)
1249                 let test = s:extractTest(a:line)
1250                 let type = getftype(path)
1252                 if type == ''
1253                         let head = fnamemodify(path, ':h')
1255                         let headType = getftype(head)
1257                         if headType == ''
1258                                 call s:mkdir(head)
1259                         elseif headType != 'dir'
1260                                 throw 'Path ''' . head . ''' exists but it is not a directory.'
1261                         endif
1262                 elseif type != 'file'
1263                         throw 'Unable to open ''' . path . ''' of type ''' . type . '''.'
1264                 elseif !filereadable(path)
1265                         throw 'Unable to read file ''' . path . '''.'
1266                 endif
1268                 if g:myprojects_auto_resize
1269                         call s:setWindowWidth(g:myprojects_width)
1270                 endif
1271         
1272                 if g:myprojects_auto_close
1273                         call s:closeMyProjectsWindow()
1274                 endif
1276                 let window = bufwinnr('^' . path . '$')
1278                 if window != -1
1279                         silent execute window . 'wincmd w'
1280                         silent execute 'buffer ' . path
1281                 else
1282                         call s:goToAnEditionWindow()
1284                         let command =  a:command . ' ' . fnameescape(path)
1286                         try
1287                                 silent execute command
1288                         catch E37
1289                                 if s:input('Save ''' . expand(bufname('%'), ':p') . ''' and load ''' . path . ''' ? [y/N]: ', '') != 'y'
1290                                         return 0
1291                                 else
1292                                         write
1293                                         silent execute command
1294                                 endif
1295                         endtry
1296                 endif
1298                 if g:myprojects_tags_file != '' && projectPath != ''
1299                         let tagsPath = projectPath . s:osSlash . g:myprojects_tags_file
1301                         if getftype(tagsPath) == 'file'
1302                                 if &tags !~ '^' . tagsPath . ',\?'
1303                                         silent execute 'set tags=' . tagsPath . ',' . &tags
1304                                 endif
1305                         endif
1306                 endif
1308                 if cd != ''
1309                         let cd = s:unescape(cd)
1311                         if getftype(cd) != 'dir'
1312                                 throw 'Unable to change directory to ' . cd . '.'
1313                         else
1314                                 let cd = resolve(cd)
1316                                 if getftype(cd) != 'dir'
1317                                         call s:warningMessage('Path ''' . cd . ''' is not a valid working directory.')
1318                                 else
1319                                         let cd = fnameescape(cd)
1321                                         try
1322                                                 silent execute 'lcd ' . cd
1324                                                 if !exists('#' . s:plugin . '#BufEnter#<buffer>')
1325                                                         silent execute 'augroup ' . s:plugin
1326                                                         silent execute 'au! BufEnter <buffer> lcd ' . cd
1327                                                         silent augroup END
1328                                                 endif
1329                                         catch /E472/
1330                                                 call s:warningMessage('Unable to go to working directory ''' . cd . '''.')
1331                                         endtry
1332                                 endif
1333                         endif
1334                 endif
1336                 for [line, mapping] in items(mappings)
1337                         for [key, value] in items(mapping)
1338                                 silent execute 'nnoremap <buffer> <silent> <F' . key . '> ' . escape(expand(value), '|')
1339                         endfor
1340                 endfor
1342                 if make != ''
1343                         silent execute 'setlocal makeprg=' . s:escape(make)
1344                 endif
1346                 if errorFormat != ''
1347                         silent execute 'setlocal errorformat=' . s:escape(errorFormat)
1348                 endif
1350                 if test != ''
1351                         let tail = fnamemodify(path, ':t')
1352                         let rootTail = fnamemodify(tail, ':r')
1354                         while rootTail != tail
1355                                 let tail = rootTail
1356                                 let rootTail = fnamemodify(tail, ':r')
1357                         endwhile
1359                         silent execute 'nnoremap <silent> <buffer> <LocalLeader>et :call <SID>openTest(''split'', ''' . path . ''', ''' . tail . test . ''')<CR>'
1360                 endif
1362                 setlocal more
1364                 if !hasmapto('<Plug>MyProjectsGoTo')
1365                         map <buffer> <silent> <C-Tab> <Plug>MyProjectsGoTo
1366                 endif
1368                 nnoremap <silent> <buffer> <LocalLeader>ra :call <SID>openFromMyProjectsWindow('edit', fnamemodify(bufname('%'), ':p'))<CR>
1370                 silent execute 'nnoremap <buffer> <silent> <LocalLeader>b :call <SID>toggleProjectBuffers(''' . projectName. ''', ''' . projectPath . ''', '''')<CR>'
1372                 let b:myprojectsAttributesLoaded = 1
1373         endfunction
1375         " Function s:append() {{{2
1376         function s:append(line)
1377                 let path = s:getPath(a:line)
1379                 if path != ''
1380                         if getftype(path) != 'file' || !filereadable(path)
1381                                 call s:error('Unable to read file ' . path . '.')
1382                         else
1383                                 call s:goToAnEditionWindow()
1384                                 silent execute ':r ' . path
1385                                 silent normal! k
1386                                 silent normal! dd
1387                         endif
1388                 endif
1389         endfunction
1391         " Function s:getNestedAttribute() {{{2
1392         function s:getNestedAttribute(name, line)
1393                 let attribute = []
1395                 let line = a:line
1397                 if !exists('*s:has' . a:name)
1398                         while line > 0 && empty(attribute)
1399                                 if s:hasAttribute(a:name, line)
1400                                         let attribute = [line, s:extractAttribute(a:name, line)]
1401                                 else
1402                                         let line = s:getFirstFolderLine(line)
1403                                 endif
1404                         endwhile
1406                         if empty(attribute) && s:hasAttribute(a:name, line)
1407                                 let attribute = [line, s:extractAttribute(a:name, line)]
1408                         endif
1409                 else
1410                         while line > 0 && empty(attribute)
1411                                 if s:has{a:name}(line)
1412                                         let attribute = [line, s:extract{a:name}(line)]
1413                                 else
1414                                         let line = s:getFirstFolderLine(line)
1415                                 endif
1416                         endwhile
1418                         if empty(attribute) && s:has{a:name}(line)
1419                                 let attribute = [line, s:extract{a:name}(line)]
1420                         endif
1421                 endif
1423                 return attribute
1424         endfunction
1426         " Function s:getNestedPath() {{{2
1427         function s:getNestedPath(line)
1428                 return s:getNestedAttribute('Path', a:line)
1429         endfunction
1431         " Function s:getNestedCd() {{{2
1432         function s:getNestedCd(line)
1433                 return s:getNestedAttribute('Cd', a:line)
1434         endfunction
1436         " Function s:getNestedMappings() {{{2
1437         function s:getNestedMappings(line)
1438                 let mappings = {}
1440                 let index = 1
1442                 while index <= 12
1443                         let mapping = s:getNestedAttribute('F' . index, a:line)
1445                         if !empty(mapping)
1446                                 let mappings[index] = mapping
1447                         endif
1449                         let index += 1
1450                 endwhile
1452                 return mappings
1453         endfunction
1455         " Function s:getNestedFilter() {{{2
1456         function s:getNestedFilter(line)
1457                 return s:getNestedAttribute('Filter', a:line)
1458         endfunction
1460         " Function s:getNestedMake() {{{2
1461         function s:getNestedMake(line)
1462                 return s:getNestedAttribute('Make', a:line)
1463         endfunction
1465         " Function s:getNestedErrorFormat() {{{2
1466         function s:getNestedErrorFormat(line)
1467                 return s:getNestedAttribute('errorformat', a:line)
1468         endfunction
1470         " Function s:getNestedTest() {{{2
1471         function s:getNestedTest(line)
1472                 return s:getNestedAttribute('test', a:line)
1473         endfunction
1475         " Function s:hasAttribute() {{{2
1476         function s:hasAttribute(name, line)
1477                 return getline(a:line) =~ '.*\%(\%(\\\)\@<! \)\+' . a:name . '="[^"]\{-}"'
1478         endfunction
1480         " Function s:hasPath() {{{2
1481         function s:hasPath(line)
1482                 return substitute(getline(a:line), '^\t*[^\t].\{-}\(\%(\\\)\@<!\%( \|=\)\)', '\1', '') =~ '^='
1483         endfunction
1485         " Function s:hasCd() {{{2
1486         function s:hasCd(line)
1487                 return s:hasAttribute('cd', a:line)
1488         endfunction
1490         " Function s:hasFilter() {{{2
1491         function s:hasFilter(line)
1492                 return s:hasAttribute('filter', a:line)
1493         endfunction
1495         " Function s:hasMapping() {{{2
1496         function s:hasMapping(mapping, line)
1497                 return s:hasAttribute(a:mapping, a:line)
1498         endfunction
1500         " Function s:hasMake() {{{2
1501         function s:hasMake(line)
1502                 return s:hasAttribute('make', a:line)
1503         endfunction
1505         " Function s:hasErrorFormat() {{{2
1506         function s:hasErrorFormat(line)
1507                 return s:hasAttribute('errorformat', a:line)
1508         endfunction
1510         " Function s:hasTest() {{{2
1511         function s:hasTest(line)
1512                 return s:hasAttribute('test', a:line)
1513         endfunction
1515         " Function s:setPath() {{{2
1516         function s:setPath(line)
1517                 if !s:hasPath(a:line)
1518                         let currentPath = s:getPath(a:line)
1520                         if currentPath != ''
1521                                 let name = s:getName(a:line)
1523                                 try
1524                                         let newPath = s:cleanPath(s:inputRealPath('Set path for ''' . name . ''': ', '', 1))
1526                                         if newPath != '' && newPath != currentPath
1527                                                 call s:echo('Set path with ''' . newPath . ''' on ''' . name . '''...')
1528                                                 call s:substitute(a:line, '\(^\t*[^\t]\%(\\ \|\f\)\+\)', '\1=' . newPath, '')
1529                                                 call s:refresh(pathLine, 0)
1530                                                 call s:message('Path set with ''' . newPath . ''' on ''' . name . '''.')
1531                                         endif
1532                                 catch /.*/
1533                                         call s:error(v:exception)
1534                                 endtry
1535                         endif
1536                 endif
1537         endfunction
1539         " Function s:setCd() {{{2
1540         function s:setCd(line)
1541                 if !s:hasCd(a:line)
1542                         let path = s:getPath(a:line)
1544                         if path != ''
1545                                 let cd = s:getNestedCd(a:line)
1546                                 let currentCd = empty(cd) ? '' : cd[1]
1548                                 try
1549                                         let newCd = s:inputCd('Set working directory for ''' . path . ''': ', path, currentCd)
1551                                         if newCd != '' && newCd != currentCd
1552                                                 call s:echo('Set working directory with ''' . newCd . ''' on ''' . path . '''...')
1553                                                 call s:updateAttribute(a:line, 'cd', s:escape(newCd))
1554                                                 call s:autowrite()
1555                                                 call s:message('Working directory set with ''' . newCd . ''' on ''' . path . '''.')
1556                                         endif
1557                                 catch /.*/
1558                                         call s:error(v:exception)
1559                                 endtry
1560                         endif
1561                 endif
1562         endfunction
1564         " Function s:setFilter() {{{2
1565         function s:setFilter(line)
1566                 let line = s:isFolder(a:line) ? a:line : s:getFirstFolderLine(a:line)
1568                 if line > 0 && !s:hasFilter(line)
1569                         let path = s:getPath(line)
1571                         if path != ''
1572                                 let filter = s:getNestedFilter(line)
1573                                 let currentFilter = empty(filter) ? '' : filter[1]
1574                                 let newFilter = s:inputFilter('Set filter for ''' . path . ''': ', currentFilter)
1576                                 if newFilter != currentFilter
1577                                         call s:echo('Set filter with ''' . newFilter . ''' on ''' . path . '''...')
1578                                         call s:updateAttribute(line, 'filter', newFilter)
1579                                         call s:updateRefresh(line, '')
1580                                         call s:refresh(line, 0)
1581                                         call s:message('Filter set with ''' . newFilter . ''' on ''' . path . '''.')
1582                                 endif
1583                         endif
1584                 endif
1585         endfunction
1587         " Function s:setMappings() {{{2
1588         function s:setMappings(line)
1589                 if !s:hasMapping('F[1-9][0-2]\?', a:line)
1590                         let path = s:getPath(a:line)
1592                         if path != ''
1593                                 for [key, mapping] in items(s:inputMappings('Set mapping for ''' . path . ''': ', {}))
1594                                         if mapping != ''
1595                                                 call s:echo('Set mappings on ''' . path . '''...')
1596                                                 call s:updateAttribute(a:line, 'F' . key, mapping)
1597                                                 call s:autowrite()
1598                                                 call s:message('Mappings set on ''' . path . '''.')
1599                                         endif
1600                                 endfor
1601                         endif
1602                 endif
1603         endfunction
1605         " Function s:setMake() {{{2
1606         function s:setMake(line)
1607                 if !s:hasMake(a:line)
1608                         let path = s:getPath(a:line)
1610                         if path != ''
1611                                 let make = s:getNestedMake(a:line)
1612                                 let currentMake = empty(make) ? '' : make[1]
1614                                 try
1615                                         let newMake = s:inputMake('Set make for ''' . path . ''': ', currentMake)
1617                                         if newMake != currentMake
1618                                                 call s:echo('Set make with ''' . newMake . ''' on ''' . path . '''...')
1619                                                 call s:updateAttribute(a:line, 'make', newMake)
1620                                                 call s:autowrite()
1621                                                 call s:message('Make set with ''' . newMake . ''' on ''' . path . '''.')
1622                                         endif
1623                                 catch /.*/
1624                                         call s:error(v:exception)
1625                                 endtry
1626                         endif
1627                 endif
1628         endfunction
1630         " Function s:setErrorFormat() {{{2
1631         function s:setErrorFormat(line)
1632                 if !s:hasErrorFormat(a:line)
1633                         let path = s:getPath(a:line)
1635                         if path != ''
1636                                 let errorFormat = s:getNestedErrorFormat(a:line)
1637                                 let currentErrorFormat = empty(errorFormat) ? '' : errorFormat[1]
1639                                 try
1640                                         let newErrorFormat = s:inputErrorFormat('Set error format for ''' . path . ''': ', currentErrorFormat)
1642                                         if newErrorFormat != currentErrorFormat
1643                                                 call s:echo('Set error format with ''' . newErrorFormat . ''' on ''' . path . '''...')
1644                                                 call s:updateAttribute(a:line, 'errorformat', newErrorFormat)
1645                                                 call s:autowrite()
1646                                                 call s:message('Error format set with ''' . newErrorFormat . ''' on ''' . path . '''.')
1647                                         endif
1648                                 catch /.*/
1649                                         call s:error(v:exception)
1650                                 endtry
1651                         endif
1652                 endif
1653         endfunction
1655         " Function s:setTest() {{{2
1656         function s:setTest(line)
1657                 if !s:hasTest(a:line)
1658                         let path = s:getPath(a:line)
1660                         if path != ''
1661                                 let test = s:getNestedTest(a:line)
1662                                 let currentTest = empty(test) ? '' : test[1]
1664                                 try
1665                                         let newTest = s:inputTest('Set test for ''' . path . ''': ', currentTest)
1667                                         if newTest != currentTest
1668                                                 call s:echo('Set test with ''' . newTest . ''' on ''' . path . '''...')
1669                                                 call s:updateAttribute(a:line, 'test', newTest)
1670                                                 call s:autowrite()
1671                                                 call s:message('Test set with ''' . newTest . ''' on ''' . path . '''.')
1672                                         endif
1673                                 catch /.*/
1674                                         call s:error(v:exception)
1675                                 endtry
1676                         endif
1677                 endif
1678         endfunction
1680         " Function s:updateAttribute() {{{2
1681         function s:updateAttribute(line, attribute, value)
1682                 if getline(a:line) =~ '\s\+' . a:attribute . '="[^"]\+"'
1683                         if a:value == '' && a:attribute != 'filter'
1684                                 call s:substitute(a:line, '\s\+' . a:attribute . '="[^"]\{-}"', '', '')
1685                         else
1686                                 call s:substitute(a:line, '\s\+' . a:attribute . '="[^"]\{-}"', ' ' . a:attribute . '="' . escape(a:value, '\%&') . '"', '')
1687                         endif
1688                 else
1689                         call s:substitute(a:line, '\(^.\+$\)', '\1 ' . a:attribute . '="' . escape(a:value, '\%&') . '"', '')
1690                 endif
1691         endfunction
1693         " Function s:updatePath() {{{2
1694         function s:updatePath(line)
1695                 let path = s:getNestedPath(a:line)
1697                 if !empty(path)
1698                         let [pathLine, currentPath] = path
1700                         try
1701                                 let name = s:getName(pathLine)
1702                                 let newPath = s:cleanPath(s:inputRealPath('Update path for ''' . name . ''': ', '', 1))
1704                                 if newPath != ''
1705                                         if newPath == currentPath
1706                                                 call s:echo('Path not updated for ''' . name . '''.')
1707                                         else
1708                                                 call s:echo('Update path with ''' . newPath . ''' for ''' . name . '''...')
1709                                                 call s:substitute(pathLine, '^.*$', s:getName(pathLine) . '=' . newPath . ' ' . substitute(substitute(getline(pathLine), '^\t*[^\t].\{-}\(\%(\\\)\@<!\%( \|=\)\)', '\1', ''), '^=.\{-}\%(\\\)\@<! \(.*$\)', '\1', ''), '')
1710                                                 call s:refresh(pathLine, 0)
1711                                                 call s:message('Path updated with ''' . newPath . ''' for name ''' . name . '''.')
1712                                 endif
1713                         catch /.*/
1714                                 call s:error(v:exception)
1715                         endtry
1716                 endif
1717         endfunction
1719         " Function s:updateCd() {{{2
1720         function s:updateCd(line)
1721                 let cd = s:getNestedCd(a:line)
1723                 if !empty(cd)
1724                         let [cdLine, currentCd] = cd
1726                         try
1727                                 let path = s:getPath(cdLine)
1728                                 let newCd = s:inputCd('Update working directory for ''' . path . ''': ', path, currentCd)
1730                                 if newCd == currentCd
1731                                         call s:echo('Working directory not updated for ''' . path . '''.')
1732                                 else
1733                                         call s:echo('Update working directory with ''' . newCd . ''' on ''' . path . '''...')
1734                                         call s:updateAttribute(cdLine, 'cd', s:escape(newCd))
1735                                         call s:autowrite()
1736                                         call s:message('Working directory updated with ''' . newCd . ''' on ''' . path . '''.')
1737                                 endif
1738                         catch /.*/
1739                                 call s:error(v:exception)
1740                         endtry
1741                 endif
1742         endfunction
1744         " Function s:updateFilter() {{{2
1745         function s:updateFilter(line)
1746                 let filter = s:getNestedFilter(a:line)
1748                 if !empty(filter)
1749                         let [filterLine, currentFilter] = filter
1751                         try
1752                                 let path = s:getPath(filterLine)
1753                                 let newFilter = s:inputFilter('Update filter for ''' . path . ''': ', currentFilter)
1755                                 if newFilter == currentFilter
1756                                         call s:echo('Filter not updated for ''' . path . '''.')
1757                                 else
1758                                         call s:echo('Update filter with ''' . newFilter . ''' on ''' . path . '''...')
1759                                         call s:updateAttribute(filterLine, 'filter', newFilter)
1760                                         call s:updateRefresh(filterLine, '')
1761                                         call s:refresh(filterLine, 0)
1762                                         call s:message('Filter updated with ''' . newFilter . ''' on ''' . path . '''.')
1763                                 endif
1764                         catch /.*/
1765                                 call s:error(v:exception)
1766                         endtry
1767                 endif
1768         endfunction
1770         " Function s:updateMappings() {{{2
1771         function s:updateMappings(line)
1772                 let currentMappings = s:getNestedMappings(a:line)
1774                 if !empty(currentMappings)
1775                         let path = s:getPath(a:line)
1776                         let lines = {1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: ''}
1777                         let mappings = {1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: ''}
1779                         for [key, value] in items(currentMappings)
1780                                 let lines[key] = value[0]
1781                                 let mappings[key] = value[1]
1782                         endfor
1784                         let newMappings = s:inputMappings('Update mapping: ', mappings)
1786                         call s:echo('Update mappings on ''' . path . '''...')
1788                         for [key, mapping] in items(newMappings)
1789                                 if has_key(lines, key)
1790                                         call s:updateAttribute(lines[key], 'F' . key, mapping)
1791                                 endif
1792                         endfor
1794                         call s:autowrite()
1795                         call s:message('Mappings updated on ''' . path . '''.')
1796                 endif
1797         endfunction
1799         " Function s:updateMake() {{{2
1800         function s:updateMake(line)
1801                 let make = s:getNestedMake(a:line)
1803                 if !empty(make)
1804                         let [makeLine, currentMake] = make
1806                         try
1807                                 let path = s:getPath(makeLine)
1808                                 let newMake = s:inputMake('Update make for ''' . path . ''': ', currentMake)
1810                                 if newMake == currentMake
1811                                         call s:echo('Make not updated for ''' . path . '''.')
1812                                 else
1813                                         call s:echo('Update make with ''' . newMake . ''' on ''' . path . '''...')
1814                                         call s:updateAttribute(makeLine, 'make', newMake)
1815                                         call s:autowrite()
1816                                         call s:message('Make updated with ''' . newMake . ''' on ''' . path . '''.')
1817                                 endif
1818                         catch /.*/
1819                                 call s:error(v:exception)
1820                         endtry
1821                 endif
1822         endfunction
1824         " Function s:updateErrorFormat() {{{2
1825         function s:updateErrorFormat(line)
1826                 let errorFormat = s:getNestedErrorFormat(a:line)
1828                 if !empty(errorFormat)
1829                         let [errorFormatLine, currentErrorFormat] = errorFormat
1831                         try
1832                                 let path = s:getPath(errorFormatLine)
1833                                 let newErrorFormat = s:inputErrorFormat('Update error format for ''' . path . ''': ', currentErrorFormat)
1835                                 if newErrorFormat == currentErrorFormat
1836                                         call s:echo('Errorformat not updated for ''' . path . '''.')
1837                                 else
1838                                         call s:echo('Update error format with ''' . newErrorFormat . ''' on ''' . path . '''...')
1839                                         call s:updateAttribute(errorFormatLine, 'errorformat', newErrorFormat)
1840                                         call s:autowrite()
1841                                         call s:message('Error format updated with ''' . newErrorFormat . ''' on ''' . path . '''.')
1842                                 endif
1843                         catch /.*/
1844                                 call s:error(v:exception)
1845                         endtry
1846                 endif
1847         endfunction
1850         " Function s:updateTest() {{{2
1851         function s:updateTest(line)
1852                 let test = s:getNestedTest(a:line)
1854                 if !empty(test)
1855                         let [testLine, currentTest] = test
1857                         try
1858                                 let path = s:getPath(testLine)
1859                                 let newTest = s:inputTest('Update test for ''' . path . ''': ', currentTest)
1861                                 if newTest == currentTest
1862                                         call s:echo('Test not updated for ''' . path . '''.')
1863                                 else
1864                                         call s:echo('Update test with ''' . newTest . ''' on ''' . path . '''...')
1865                                         call s:updateAttribute(testLine, 'test', newTest)
1866                                         call s:autowrite()
1867                                         call s:message('Test updated with ''' . newTest . ''' on ''' . path . '''.')
1868                                 endif
1869                         catch /.*/
1870                                 call s:error(v:exception)
1871                         endtry
1872                 endif
1873         endfunction
1876         " Function s:updateRefresh() {{{2
1877         function s:updateRefresh(line, timestamp)
1878                 let path = s:getPath(a:line)
1880                 if path != '' && getftype(path) == 'dir'
1881                         call s:updateAttribute(a:line, 'refresh', a:timestamp)
1882                 endif
1883         endfunction
1885         " Function s:system() {{{2
1886         function s:system(bin, arguments)
1887                 if !exists('*system')
1888                         throw 'Vim system() built-in function is not available.'
1889                 elseif !executable(a:bin)
1890                         throw '''' . a:bin . ''' executable is not available.'
1891                 else
1892                         let output = system(a:bin . ' ' . a:arguments)
1894                         if v:shell_error
1895                                 throw output
1896                         else
1897                                 return output
1898                         endif
1899                 endif
1900         endfunction
1902         " Function s:svn() {{{2
1903         function s:svn(arguments)
1904                 return s:system('svn', a:arguments)
1905         endfunction
1907         " Function s:svnError() {{{2
1908         function s:svnError(error, exception)
1909                 call s:errorMessage(a:error)
1911                 for error in split(a:exception, "\n")
1912                         call s:errorMessage("   " . error)
1913                 endfor
1914         endfunction
1916         " Function s:getSvnStatus() {{{2
1917         function s:getSvnStatus(path)
1918                 let files = filter(split(s:svn('status ' . shellescape(a:path)), "\n"), "v:val =~# '^[[:space:]ACDIMRX?!~L+SKOTB]\\{6}\\s'")
1920                 if g:myprojects_sort_svn
1921                         let files = sort(files)
1922                 endif
1924                 return files
1925         endfunction
1927         " Function s:svnStatus() {{{2
1928         function s:svnStatus(line)
1929                 let path = s:getPath(a:line)
1931                 if path != ''
1932                         try
1933                                 call s:createSvnWindow('Svn status of ''' . path . '''')
1934                                 call s:echo('Do svn status on ''' . path . '''...')
1935                                 call s:putInMyProjectsWindow(s:getSvnStatus(path))
1936                                 call s:message('Svn status done on path ''' . path . '''.')
1937                         catch /.*/
1938                                 call s:svnError('Svn status failed on ''' . path . ''' :', v:exception)
1939                         endtry
1940                 endif
1941         endfunction
1943         " Function s:svnUpdate() {{{2
1944         function s:svnUpdate(line)
1945                 let path = s:getPath(a:line)
1947                 if path != ''
1948                         try
1949                                 call s:createSvnWindow('Svn update of ''' . path . '''')
1950                                 call s:echo('Do svn update on ''' . path . '''...')
1952                                 let files = filter(split(s:svn('update --accept postpone ' . shellescape(path)), "\n"), "v:val =~# '^[ADUCGE[:space:]]\\{4}\\s'")
1954                                 if !empty(files)
1955                                         if g:myprojects_sort_svn
1956                                                 let files = sort(files)
1957                                         endif
1959                                         call s:refresh(a:line, 0)
1960                                 endif
1962                                 call s:putInMyProjectsWindow(files)
1963                                 call s:message('Svn update done on ''' . path . '''.')
1964                         catch /.*/
1965                                 call s:svnError('Svn update failed on ''' . path . ''' :', v:exception)
1966                         endtry
1967                 endif
1968         endfunction
1970         " Function s:svnCommitStepOne() {{{2
1971         function s:svnCommitStepOne(line)
1972                 let path = s:getPath(a:line)
1974                 if path != ''
1975                         try
1976                                 call s:createSvnWindow('Files to commit in ''' . path . '''')
1978                                 call s:echo('Retrieve files to commit in ''' . path . '''...')
1979                                 call s:putInMyProjectsWindow(filter(s:getSvnStatus(path), 'strpart(v:val, 0, 6) =~# "[MDAR]"'))
1980                                 call s:echo('Files to commit retrieved in ''' . path . '''.')
1982                                 setlocal buftype=acwrite
1983                                 setlocal modifiable
1985                                 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnCommitStepTwo()'
1986                         catch /.*/
1987                                 call s:svnError('Unable to retrieve files to revert in ''' . path . ''' :', v:exception)
1988                         endtry
1989                 endif
1990         endfunction
1992         " Function s:svnCommitStepTwo() {{{2
1993         function s:svnCommitStepTwo()
1994                 setlocal nomodified
1996                 let files = getbufline('%', 1, '$')
1998                 call filter(files, 'strpart(v:val, 0, 6) =~# "[MDAR]"')
2000                 if !empty(files)
2001                         let b:files = copy(files)
2003                         call insert(files, '')
2004                         call s:createSvnWindow('Define log message and type :w to commit...')
2005                         call s:putInMyProjectsWindow(files)
2007                         setlocal modifiable
2008                         setlocal buftype=acwrite
2010                         execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnCommitStepThree()'
2011                 endif
2012         endfunction
2014         " Function s:svnCommitStepThree() {{{2
2015         function s:svnCommitStepThree()
2016                 setlocal nomodified
2018                 let files = b:files
2019                 let message = filter(getbufline('%', 1, '$'), "v:val !~# '^" . escape(s:prompt, '[]') . "'")
2021                 silent! bwipeout
2023                 call map(files, "substitute(v:val, '^[^\\s]\\+\\s', '', '')")
2025                 try
2026                         call s:echo('Do svn commit of ' . join(files, ', ') . '...')
2027                         call s:svn('commit ' . join(map(copy(files), 'shellescape(v:val)'), ' ') . ' -m ' . shellescape(join(message, "\n")))
2028                         call s:message('Svn commit done for files ' . join(files, ', ') . '.')
2029                 catch /.*/
2030                         call s:svnError('Svn commit failed on files ''' . join(files, ''', ''') . ''':', v:exception)
2031                 endtry
2032         endfunction
2034         " Function s:svnRevertStepOne() {{{2
2035         function s:svnRevertStepOne(line)
2036                 let path = s:getPath(a:line)
2038                 if path != ''
2039                         try
2040                                 call s:createSvnWindow('Files to revert in ''' . path . ''', type :w to revert them...')
2041                                 call s:echo('Retrieve files to revert in ''' . path . '''...')
2042                                 call s:putInMyProjectsWindow(filter(s:getSvnStatus(path), 'strpart(v:val, 0, 6) =~# ''\%(M\|D\|R\|C\)'''))
2043                                 call s:echo('Files to revert retrieved in ''' . path . '''.')
2045                                 setlocal buftype=acwrite
2046                                 setlocal modifiable
2048                                 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnRevertStepTwo()'
2049                         catch /.*/
2050                                 call s:svnError('Unable to retrieve files to revert in ''' . path . ''':', v:exception)
2051                         endtry
2052                 endif
2053         endfunction
2055         " Function s:svnRevertStepTwo() {{{2
2056         function s:svnRevertStepTwo()
2057                 setlocal nomodified
2059                 let files = filter(getbufline('%', 1, '$'), 'strpart(v:val, 0, 6) =~# ''\%(M\|D\|R\|C\)''')
2061                 silent! execute 'bwipeout ' . s:sid . 'svn'
2063                 if !empty(files)
2064                         call map(files, "substitute(v:val, '^[^\\s]\\+\\s', '', '')")
2066                         try
2067                                 call s:echo('Do svn revert on files ' . join(files, ', ') . '...')
2068                                 call s:svn('revert ' . join(map(copy(files), 'shellescape(v:val)'), ' '))
2069                                 call s:message('Svn revert done for files ' . join(files, ', ') . '.')
2070                         catch /.*/
2071                                 call s:svnError('Svn revert failed on ''' . path . ''':', v:exception)
2072                         endtry
2073                 endif
2074         endfunction
2076         " Function s:svnAddStepOne() {{{2
2077         function s:svnAddStepOne(line)
2078                 let path = s:getPath(a:line)
2080                 if path != ''
2081                         try
2082                                 call s:createSvnWindow('Files to add in ''' . path . ''', type :w to add them...')
2083                                 call s:echo('Retrieve files to add in ''' . path . '''...')
2084                                 call s:putInMyProjectsWindow(filter(s:getSvnStatus(path), 'v:val =~ "^?"'))
2085                                 call s:echo('Files to add retrieved in ''' . path . '''.')
2087                                 setlocal buftype=acwrite
2088                                 setlocal modifiable
2090                                 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnAddStepTwo()'
2091                         catch /.*/
2092                                 call s:svnError('Unable to retrieve files to add in ''' . path . ''':', v:exception)
2093                         endtry
2094                 endif
2095         endfunction
2097         " Function s:svnAddStepTwo() {{{2
2098         function s:svnAddStepTwo()
2099                 setlocal nomodified
2101                 let files = getbufline('%', 1, '$')
2103                 silent! execute 'bwipeout ' . s:sid . 'svn'
2105                 call filter(files, "v:val =~ '^?'")
2107                 if !empty(files)
2108                         call map(files, "substitute(v:val, '^[^\\s]\\+\\s', '', '')")
2110                         try
2111                                 call s:echo('Do svn add for files ' . join(files, ', ') . '...')
2112                                 call s:svn('add ' . join(map(copy(files), 'shellescape(v:val)'), ' '))
2113                                 call s:message('Svn add done for files ' . join(files, ', ') . '.')
2114                         catch /.*/
2115                                 call s:svnError('Svn add failed on ''' . path . ''':', v:exception)
2116                         endtry
2117                 endif
2118         endfunction
2120         " Function s:svnDiff() {{{2
2121         function s:svnDiff(line)
2122                 let path = s:getPath(a:line)
2124                 if path != ''
2125                         let path = resolve(path)
2127                         if getftype(path) != 'file'
2128                                 call s:error('Unable to diff ''' . path . ''' because it is not a file.')
2129                         else
2130                                 try
2131                                         call s:echo('Do svn diff on ''' . path . '''...')
2132                                         let previousVersion = s:svn('cat ' . shellescape(path) . ' -r HEAD')
2133                                         call s:message('Svn diff done on ''' . path . '''.')
2135                                         if !empty(s:diffBuffers)
2136                                                 if bufexists(s:diffBuffers[0]['buffer'])
2137                                                         let window = bufwinnr(s:diffBuffers[0]['buffer'])
2139                                                         silent execute window . 'wincmd w'
2140                                                         silent diffoff
2142                                                         if !s:diffBuffers[0]['wrap']
2143                                                                 setlocal nowrap
2144                                                         endif
2146                                                         silent execute 'setlocal foldmethod=' . s:diffBuffers[0]['foldmethod']
2147                                                         silent execute 'setlocal foldcolumn=' . s:diffBuffers[0]['foldcolumn']
2148                                                         silent wincmd p
2149                                                 endif
2151                                                 if bufexists(s:diffBuffers[1])
2152                                                         silent execute 'bwipeout ' . s:diffBuffers[1]
2153                                                 endif
2154                                         endif
2156                                         let s:diffBuffers = []
2158                                         call s:edit('edit', a:line)
2160                                         call add(s:diffBuffers, {'buffer': bufnr('%'), 'wrap': &wrap, 'foldmethod': &foldmethod, 'foldcolumn': &foldcolumn})
2162                                         let filetype = &filetype
2164                                         diffthis
2166                                         silent vnew
2167                                         silent execute 'setlocal filetype=' . filetype
2168                                         setlocal bufhidden=delete
2169                                         setlocal buftype=nofile
2170                                         setlocal nobuflisted
2171                                         setlocal noswapfile
2172                                         silent! 0put=previousVersion
2173                                         silent! normal! $d
2174                                         silent normal! 1gg
2175                                         setlocal nomodifiable
2177                                         diffthis
2179                                         call add(s:diffBuffers, bufnr('%'))
2181                                         let file = s:prompt .'Svn diff of ''' . path . ''''
2182                                         silent file `=file`
2184                                         let &titlestring = file
2186                                         silent execute 'augroup ' . s:plugin
2187                                         silent execute 'au! BufEnter <buffer> let &titlestring ="' . file . '"'
2188                                         silent augroup END
2190                                         silent normal! ]c
2191                                 catch /.*/
2192                                         call s:error('Unable to diff ''' . path . ''' : ' . v:exception . '.')
2193                                 endtry
2194                         endif
2195                 endif
2196         endfunction
2198         " Function s:svnBlame() {{{2
2199         function s:svnBlame(line)
2200                 let path = s:getPath(a:line)
2202                 if path != ''
2203                         let path = resolve(path)
2205                         if getftype(path) != 'file'
2206                                 call s:error('Unable to blame ''' . path . ''' because it is not a file.')
2207                         else
2208                                 try
2209                                         call s:echo('Do svn blame on ''' . path . '''...')
2210                                         let output = s:svn('blame -v ' . shellescape(path))
2211                                         call s:message('Svn blame on ''' . path . ''' done.')
2213                                         let blame = split(output, "\n")
2214                                         call map(blame, 'substitute(v:val, "^\\([^)]\\+)\\s\\).*$", "\\1|", "")')
2215                                         call map(blame, 'substitute(v:val, "\\s([^)]\\+)", "", "")')
2217                                         call s:edit('edit', a:line)
2218                                         setlocal bufhidden=delete
2219                                         setlocal buftype=nofile
2220                                         setlocal nobuflisted
2221                                         setlocal noswapfile
2222                                         setlocal nofoldenable
2224                                         let buffer = getbufline('%', 1, '$')
2226                                         for line in range(0, len(buffer) - 1)
2227                                                 let buffer[line] = blame[line] . buffer[line]
2228                                         endfor
2230                                         silent! %d
2231                                         silent! 0put=buffer
2232                                         silent! $d
2233                                         silent normal! 1gg
2235                                         setlocal nomodifiable
2237                                         let file = s:prompt .'Svn blame of ''' . path . ''''
2238                                         silent file `=file`
2240                                         let &titlestring = file
2242                                         silent execute 'augroup ' . s:plugin
2243                                         silent execute 'au! BufEnter <buffer> let &titlestring ="' . file . '"'
2244                                         silent augroup END
2245                                 catch /.*/
2246                                         call s:error('Unable to blame ''' . path . ''' : ' . v:exception . '.')
2247                                 endtry
2248                         endif
2249                 endif
2250         endfunction
2252         " Function s:svnCheckout() {{{2
2253         function s:svnCheckout(line)
2254                 let indent = s:indent(a:line)
2256                 if indent >= 0
2257                         try
2258                                 let project = s:defineProject()
2260                                 let svn = s:input('Svn reporitory of project ''' . project[0] . ''': ', '')
2262                                 if svn == ''
2263                                         throw 'Svn repository must not be empty.'
2264                                 else
2265                                         let svnCommand = 'checkout --non-interactive ' . shellescape(svn)
2267                                         let svnUser = s:input('Svn user of project ''' . project[0] . ''': ', '')
2269                                         if svnUser != ''
2270                                                 let svnCommand .=  ' --username ' . shellescape(svnUser)
2272                                                 let svnPassword = s:inputSecret('Svn password of project ''' . project[0] . ''': ', '')
2274                                                 if svnPassword != ''
2275                                                         let svnCommand .= ' --password ' . shellescape(svnPassword)
2276                                                 endif
2277                                         endif
2279                                         let svnCommand .= ' ' . shellescape(project[1][project[0]]['attributes']['path'])
2281                                         try
2282                                                 call s:echo('Do svn checkout of ''' . svn . ''' in ''' . project[1][project[0]]['attributes']['path'] . '''...')
2283                                                 call s:svn(svnCommand)
2284                                                 call s:message('Svn checkout of ''' . svn . ''' in ''' . project[1][project[0]]['attributes']['path'] . ''' done.')
2285                                                 call s:echo('Create project ''' . project[0] . ''' from path ''' . project[1][project[0]]['attributes']['path'] . '''...')
2286                                                 call s:put(s:buildMyProjects('', project[1][project[0]]['attributes']['path'], project[1], '', indent), a:line)
2287                                                 call s:message('Project ''' . project[0] . ''' created.')
2288                                                 call s:echo(s:getPath(a:line))
2289                                         catch /.*/
2290                                                 call s:svnError('Unable to checkout ''' . svn . ''' in ''' . project[1][project[0]]['attributes']['path'] . ''':', v:exception)
2291                                         endtry
2292                                 endif
2293                         catch /.*/
2294                                 call s:error(v:exception)
2295                         endtry
2296                 endif
2297         endfunction
2299         " Function s:svnLog() {{{2
2300         function s:svnLog(line)
2301                 let path = s:getPath(a:line)
2303                 if path != ''
2304                         let path = resolve(path)
2306                         if getftype(path) == ''
2307                                 call s:error('Unable to get log file of ''' . path . ''' because it is not a file or a directory.')
2308                         else
2309                                 try
2310                                         let path = s:getPath(a:line)
2312                                         call s:createSvnWindow('Svn log of ''' . path . '''')
2313                                         call s:echo('Do svn log on ''' . path . '''...')
2315                                         let log = map(split(substitute(substitute(s:svn('log -v ' . shellescape(path)), '\n\n\+\(-\{72}\)', '\n\1', 'g'), '[[:space:]ACDIMRX?!~][[:space:]CM][[:space:]L][[:space:]+][[:space:]SX][[:space:]K].\{-}\(-\{72}\)\@=', '\n', 'g'), "\n"), 'substitute(v:val, "\\\\$", "", "")')
2317                                         let info = s:svn('info ' . shellescape(path))
2318                                         let root = substitute(info, '^.*Repository\sRoot:\s\([^\n]\{-}\)\n.*$', '\1', '')
2319                                         let url = substitute(info, '^.*URL:\s\([^\n]\{-}\)\n.*$', '\1', '')
2320                                         let delta = substitute(url, '^' . root, '', '')
2321                                         let log = map(log, 'substitute(v:val, "^\\s\\+\\([ACDIMRX]\\s\\)' . substitute(url, '^' . root, '', '') . '\\(.\\+\\)$", "\\1      " . path . "\\2", "")')
2322                                         let log = filter(log, 'v:val !~ ''^\s\+[ASDIMRX]''')
2324                                         call s:putInMyProjectsWindow(log)
2325                                         call s:message('Svn log done on path ''' . path . '''.')
2326                                 catch /.*/
2327                                         call s:svnError('Svn status failed on ''' . path . ''' :', v:exception)
2328                                 endtry
2329                         endif
2330                 endif
2331         endfunction
2333         " Function s:refreshSvnConflictWindow() {{{2
2334         function s:refreshSvnConflictWindow(path)
2335                 try
2336                         call s:createSvnConflictWindow('Conflict files in ''' . a:path . '''', a:path)
2337                         call s:echo('Retrieve conflict files in ''' . a:path . '''...')
2338                         call s:putInMyProjectsWindow(filter(s:getSvnStatus(a:path), 'strpart(v:val, 0, 6) =~# ''C'''))
2339                         call s:echo('Conflict files retrieved in ''' . a:path . '''.')
2340                 catch /.*/
2341                         call s:svnError('Unable to retrieve conflict files in ''' . a:path . ''':', v:exception)
2342                 endtry
2343         endfunction
2345         " Function s:svnResolve() {{{2
2346         function s:svnResolve(line)
2347                 let path = s:getPath(a:line)
2349                 if path != ''
2350                         call s:refreshSvnConflictWindow(path)
2351                 endif
2352         endfunction
2354         " Function s:svnMarkAsResolved() {{{2
2355         function s:svnMarkAsResolved(path)
2356                 let path = fnamemodify(bufname('%'), ':p')
2358                 if s:input('All conflicts are resolved [yN] ? [y/N] : ', 'N') != 'y'
2359                         call s:echo('Conflicts not resolved on ''' . path . '''.')
2360                 else
2361                         try
2362                                 call s:echo('Resolve conflicts on ''' . path . '''...')
2363                                 call s:svn('resolved --non-interactive ' . shellescape(path))
2364                                 call s:message('Conflicts resolved on ''' . path . '''.')
2365                                 call s:refreshSvnConflictWindow(a:path)
2366                                 execute 'au! ' . s:plugin . ' BufWritePost <buffer>'
2367                         catch /.*/
2368                                 call s:svnError('Unable to resolve conflict for file ''' . path . ''':', v:exception)
2369                         endtry
2370                 endif
2371         endfunction
2373         " Function s:svnInfo() {{{2
2374         function s:svnInfo(line)
2375                 let path = s:getPath(a:line)
2377                 if path != ''
2378                         try
2379                                 call s:createSvnWindow('Svn info of ''' . path . '''')
2380                                 call s:echo('Do svn info on ''' . path . '''...')
2382                                 let lines = split(s:svn('info --non-interactive ' . shellescape(path)), "\n")
2384                                 let maxLength = 0
2386                                 for line in lines
2387                                         let lineLength = strlen(substitute(line, '^\([^:]\+:\).*$', '\1', ''))
2389                                         if lineLength > maxLength
2390                                                 let maxLength = lineLength
2391                                         endif
2392                                 endfor
2394                                 call map(lines, 'repeat('' '', ' . maxLength . ' - strlen(substitute(v:val, ''^\([^:]\+:\).*$'', ''\1'', ''''))) . v:val')
2395                                 call s:putInMyProjectsWindow(lines)
2396                                 call s:message('Svn info done on path ''' . path . '''.')
2397                         catch /.*/
2398                                 call s:svnError('Svn info failed on ''' . path . ''':', v:exception)
2399                         endtry
2400                 endif
2401         endfunction
2403         " Function s:getRawBuffers() {{{2
2404         function s:getRawBuffers(hidden)
2405                 redir => rawBuffers
2407                 if a:hidden
2408                         buffers!
2409                 else
2410                         buffers
2411                 endif
2413                 redir END
2415                 return split(rawBuffers, "\n")
2416         endfunction
2418         " Function s:getBuffers() {{{2
2419         function s:getBuffers(hidden)
2420                 let buffers = {}
2422                 silent let rawBuffers = s:getRawBuffers(a:hidden)
2424                 for buffer in rawBuffers
2425                         let path = resolve(fnamemodify(expand(substitute(buffer, '^[^"]\+"\([^"]\+\)".*$', '\1', ''), ':p'), ':p'))
2427                         if getftype(path) == 'file'
2428                                 let buffers[substitute(buffer, '^\s*\([^ ]\+\).*$', '\1', '')] = path
2429                         endif
2430                 endfor
2432                 return buffers
2433         endfunction
2435         " Function s:getProjectBuffers() {{{2
2436         function s:getProjectBuffers(project, path, delete)
2437                 let projectBuffers = []
2439                 if a:path != ''
2440                         silent let buffers = filter(s:getBuffers(0), 'v:val =~ ''^' . a:path . s:osSlash . '.*$''')
2442                         if a:delete != '' && has_key(buffers, a:delete)
2443                                 call remove(buffers, a:delete)
2444                         endif
2446                         let projectBuffers = values(buffers)
2448                         if g:myprojects_sort_buffers
2449                                 let projectBuffers = sort(projectBuffers)
2450                         endif
2452                         call map(projectBuffers, 'substitute(v:val, ''^' . a:path . ''', '''', '''')')
2453                 endif
2455                 return projectBuffers
2456         endfunction
2458         " Function s:toggleProjectBuffers() {{{2
2459         function s:toggleProjectBuffers(project, path, delete)
2460                 if a:path != ''
2461                         if !s:createBufferWindow('Buffers of project ''' . a:project . ''' in ''' . a:path . '''', a:project, a:path)
2462                                 bwipeout
2463                         else
2464                                 silent execute 'nnoremap <buffer> <silent> d :call <SID>deleteProjectBuffers(line(''.''), ''' . a:path .''')<CR>'
2466                                 silent execute 'augroup ' . s:plugin
2467                                 silent execute 'au! BufWinLeave <buffer> au! ' . s:plugin . ' BufNew,BufDelete ' . a:path . '/*'
2468                                 silent execute 'au! BufNew ' . a:path . '/* call' . s:sid . 'refreshProjectBuffers(''' . a:project . ''', ''' . a:path . ''', '''')'
2469                                 silent execute 'au! BufDelete ' . a:path . '/* execute "call ' . s:sid . 'refreshProjectBuffers(''' . a:project . ''', ''' . a:path . ''', " . expand(''<abuf>'') . ")"'
2470                                 silent augroup END
2472                                 call s:putInMyProjectsWindow(s:getProjectBuffers(a:project, a:path, a:delete))
2473                         endif
2474                 endif
2475         endfunction
2477         " Function s:refreshProjectBuffers() {{{2
2478         function s:refreshProjectBuffers(project, path, delete)
2479                 if s:refreshProjectBuffers
2480                         let window = bufwinnr(s:sid . a:project)
2482                         if window != -1
2483                                 silent execute window . 'wincmd w'
2484                                 call s:putInMyProjectsWindow(s:getProjectBuffers(a:project, a:path, a:delete))
2485                                 wincmd p
2486                         endif
2487                 endif
2488         endfunction
2490         " Function s:deleteProjectBuffers() {{{2
2491         function s:deleteProjectBuffers(line, path)
2492                 let line = a:path . getline(a:line)
2494                 if line != ''
2495                         let buffer = bufnr(line)
2497                         if buffer != -1
2498                                 if getbufvar(buffer, '&modified') == 1
2499                                         call s:error('Sorry, no write since last change for buffer ' . line . ', unable to delete')
2500                                 else
2501                                         let position = getpos('.')
2502                                         let currentBuffer = bufnr('%')
2504                                         silent! execute 'bdelete ' . buffer
2506                                         if !s:quitVim()
2507                                                 silent! execute bufwinnr(currentBuffer) . ' wincmd w'
2508                                                 call setpos('.', position)
2509                                         endif
2510                                 endif
2511                         endif
2512                 endif
2513         endfunction
2515         " Function s:echoVersion() {{{2
2516         function s:echoVersion()
2517                 call s:echo('Version ' . s:version . ' - ' . s:email . ' - (c) ' . s:author . ' ' . s:copyright . ' - ' . s:webSite)
2518         endfunction
2520         " Function s:echoMyprojectsFile() {{{2
2521         function s:echoMyprojectsFile()
2522                 call s:echo('Currently used file ' . g:myprojects_file)
2523         endfunction
2525         " Function s:getSessionFile() {{{2
2526         function s:getSessionFile(line)
2527                 let path = ''
2529                 let projectPath = s:getProjectPath(a:line)
2531                 if s:windowsOs
2532                         let projectPath = substitute(projectPath, '^[a-zA-Z]:\(.*\)', '', '')
2533                 endif
2535                 if projectPath != ''
2536                         let path = g:myprojects_sessions_directory . projectPath
2537                 endif
2539                 return path
2540         endfunction
2542         " Function s:saveSession() {{{2
2543         function s:saveSession(line)
2544                 call s:goToMyProjectsWindow()
2546                 try
2547                         if !isdirectory(g:myprojects_sessions_directory)
2548                                 call s:mkdir(g:myprojects_sessions_directory)
2549                         endif
2551                         if !isdirectory(g:myprojects_sessions_directory)
2552                                 throw 'Unable to create session, directory ' . g:myprojects_sessions_directory . ' does not exist.'
2553                         else
2554                                 let session = s:getSessionFile(a:line)
2556                                 if session == ''
2557                                         throw 'Unable to create session.'
2558                                 else
2559                                         let head = fnamemodify(session, ':h')
2561                                         let headType = getftype(head)
2563                                         if headType == ''
2564                                                 call s:mkdir(head)
2565                                         elseif headType != 'dir'
2566                                                 throw 'Path ' . head . ' exists but it is not a directory.'
2567                                         elseif !filewritable(head)
2568                                                 throw 'Unable to write in directory ' . head . ' to save session.'
2569                                         endif
2571                                         silent let buffers = s:getRawBuffers(1)
2573                                         for buffer in buffers
2574                                                 if buffer =~# '\s"' . s:sid
2575                                                         silent execute 'bwipeout ' . substitute(buffer, '^\s*\([0-9]\+\).\+$', '\1', '')
2576                                                 endif
2577                                         endfor
2579                                         execute 'mksession! ' . session
2581                                         call s:echo('Session saved in ''' . session . '''.')
2582                                 endif
2583                         endif
2584                 catch /.*/
2585                         call s:error(v:exception)
2586                 endtry
2587         endfunction
2589         " Function s:loadSession() {{{2
2590         function s:loadSession(line)
2591                 call s:goToMyProjectsWindow()
2593                 let session = s:getSessionFile(a:line)
2595                 if !filereadable(session)
2596                         call s:error('Unable to read session file ''' . session . '''.')
2597                 else
2598                         let s:quitVimIfMyProjectsIsAlone = 0
2599                         execute 'source ' . session
2600                         let s:quitVimIfMyProjectsIsAlone = 1
2602                         if has('syntax') && g:myprojects_syntax
2603                                 syntax on
2604                         endif
2606                         call s:echo('Session loaded from ''' . session . '''.')
2607                 endif
2608         endfunction
2610         " Function s:deleteSession() {{{2
2611         function s:deleteSession(line)
2612                 call s:goToMyProjectsWindow()
2614                 let session = s:getSessionFile(a:line)
2616                 if !filereadable(session) || delete(session) != 0
2617                         call s:error('Unable to delete session file ' . session . '.')
2618                 endif
2619         endfunction
2620         
2621         " Function s:getMyProjects() {{{2
2622         function s:getMyProjects(line)
2623                 let myprojects = {}
2625                 let name = s:unescape(s:getName(a:line))
2627                 if name != ''
2628                         let myprojects[name] = {}
2630                         let attributes = {}
2632                         let pathAttribute = s:extractPathFromLine(a:line)
2634                         if pathAttribute != ''
2635                                 let attributes['path'] = pathAttribute
2636                         endif
2638                         let cdAttribute = s:extractCdFromLine(a:line, 0)
2640                         if cdAttribute != ''
2641                                 let attributes['cd'] = cdAttribute
2642                         endif
2644                         if s:hasFilter(a:line)
2645                                 let attributes['filter'] = s:extractFilterFromLine(a:line)
2646                         endif
2648                         let mappings = s:extractMappingsFromLine(a:line)
2650                         if !empty(mappings)
2651                                 let attributes['mappings'] = mappings
2652                         endif
2654                         let make = s:extractMakeFromLine(a:line)
2656                         if !empty(make)
2657                                 let attributes['make'] = make
2658                         endif
2660                         let errorFormat = s:extractErrorFormatFromLine(a:line)
2662                         if !empty(errorFormat)
2663                                 let attributes['errorformat'] = errorFormat
2664                         endif
2666                         let test = s:extractTestFromLine(a:line)
2668                         if !empty(test)
2669                                 let attributes['test'] = test
2670                         endif
2672                         let refresh = s:extractRefreshFromLine(a:line)
2674                         if !empty(refresh)
2675                                 let attributes['refresh'] = refresh
2676                         endif
2678                         if !empty(attributes)
2679                                 let myprojects[name]['attributes'] = attributes
2680                         endif
2682                         if s:isFolder(a:line)
2683                                 let oldPosition = s:setCursorPosition([0, a:line, 1])
2684                                 let files = []
2685                                 let endLine = s:getLastFolderLine(a:line)
2686                                 let regex = '^' . repeat('\t', (s:indent(a:line) + 1)) . '[^\t]\+$'
2687                                 let file = search(regex, '', endLine)
2689                                 while file
2690                                         call add(files, s:getMyProjects(file))
2691                                         let file = search(regex, '', endLine)
2692                                 endwhile
2694                                 if !empty(files)
2695                                         let myprojects[name]['files'] = files
2696                                 endif
2698                                 call s:setCursorPosition(oldPosition)
2699                         endif
2700                 endif
2702                 return myprojects
2703         endfunction
2705         " Function s:buildMyProjects() {{{2
2706         function s:buildMyProjects(path, filter, myprojects, refresh, indent)
2707                 let myprojects = ''
2709                 let filter = a:filter
2711                 for [name, meta] in items(a:myprojects)
2712                         let path = resolve(s:unescape(!has_key(meta, 'attributes') || !has_key(meta['attributes'], 'path') ? a:path . s:osSlash . name : meta['attributes']['path']))
2713                         let refresh = a:refresh
2715                         if s:pathExists(path) && (getftype(path) == 'dir' || filter == '' || match(name, filter) != -1)
2716                                 let myprojects .= repeat("\t", a:indent) . s:escape(name)
2718                                 if has_key(meta, 'attributes')
2719                                         if has_key(meta['attributes'], 'path')
2720                                                 let myprojects .= '=' . s:escape(s:cleanPath(meta['attributes']['path']))
2721                                         endif
2723                                         if has_key(meta['attributes'], 'cd') && meta['attributes']['cd'] != ''
2724                                                 let myprojects .= ' cd="' . s:escape(s:cleanPath(meta['attributes']['cd'])) . '"'
2725                                         endif
2727                                         if has_key(meta['attributes'], 'filter')
2728                                                 let myprojects .= ' filter="' . meta['attributes']['filter'] . '"'
2729                                                 let filter = meta['attributes']['filter']
2730                                         endif
2732                                         if has_key(meta['attributes'], 'make') && meta['attributes']['make'] != ''
2733                                                 let myprojects .= ' make="' . meta['attributes']['make'] . '"'
2734                                         endif
2736                                         if has_key(meta['attributes'], 'errorformat') && meta['attributes']['errorformat'] != ''
2737                                                 let myprojects .= ' errorformat="' . meta['attributes']['errorformat'] . '"'
2738                                         endif
2740                                         if has_key(meta['attributes'], 'refresh') && meta['attributes']['refresh'] != ''
2741                                                 let refresh = meta['attributes']['refresh']
2742                                         endif
2744                                         if has_key(meta['attributes'], 'test') && meta['attributes']['test'] != ''
2745                                                 let myprojects .= ' test="' . meta['attributes']['test'] . '"'
2746                                         endif
2748                                         if has_key(meta['attributes'], 'mappings')
2749                                                 for [index, mapping] in items(meta['attributes']['mappings'])
2750                                                         let myprojects .= ' F' . index . '="' . mapping . '"'
2751                                                 endfor
2752                                         endif
2753                                 endif
2755                                 if getftype(path) != 'dir'
2756                                         let myprojects .= "\n"
2757                                 else
2758                                         let myprojects .= ' refresh="' . localtime() . '"' . "\n"
2760                                         let subFiles = !has_key(meta, 'files') ? [] : meta['files']
2762                                         let files = ''
2764                                         for subName in subFiles
2765                                                 let files .= s:buildMyProjects(path, filter, subName, refresh, a:indent + 1)
2766                                         endfor
2768                                         let notInMyProjectsFiles = s:getFilesNotInMyprojects(path, filter, a:indent, refresh, subFiles)
2770                                         if g:myprojects_new_file_on_bottom
2771                                                 let files .= notInMyProjectsFiles
2772                                         else
2773                                                 let files = notInMyProjectsFiles . files
2774                                         endif
2776                                         if files != '' || g:myprojects_display_empty_folder
2777                                                 let myprojects .= files
2778                                         else
2779                                                 let myprojects = ''
2780                                         endif
2781                                 endif
2782                         endif
2783                 endfor
2785                 return myprojects
2786         endfunction
2788         " Function s:isInMyprojects() {{{2
2789         function s:isInMyprojects(name, files)
2790                 for file in a:files
2791                         if has_key(file, a:name)
2792                                 return 1
2793                         endif
2794                 endfor
2796                 return 0
2797         endfunction
2799         " Function s:getFilesNotInMyprojects() {{{2
2800         function s:getFilesNotInMyprojects(path, filter, indent, refresh, myprojects)
2801                 let myprojects = ''
2803                 let path = resolve(a:path)
2805                 if getftype(path) != 'dir'
2806                         call s:warningMessage('Path ''' . path . ''' is not a directory.')
2807                 else
2808                         let cwd = getcwd()
2810                         try
2811                                 silent execute 'lcd ' . fnameescape(path)
2813                                 for globName in sort(filter(split(glob('*') . "\n" . glob('.*'), "\n"), 'v:val != "." && v:val != ".."'))
2814                                         if !s:isInMyprojects(globName, a:myprojects) && getftime(fnamemodify(globName, ':p')) > a:refresh
2815                                                 let myprojects .= s:buildMyProjects(path, a:filter, {globName : {}}, a:refresh, a:indent + 1)
2816                                         endif
2817                                 endfor
2819                                 silent execute 'lcd ' . fnameescape(cwd)
2820                         catch /E472/
2821                                 call s:warningMessage('Unable to go to working directory ''' . path . '''.')
2822                         endtry
2823                 endif
2825                 return myprojects
2826         endfunction
2828         " Function s:getLineOfPath() {{{2
2829         function s:getLineOfPath(path)
2830                 let line = 0
2832                 if getftype(a:path) == 'file'
2833                         call s:openMyProjectsWindow()
2834                         let line = s:searchPath(a:path, 0)
2835                 endif
2837                 return line
2838         endfunction
2840         " Function s:openFromMyProjectsWindow() {{{2
2841         function s:openFromMyProjectsWindow(command, path)
2842                 let line = s:getLineOfPath(resolve(a:path))
2844                 if line <= 0
2845                         wincmd p
2846                 else
2847                         call s:edit(a:command, line)
2848                 endif
2849         endfunction
2851         " Function s:openTest() {{{2
2852         function s:openTest(command, path, test)
2853                 let line = s:getLineOfPath(a:path)
2855                 if line <= 0
2856                         wincmd p
2857                 else
2858                         let firstProjectLine = s:getProjectLine(line)
2859                         let lastProjectLine = s:getLastFolderLine(firstProjectLine)
2860                         let oldPosition = s:setCursorPosition([0, firstProjectLine, 1])
2861                         let line = search('\%(^\t*\|\/\)' . a:test . '\%(\s\|=\|$\)', 'W', lastProjectLine)
2862                         let lines = {}
2864                         while line > 0
2865                                 let lines[line] = s:getPath(line)
2866                                 let line = search('\%(^\t*\|\/\)' . a:test . '\%(\s\|=\|$\)', 'W', lastProjectLine)
2867                         endwhile
2869                         call s:setCursorPosition(oldPosition)
2871                         let linesLength = len(lines)
2873                         if linesLength <= 0
2874                                 call s:error('No test file ''' . a:test . ''' found for ''' . a:path . '''')
2875                         else
2876                                 let line = 0
2878                                 if linesLength == 1
2879                                         let line = get(keys(lines), 0)
2880                                 else
2881                                         let list = ['There is several test file ''' . a:test . ''' found for ''' . a:path . ''':']
2882                                         let keys = {}
2884                                         let index = 1
2886                                         for [line, path] in items(lines)
2887                                                 let list = add(list, index . '. ' . path)
2888                                                 let keys[index] = line
2889                                                 let index += 1
2890                                         endfor
2892                                         let index = inputlist(list)
2894                                         if has_key(keys, index)
2895                                                 let line = keys[index]
2896                                         endif
2897                                 endif
2899                                 if line > 0
2900                                         try
2901                                                 call s:edit(a:command, line)
2902                                         catch /.*/
2903                                                 call s:error(v:exception)
2904                                         endtry
2905                                 endif
2906                         endif
2908                 endif
2909         endfunction
2911         " Function s:loadMyProjectsAttributes() {{{2
2912         function s:loadMyProjectsAttributes()
2913                 let bufferName = fnamemodify(bufname('%'), ':p')
2915                 if bufferName !~ g:myprojects_file && bufferName !~ '^' . s:sid && s:loadAttributes == 1 && !exists('b:myprojectsAttributesLoaded')
2916                         call s:openFromMyProjectsWindow('edit', bufferName)
2917                         let b:myprojectsAttributesLoaded = 1
2918                 endif
2919         endfunction
2921         " Function s:resolveSvnConflict() {{{2
2922         function s:resolveSvnConflict(command, path)
2923                 try
2924                         call s:openFromSvnWindow(a:command)
2925                         execute 'au! ' . s:plugin . ' BufWritePost <buffer> call ' . s:sid . 'svnMarkAsResolved(''' . a:path . ''')'
2926                 catch /.*/
2927                         call s:error(v:exception)
2928                 endtry
2929         endfunction
2931         " Function s:openFromSvnWindow() {{{2
2932         function s:openFromSvnWindow(command)
2933                 try
2934                         call s:openFromMyProjectsWindow(a:command, substitute(getline('.'), '^[[:space:]ACDIMRX?!~]\?[[:space:]CM]\?[[:space:]L]\?[[:space:]+]\?[[:space:]SX]\?[[:space:]K]\?[[:space:]C]\?\s*', '', ''))
2935                 catch /.*/
2936                         call s:error(v:exception)
2937                 endtry
2938         endfunction
2940         " Function s:openFromBuffersWindow() {{{2
2941         function s:openFromBuffersWindow(command, path)
2942                 try
2943                         call s:openFromMyProjectsWindow(a:command, a:path . getline('.'))
2944                 catch /.*/
2945                         call s:error(v:exception)
2946                 endtry
2947         endfunction
2949         " Function s:svnDiffFromMyProjectWindow() {{{2
2950         function s:svnDiffFromMyProjectWindow(path)
2951                 let path = resolve(substitute(a:path, '^[[:space:]A-Z]\+\s', '', ''))
2953                 let line = s:getLineOfPath(path)
2955                 if line <= 0
2956                         wincmd p
2957                 else
2958                         call s:svnDiff(line)
2959                 endif
2960         endfunction
2962         " Function s:svnDiffFromSvnWindow() {{{2
2963         function s:svnDiffFromSvnWindow()
2964                 call s:svnDiffFromMyProjectWindow(getline('.'))
2965         endfunction
2968         " Function s:setCursorPosition() {{{2
2969         function s:setCursorPosition(position)
2970                 let oldPosition = getpos('.')
2971                 call setpos('.', a:position)
2973                 return oldPosition
2974         endfunction
2975         " Function s:svnDiffFromBuffersWindow() {{{2
2976         function s:svnDiffFromBuffersWindow(path)
2977                 let s:refreshProjectBuffers = 0
2979                 call s:svnDiffFromMyProjectWindow(a:path . getline('.'))
2981                 let s:refreshProjectBuffers = 1
2982         endfunction
2984         " Function s:autowrite() {{{2
2985         function s:autowrite()
2986                 if g:myprojects_autowrite
2987                         write
2988                 endif
2989         endfunction
2991         " Function s:sid() {{{2
2992         function s:sid()
2993                 return matchstr(expand('<sfile>'), '<SNR>\d\+_\zesid$')
2994         endfunction
2996         " Function s:setLocal() {{{2
2997         function s:setLocal(name, bool)
2998                 silent execute 'setlocal ' . (a:bool ? a:name : 'no' . a:name)
2999         endfunction
3001         " Function s:substitute() {{{2
3002         function s:substitute(line, search, replace, flags)
3003                 silent execute ':' . a:line . 's/' . a:search . '/' . escape(a:replace, '/') . '/' . a:flags
3005                 if &hlsearch
3006                         set nohlsearch
3007                 endif
3008         endfunction
3010         " Function s:input() {{{2
3011         function s:input(prompt, ...)
3012                 redraw
3014                 let prompt = s:getPromptedString(a:prompt)
3016                 if a:0 == 0
3017                         return input(prompt)
3018                 elseif a:0 == 1
3019                         return input(prompt, a:1)
3020                 elseif a:0 == 2
3021                         return input(prompt, a:1, a:2)
3022                 endif
3023         endfunction
3025         " Function s:inputSecret() {{{2
3026         function s:inputSecret(prompt, ...)
3027                 redraw
3029                 let prompt = s:getPromptedString(a:prompt)
3031                 if a:0 == 0
3032                         return inputsecret(prompt)
3033                 elseif a:0 == 1
3034                         return inputsecret(prompt, a:1)
3035                 endif
3036         endfunction
3037         " Function s:indent() {{{2
3038         function s:indent(line)
3039                 return indent(a:line) / &tabstop
3040         endfunction
3042         " Function s:put() {{{2
3043         function s:put(data, line)
3044                 if a:data != ''
3045                         silent execute a:line - 1 . 'put =a:data'
3047                         let nextLine = line('.') + 1
3049                         if nextLine <= line('$') && getline(nextLine) =~ '^$'
3050                                 silent! execute ':' . nextLine . 'd'
3051                         endif
3053                         call s:goToLine(a:line)
3054                 endif
3055         endfunction
3057         " Function s:putInMyProjectsWindow() {{{2
3058         function s:putInMyProjectsWindow(lines)
3059                 setlocal modifiable
3060                 silent! %d
3061                 silent! 0put =substitute(join(a:lines, \"\n\"), '\n\s*$', '', '')
3062                 silent! $d
3063                 setlocal nomodifiable
3064                 setlocal nomodified
3065                 setlocal buftype=nofile
3067                 call s:goToLine(1)
3068                 call s:setWindowHeight(line('$'))
3069         endfunction
3071         " Function s:getPromptedString() {{{2
3072         function s:getPromptedString(message)
3073                 return s:prompt .  substitute(a:message, '^@', '', 'g')
3074         endfunction
3076         " Function s:getPromptedStringLength() {{{2
3077         function s:getPromptedStringLength(message)
3078                 return strlen(s:getPromptedString(a:message)) + 20
3079         endfunction
3081         " Function s:echo() {{{2
3082         function s:echo(message)
3083                 redraw
3084                 echo s:getPromptedString(a:message)
3085         endfunction
3087         " Function s:echoPath() {{{2
3088         function s:echoPath()
3089                 if winbufnr(0) == bufnr(g:myprojects_file)
3090                         let path = s:getPath(line('.'))
3092                         if s:getPromptedStringLength(path) > &columns
3093                                 let path = pathshorten(path)
3095                                 if s:getPromptedStringLength(path) > &columns
3096                                         let path = s:getName(line('.'))
3098                                         if s:getPromptedStringLength(path) > &columns
3099                                                 let path = ''
3100                                         endif
3101                                 endif
3102                         endif
3104                         if path != ''
3105                                 call s:echo(path)
3106                         endif
3107                 endif
3108         endfunction
3110         " Function s:error() {{{2
3111         function s:error(message)
3112                 echohl ErrorMsg
3113                 call s:echo(a:message)
3114                 echohl Normal
3115         endfunction
3117         " Function s:message() {{{2
3118         function s:message(message)
3119                 redraw
3120                 echomsg s:getPromptedString(a:message)
3121         endfunction
3123         " Function s:errorMessage() {{{2
3124         function s:errorMessage(message)
3125                 echohl ErrorMsg
3126                 call s:message(a:message)
3127                 echohl Normal
3128         endfunction
3130         " Function s:warningMessage() {{{2
3131         function s:warningMessage(message)
3132                 echohl WarningMsg
3133                 call s:message(a:message)
3134                 echohl Normal
3135         endfunction
3137         " Function s:escape() {{{2
3138         function s:escape(path)
3139                 return substitute(a:path, '\%(\\\)\@<!\([ "=]\)', '\\\1', 'g')
3140         endfunction
3142         " Function s:unescape() {{{2
3143         function s:unescape(path)
3144                 return substitute(a:path, '\\\([ ="]\)', '\1', 'g')
3145         endfunction
3147         " Function s:goToLine() {{{2
3148         function s:goToLine(line)
3149                 silent execute 'normal! ' . a:line . 'G'
3150                 silent normal |
3151         endfunction
3153         " Function s:getFiles() {{{2
3154         function s:getFiles(path, filter)
3155                 let files = ''
3157                 let path = resolve(a:path)
3159                 if !isdirectory(path)
3160                         call s:warningMessage('Path ''' . path . ''' is not a directory.')
3161                 else
3162                         let cwd = getcwd()
3164                         try
3165                                 silent execute 'lcd ' . path
3167                                 for inode in sort(split(glob('*'), "\n"))
3168                                         let inode = resolve(inode)
3170                                         if isdirectory(inode)
3171                                                 let files .= ' ' . s:getFiles(path . s:osSlash . inode, a:filter)
3172                                         elseif a:filter == '' || match(inode, a:filter) != -1
3173                                                 let files .= ' ' . path . s:osSlash . inode
3174                                         endif
3175                                 endfor
3177                                 silent execute 'lcd ' . cwd
3178                         catch /E472/
3179                                 call s:warningMessage('Unable to go to directory ''' . path . '''.')
3180                         endtry
3181                 endif
3183                 return files
3184         endfunction
3186         " Function s:pathExists() {{{2
3187         function s:pathExists(path)
3188                 let type = getftype(a:path)
3190                 return type == 'dir' || type == 'file'
3191         endfunction
3193         " Function s:searchPath() {{{2
3194         function s:searchPath(path, line)
3195                 let line = 0
3197                 let file = fnamemodify(a:path, ':t')
3199                 if file != ''
3200                         let oldPosition = s:setCursorPosition([0, a:line, 1])
3202                         let line = search('\%(^\t*\|\/\)' . file . '\%(\s\|=\|$\)', 'W')
3204                         while line > 0
3205                                 let path = s:getPath(line)
3207                                 if a:path == path
3208                                         call s:setCursorPosition(oldPosition)
3209                                         return line
3210                                 else
3211                                         let line = search('\%(^\t*\|\/\)' . file . '\%(\s\|=\|$\)', 'W')
3212                                 endif
3213                         endwhile
3214                 endif
3216                 call s:setCursorPosition(oldPosition)
3217                 return line
3218         endfunction
3220         " Function s:cleanPath() {{{2
3221         function s:cleanPath(path)
3222                 return substitute(a:path, escape(s:osSlash, '\') . '\+$', '', '')
3223         endfunction
3225         " Function s:mkdir() {{{2
3226         function s:mkdir(path)
3227                 if !exists("*mkdir")
3228                         throw 'Unable to create directory ' . a:path . ', mkdir() function does not exist.')
3229                 else
3230                          call mkdir(a:path, 'p')
3232                         if getftype(a:path) != 'dir'
3233                                 throw 'Unable to create directory ' . a:path . '.')
3234                         endif
3235                 endif
3236         endfunction
3238         " Function s:moveWindowToTopLeftCorner() {{{2
3239         function s:moveWindowToTopLeftCorner()
3240                 silent wincmd H
3241         endfunction
3243         " Function s:setWindowWidth() {{{2
3244         function s:setWindowWidth(width)
3245                 silent execute 'vertical resize ' . a:width
3246         endfunction
3248         " Function s:setWindowHeight() {{{2
3249         function s:setWindowHeight(height)
3250                 silent execute 'resize ' . a:height
3251         endfunction
3253         " Restore cpo {{{2
3254         let &cpo= s:keepCpo
3255         unlet s:keepCpo
3257         " Enable myprojects {{{2
3258         let g:myprojects_enable = 1
3259 endif
3261 " finish {{{1
3262 finish
3263 " vim:filetype=vim foldmethod=marker shiftwidth=3 tabstop=3
3264 syntax/myprojects.vim   [[[1
3266 "=============================================================================
3267 " File:                                         myprojects.vim
3268 " Author:                                       Frédéric Hardy - http://blog.mageekbox.net
3269 " Date:                                         Fri Mar 20 16:35:28 CET 2009
3270 " Licence:                                      GPL version 2.0 license
3271 "=============================================================================
3272 if !exists('b:current_syntax')
3273         syn case match
3275         syntax match MyProjectsFile '^\(\t*\)\zs[^\t\n][^\t]*\n\ze'
3276         highlight default MyProjectsFile guifg=lightgreen
3278         syntax match MyProjectsFolder '^\(\t*\)\zs[^\t\n][^\t]*\n\ze\t\1'
3279         highlight default MyProjectsFolder guifg=lightblue
3281         let b:current_syntax = "myprojects"
3282 endif
3283 " vim:filetype=vim foldmethod=marker shiftwidth=3 tabstop=3
3284 syntax/myprojectsSvn.vim        [[[1
3286 "=============================================================================
3287 " File:                                         myprojectsSvn.vim
3288 " Author:                                       Frédéric Hardy - http://blog.mageekbox.net
3289 " Date:                                         Fri Apr 17 09:58:00 CEST 2009
3290 " Licence:                                      GPL version 2.0 license
3291 "=============================================================================
3292 if !exists('b:current_syntax')
3293         syn case match
3295         syntax match MyProjectsSvnA '^A[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3296         highlight default MyProjectsSvnA guifg=blue
3298         syntax match MyProjectsSvnU '^U[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3299         highlight default MyProjectsSvnU guifg=yellow
3301         syntax match MyProjectsSvnC '^\%(C[ CM][ L][ +][ S]\?[ KOTB]\?\|[ AKDIMRX?!~]C[ L][ +][ S]\?[ KOTB]\?\)\s[^\s].\+$'
3302         highlight default MyProjectsSvnC guifg=red
3304         syntax match MyProjectsSvnD '^D[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3305         highlight default MyProjectsSvnD guifg=magenta
3307         syntax match MyProjectsSvnI '^I[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3308         highlight default MyProjectsSvnI guifg=gray
3310         syntax match MyProjectsSvnM '^\%(M[ CM][ L][ +][ S]\?[ KOTB]\?\|[ AKDIMRX?!~]M[ L][ +][ S]\?[ KOTB]\?\)\s[^\s].\+$'
3311         highlight default MyProjectsSvnM guifg=lightgreen
3313         syntax match MyProjectsSvnR '^R[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3314         highlight default MyProjectsSvnR guifg=violet
3316         syntax match MyProjectsSvnX '^X[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3317         highlight default MyProjectsSvnX guifg=gray
3319         syntax match MyProjectsSvnQuestion '^?[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3320         highlight default MyProjectsSvnQuestion guifg=brown
3322         syntax match MyProjectsSvnExclamation '^![ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3323         highlight default MyProjectsSvnExclamation guifg=purple
3325         syntax match MyProjectsSvnTilde '^\~[ CM][ L][ +][ S]\?[ KOTB]\?\s[^\s].\+$'
3326         highlight default MyProjectsSvnTilde guifg=orange
3328         let b:current_syntax = "myprojectsSvn"
3329 endif
3330 " vim:filetype=vim foldmethod=marker shiftwidth=3 tabstop=3