1 " Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
4 plugin/myprojects.vim [[[1
6 "=============================================================================
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 "=============================================================================
15 echoerr "myprojects.vim requires vim >= 7. DOWNLOAD IT! You'll thank me later."
17 elseif !has('folding')
18 echoerr "myprojects.vim requires folding."
19 " Check compatible mode {{{1
21 echoerr "myprojects.vim requires no compatible mode."
23 elseif !exists('myprojects_enable')
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 . '] '
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)
50 let {a:name} = a:value
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
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
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()
103 " Function s:goToMyProjectsWindow() {{{2
104 function s:goToMyProjectsWindow()
105 let window = bufwinnr(g:myprojects_file)
110 silent execute window . 'wincmd w'
115 " Function s:writeMyProjectsPreferences() {{{2
116 function s:writeMyProjectsPreferences()
117 let preferencesDirectory = fnamemodify(g:myprojects_preferences_file, ':h')
118 let type = getftype(preferencesDirectory)
121 call s:mkdir(preferencesDirectory)
123 throw 'Path ''' . preferencesDirectory . ''' exists but it is not a directory.'
126 if !filewritable(preferencesDirectory)
127 throw 'Unable to write in ''' . preferencesDirectory . '''.'
129 call writefile([string(s:preferences)], g:myprojects_preferences_file)
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
148 " Function s:definePreferences()
149 function s:definePreferences()
150 let type = s:input('Preferences for type: ', '')
153 call s:error('Preferences type must not be empty.')
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}
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
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
190 call s:message('Save preferences for type ''' . type . '''...')
191 call s:writeMyProjectsPreferences()
192 call s:message('Preferences saved for type ''' . type . '''.')
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
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>
283 setlocal foldmethod=expr
285 setlocal noequalalways
293 setlocal shiftwidth=3
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)
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
315 if g:myprojects_cursorline
316 silent au WinEnter <buffer> set cursorline
318 silent au WinEnter <buffer> set nocursorline
321 if g:myprojects_cursorcolumn
322 silent au WinEnter <buffer> set cursorcolumn
324 silent au WinEnter <buffer> set nocursorcolumn
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()'
334 silent execute 'setlocal filetype=' . s:plugin
336 if has('syntax') && g:myprojects_syntax
340 if foldlevel(line('.'))
344 if g:myprojects_display_path_in_statusline
345 call <SID>echo(<SID>getPath(line('.')))
348 if g:myprojects_version_at_startup
352 let &titlestring = s:prompt
357 " Function s:closeMyProjectsWindow() {{{2
358 function s:closeMyProjectsWindow()
359 if s:goToMyProjectsWindow()
365 " Function s:toggleMyProjectsWindow() {{{2
366 function s:toggleMyProjectsWindow()
367 if s:goToMyProjectsWindow()
368 call s:closeMyProjectsWindow()
370 call s:openMyProjectsWindow()
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 .'.\+$'
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
386 " Function s:goToAnEditionWindow() {{{2
387 function s:goToAnEditionWindow()
392 if !s:isAnEditionWindow(window)
394 let maxWindow = winnr('$')
396 while window <= maxWindow
397 if !s:isAnEditionWindow(window)
400 silent execute window . 'wincmd w'
405 let width = &columns - g:myprojects_width
408 call s:setWindowWidth(width)
414 " Function s:createMyProjectsWindow() {{{2
415 function s:createMyProjectsWindow(title, buffer, filetype)
416 let buffer = bufnr(s:sid . a:buffer)
419 let window = bufwinnr(buffer)
422 silent execute window . 'wincmd w'
424 silent execute 'botright new ' . s:sid . a:buffer
426 let &titlestring = s:prompt . a:title
428 silent execute 'setlocal statusline=' . escape(&titlestring, ' ') . '%=[%3p%%]'
433 silent execute 'botright new ' . s:sid . a:buffer
435 setlocal buftype=nofile
437 setlocal nocursorcolumn
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
459 silent au! WinEnter <buffer> set nocursorline nocursorcolumn
462 silent execute 'au! BufEnter <buffer> let &titlestring = ''' . substitute(s:prompt . a:title, "'", "''", 'g') . ''''
465 if has('syntax') && g:myprojects_syntax
472 call s:setWindowHeight(0)
477 " Function s:createSvnWindow() {{{2
478 function s:createSvnWindow(title)
479 call s:createMyProjectsWindow(a:title, 'svn', s:plugin . 'Svn')
483 setlocal nomodifiable
485 call s:setWindowHeight(line('$'))
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>
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>'
512 " Function s:createBufferWindow() {{{2
513 function s:createBufferWindow(title, buffer, path)
514 let bufferCreated = s:createMyProjectsWindow(a:title, a:buffer, s:plugin)
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>'
531 " Function s:quitVim() {{{2
533 if !g:myprojects_quit_vim_if_alone
534 if s:myProjectsIsAlone()
535 call s:goToAnEditionWindow()
539 elseif !s:quitVimIfMyProjectsIsAlone || !s:myProjectsIsAlone()
547 " Function s:myProjectsIsAlone() {{{2
548 function s:myProjectsIsAlone()
549 let windows = winnr('$')
552 if s:isAnEditionWindow(windows)
562 " Function s:toggleFullscreen() {{{2
563 function s:toggleFullscreen()
565 let s:oldWidth = winwidth(0)
566 call s:setWindowWidth('')
568 call s:setWindowWidth(s:oldWidth)
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)
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
596 " Function s:isFolder() {{{2
597 function s:isFolder(line)
598 return indent(a:line) < indent(nextnonblank(a:line + 1))
601 " Function s:getFirstFolderLine() {{{2
602 function s:getFirstFolderLine(line)
605 let indent = s:indent(a:line)
608 let oldPosition = s:setCursorPosition([0, a:line, 1])
609 let line = search('^\t\{' . (indent - 1) . '}[^\t]\+$', 'bnW')
610 call s:setCursorPosition(oldPosition)
616 " Function s:getLastFolderLine() {{{2
617 function s:getLastFolderLine(line)
620 let firstFolderLine = a:line
622 if !s:isFolder(firstFolderLine)
623 let firstFolderLine = s:getFirstFolderLine(firstFolderLine)
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)
639 " Function s:getName() {{{2
640 function s:getName(line)
643 let line = getline(a:line)
646 let name = substitute(line, '^\t*\([^\t].\{-}\)\%(\%(\\\)\@<!\%(=\| \).*\|$\)', '\1', '')
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)
660 let path = s:extractPath(folderLine) . s:osSlash . path
661 let folderLine = s:getFirstFolderLine(folderLine)
665 return !s:isAbsolutePath(path) ? '' : resolve(s:unescape(path))
668 " Function s:getProjectLine() {{{2
669 function s:getProjectLine(line)
672 let indent = indent(a:line)
675 let line = indent == 0 ? a:line : search('^[^\t]\+$', 'bnW')
681 " Function s:getProjectName() {{{2
682 function s:getProjectName(line)
685 while indent(line) > 0
686 let line = s:getFirstFolderLine(line)
689 return s:getName(line)
692 " Function s:getProjectPath() {{{2
693 function s:getProjectPath(line)
696 let line = s:getProjectLine(a:line)
699 let path = s:getPath(line)
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', '')
710 " Function s:extractAttribute() {{{2
711 function s:extractAttribute(name, line)
716 while line > 0 && !s:hasAttribute(a:name, line)
717 let line = s:getFirstFolderLine(line)
720 if s:hasAttribute(a:name, line)
721 let attribute = s:extractAttributeFromLine(a:name, line)
727 " Function s:extractPathFromLine() {{{2
728 function s:extractPathFromLine(line)
732 let lineContent = substitute(getline(a:line), '^\t*[^\t].\{-}\%(\\\)\@<!\%( \|=\)', '', '')
734 let path = substitute(lineContent, '^\(.\{-}\)\%(\\\)\@<! .*$', '\1', '')
740 " Function s:extractPath() {{{2
741 function s:extractPath(line)
742 let path = s:extractPathFromLine(a:line)
745 let path = s:getName(a:line)
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)
758 " Function s:extractCd() {{{2
759 function s:extractCd(line)
764 let cd = s:extractCdFromLine(line, 1)
765 let line = cd != '' ? 0 : s:getFirstFolderLine(line)
771 " Function s:extractFilterFromLine() {{{2
772 function s:extractFilterFromLine(line)
773 return s:extractAttributeFromLine('filter', a:line)
776 " Function s:extractFilter() {{{2
777 function s:extractFilter(line)
778 return s:extractAttribute('filter', a:line)
781 " Function s:extractMappingsFromLine() {{{2
782 function s:extractMappingsFromLine(line)
785 let line = getline(a:line)
791 if s:hasMapping('F' . index, a:line)
792 let mapping = substitute(line, '.*\s\+F' . index . '="\([^"]\+\)".*', '\1', '')
795 let mappings[index] = mapping
806 " Function s:extractMappings() {{{2
807 function s:extractMappings(line)
817 while line > 0 && !s:hasMapping('F' . key, line)
818 let line = s:getFirstFolderLine(line)
822 let mapping = s:extractAttributeFromLine('F' . key, line)
824 if has_key(mappings, line)
825 let mappings[line][key] = mapping
827 let mappings[line] = { key : mapping }
837 " Function s:extractMakeFromLine() {{{2
838 function s:extractMakeFromLine(line)
839 return s:extractAttributeFromLine('make', a:line)
842 " Function s:extractMake() {{{2
843 function s:extractMake(line)
844 return s:extractAttribute('make', a:line)
847 " Function s:extractErrorFormatFromLine() {{{2
848 function s:extractErrorFormatFromLine(line)
849 return s:extractAttributeFromLine('errorformat', a:line)
852 " Function s:extractErrorFormat() {{{2
853 function s:extractErrorFormat(line)
854 return s:extractAttribute('errorformat', a:line)
857 " Function s:extractTestFromLine() {{{2
858 function s:extractTestFromLine(line)
859 return s:extractAttributeFromLine('test', a:line)
862 " Function s:extractTest() {{{2
863 function s:extractTest(line)
864 return s:extractAttribute('test', a:line)
867 " Function s:extractRefreshFromLine() {{{2
868 function s:extractRefreshFromLine(line)
869 return s:extractAttributeFromLine('refresh', a:line)
872 " Function s:extractRefresh() {{{2
873 function s:extractRefresh(line)
874 return s:extractAttribute('refresh', a:line)
877 " Function s:inputType() {{{2
878 function s:inputType(message)
884 " Function s:inputName() {{{2
885 function s:inputName(message)
886 let name = s:input(a:message, '')
889 throw 'Name must not be empty.'
895 " Function s:isAbsolutePath() {{{2
896 function s:isAbsolutePath(path)
897 return s:windowsOs ? a:path =~ '^.:\(\\\|\/\)' : a:path =~ '^/'
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.'
907 let path = expand(path, ':p')
909 if !s:isAbsolutePath(path)
910 throw 'Path must be absolute.'
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.'
928 " Function s:inputCd() {{{2
929 function s:inputCd(message, path, value)
930 let cd = s:input(a:message, a:value, 'file')
934 let cd = fnamemodify(s:cleanPath(cd), ':p')
941 if cd != '.' && getftype(cd) != 'dir'
942 throw 'Working directory ' . cd . ' of project ' . a:project['name'] . ' is invalid.'
951 " Function s:inputFilter() {{{2
952 function s:inputFilter(message, value)
953 return s:input(a:message, a:value)
956 " Function s:inputMappings() {{{2
957 function s:inputMappings(message, mappings)
960 let inputs = a:mappings
963 let inputs = {1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: ''}
968 while index >= 1 && index <= 13
969 let list = [a:message]
975 if has_key(inputs, index)
976 let list = add(list, index . '. F' . index . ': ' . inputs[index])
977 let keys[index] = index
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])
991 for [key, mapping] in items(inputs)
992 let mappings[key] = mapping
995 call filter(mappings, 'v:val != ''''')
1000 " Function s:inputMake() {{{2
1001 function s:inputMake(message, value)
1002 return s:input(a:message, a:value)
1005 " Function s:inputErrorFormat() {{{2
1006 function s:inputErrorFormat(message, value)
1007 return s:input(a:message, a:value)
1010 " Function s:inputTest() {{{2
1011 function s:inputTest(message, value)
1012 return s:input(a:message, a:value)
1015 "Function s:defineProject()
1016 function s:defineProject()
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)
1025 let types = ['Type of project: ']
1027 for type in availableTypes
1028 call add(types, index . '. ' . type)
1033 call extend(attributes, s:preferences[availableTypes[inputlist(types) - 1]], 'force')
1035 throw 'Project type is invalid.'
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]
1052 " Function s:create() {{{2
1053 function s:create(line)
1054 let indent = s:indent(a:line)
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))
1065 call s:error(v:exception)
1070 " Function s:refresh() {{{2
1071 function s:refresh(line, refreshFolder)
1075 let line = s:isFolder(a:line) ? a:line : s:getFirstFolderLine(a:line)
1078 let path = s:getPath(line)
1081 let indent = s:indent(line)
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)
1092 let range .= ',' . s:getLastFolderLine(line)
1093 let foldlevel = foldlevel(line)
1096 silent! execute ':' . range . 'd'
1099 call s:put(myprojects, line)
1101 silent! execute ':' . range . 'foldclose!'
1112 call s:echo('Refresh done for ''' . path . '''.')
1117 " Function s:open() {{{2
1118 function s:open(command)
1119 let line = line('.')
1125 call s:edit(a:command, line)
1127 call s:error(v:exception)
1132 " Function s:delete() {{{2
1133 function s:delete(line)
1134 let path = s:getPath(a:line)
1137 if getftype(path) == 'file' && delete(path) == 0
1138 call s:refresh(a:line, 1)
1140 call s:error('Unable to delete ' . path . '.')
1145 " Function s:grep() {{{2
1146 function s:grep(line)
1147 let path = s:getPath(a:line)
1150 let pattern = s:input('Grep in ''' . path . ''': ', '')
1153 if s:isFolder(a:line)
1154 let files = s:getFiles(path, s:extractFilter(a:line))
1160 let s:loadAttributes = 0
1163 call s:echo('Do grep on ''' . path . ''' with pattern ''' . pattern . '''...')
1165 silent execute 'vimgrep /' . escape(pattern, '/') . '/jg ' . files
1167 call s:echo('Grep done on ''' . path . ''' with pattern ''' . pattern . '''.')
1170 call s:error('No match found for grep with ''' . pattern . ''' in ''' . path . '''.')
1172 call s:error(v:exception)
1175 let s:loadAttributes = 1
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)
1190 let path = s:getPath(line)
1193 call s:goToAnEditionWindow()
1194 silent execute a:mode . 'xplore ' . path
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
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()
1216 if !executable(g:myprojects_tags_generator)
1217 call s:error('Unable to find a tags generator, please define g:myprojects_tags_generator variable.')
1219 let rootPath = s:getProjectPath(a:line)
1222 let tagsPath = rootPath . s:osSlash . g:myprojects_tags_file
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
1233 call s:message('Unable to generate tags file for project ''' . s:getProjectName(a:line) . ''' : ' . v:exception)
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)
1253 let head = fnamemodify(path, ':h')
1255 let headType = getftype(head)
1259 elseif headType != 'dir'
1260 throw 'Path ''' . head . ''' exists but it is not a directory.'
1262 elseif type != 'file'
1263 throw 'Unable to open ''' . path . ''' of type ''' . type . '''.'
1264 elseif !filereadable(path)
1265 throw 'Unable to read file ''' . path . '''.'
1268 if g:myprojects_auto_resize
1269 call s:setWindowWidth(g:myprojects_width)
1272 if g:myprojects_auto_close
1273 call s:closeMyProjectsWindow()
1276 let window = bufwinnr('^' . path . '$')
1279 silent execute window . 'wincmd w'
1280 silent execute 'buffer ' . path
1282 call s:goToAnEditionWindow()
1284 let command = a:command . ' ' . fnameescape(path)
1287 silent execute command
1289 if s:input('Save ''' . expand(bufname('%'), ':p') . ''' and load ''' . path . ''' ? [y/N]: ', '') != 'y'
1293 silent execute command
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
1309 let cd = s:unescape(cd)
1311 if getftype(cd) != 'dir'
1312 throw 'Unable to change directory to ' . cd . '.'
1314 let cd = resolve(cd)
1316 if getftype(cd) != 'dir'
1317 call s:warningMessage('Path ''' . cd . ''' is not a valid working directory.')
1319 let cd = fnameescape(cd)
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
1330 call s:warningMessage('Unable to go to working directory ''' . cd . '''.')
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), '|')
1343 silent execute 'setlocal makeprg=' . s:escape(make)
1346 if errorFormat != ''
1347 silent execute 'setlocal errorformat=' . s:escape(errorFormat)
1351 let tail = fnamemodify(path, ':t')
1352 let rootTail = fnamemodify(tail, ':r')
1354 while rootTail != tail
1356 let rootTail = fnamemodify(tail, ':r')
1359 silent execute 'nnoremap <silent> <buffer> <LocalLeader>et :call <SID>openTest(''split'', ''' . path . ''', ''' . tail . test . ''')<CR>'
1364 if !hasmapto('<Plug>MyProjectsGoTo')
1365 map <buffer> <silent> <C-Tab> <Plug>MyProjectsGoTo
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
1375 " Function s:append() {{{2
1376 function s:append(line)
1377 let path = s:getPath(a:line)
1380 if getftype(path) != 'file' || !filereadable(path)
1381 call s:error('Unable to read file ' . path . '.')
1383 call s:goToAnEditionWindow()
1384 silent execute ':r ' . path
1391 " Function s:getNestedAttribute() {{{2
1392 function s:getNestedAttribute(name, 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)]
1402 let line = s:getFirstFolderLine(line)
1406 if empty(attribute) && s:hasAttribute(a:name, line)
1407 let attribute = [line, s:extractAttribute(a:name, line)]
1410 while line > 0 && empty(attribute)
1411 if s:has{a:name}(line)
1412 let attribute = [line, s:extract{a:name}(line)]
1414 let line = s:getFirstFolderLine(line)
1418 if empty(attribute) && s:has{a:name}(line)
1419 let attribute = [line, s:extract{a:name}(line)]
1426 " Function s:getNestedPath() {{{2
1427 function s:getNestedPath(line)
1428 return s:getNestedAttribute('Path', a:line)
1431 " Function s:getNestedCd() {{{2
1432 function s:getNestedCd(line)
1433 return s:getNestedAttribute('Cd', a:line)
1436 " Function s:getNestedMappings() {{{2
1437 function s:getNestedMappings(line)
1443 let mapping = s:getNestedAttribute('F' . index, a:line)
1446 let mappings[index] = mapping
1455 " Function s:getNestedFilter() {{{2
1456 function s:getNestedFilter(line)
1457 return s:getNestedAttribute('Filter', a:line)
1460 " Function s:getNestedMake() {{{2
1461 function s:getNestedMake(line)
1462 return s:getNestedAttribute('Make', a:line)
1465 " Function s:getNestedErrorFormat() {{{2
1466 function s:getNestedErrorFormat(line)
1467 return s:getNestedAttribute('errorformat', a:line)
1470 " Function s:getNestedTest() {{{2
1471 function s:getNestedTest(line)
1472 return s:getNestedAttribute('test', a:line)
1475 " Function s:hasAttribute() {{{2
1476 function s:hasAttribute(name, line)
1477 return getline(a:line) =~ '.*\%(\%(\\\)\@<! \)\+' . a:name . '="[^"]\{-}"'
1480 " Function s:hasPath() {{{2
1481 function s:hasPath(line)
1482 return substitute(getline(a:line), '^\t*[^\t].\{-}\(\%(\\\)\@<!\%( \|=\)\)', '\1', '') =~ '^='
1485 " Function s:hasCd() {{{2
1486 function s:hasCd(line)
1487 return s:hasAttribute('cd', a:line)
1490 " Function s:hasFilter() {{{2
1491 function s:hasFilter(line)
1492 return s:hasAttribute('filter', a:line)
1495 " Function s:hasMapping() {{{2
1496 function s:hasMapping(mapping, line)
1497 return s:hasAttribute(a:mapping, a:line)
1500 " Function s:hasMake() {{{2
1501 function s:hasMake(line)
1502 return s:hasAttribute('make', a:line)
1505 " Function s:hasErrorFormat() {{{2
1506 function s:hasErrorFormat(line)
1507 return s:hasAttribute('errorformat', a:line)
1510 " Function s:hasTest() {{{2
1511 function s:hasTest(line)
1512 return s:hasAttribute('test', a:line)
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)
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 . '''.')
1533 call s:error(v:exception)
1539 " Function s:setCd() {{{2
1540 function s:setCd(line)
1542 let path = s:getPath(a:line)
1545 let cd = s:getNestedCd(a:line)
1546 let currentCd = empty(cd) ? '' : cd[1]
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))
1555 call s:message('Working directory set with ''' . newCd . ''' on ''' . path . '''.')
1558 call s:error(v:exception)
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)
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 . '''.')
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)
1593 for [key, mapping] in items(s:inputMappings('Set mapping for ''' . path . ''': ', {}))
1595 call s:echo('Set mappings on ''' . path . '''...')
1596 call s:updateAttribute(a:line, 'F' . key, mapping)
1598 call s:message('Mappings set on ''' . path . '''.')
1605 " Function s:setMake() {{{2
1606 function s:setMake(line)
1607 if !s:hasMake(a:line)
1608 let path = s:getPath(a:line)
1611 let make = s:getNestedMake(a:line)
1612 let currentMake = empty(make) ? '' : make[1]
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)
1621 call s:message('Make set with ''' . newMake . ''' on ''' . path . '''.')
1624 call s:error(v:exception)
1630 " Function s:setErrorFormat() {{{2
1631 function s:setErrorFormat(line)
1632 if !s:hasErrorFormat(a:line)
1633 let path = s:getPath(a:line)
1636 let errorFormat = s:getNestedErrorFormat(a:line)
1637 let currentErrorFormat = empty(errorFormat) ? '' : errorFormat[1]
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)
1646 call s:message('Error format set with ''' . newErrorFormat . ''' on ''' . path . '''.')
1649 call s:error(v:exception)
1655 " Function s:setTest() {{{2
1656 function s:setTest(line)
1657 if !s:hasTest(a:line)
1658 let path = s:getPath(a:line)
1661 let test = s:getNestedTest(a:line)
1662 let currentTest = empty(test) ? '' : test[1]
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)
1671 call s:message('Test set with ''' . newTest . ''' on ''' . path . '''.')
1674 call s:error(v:exception)
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 . '="[^"]\{-}"', '', '')
1686 call s:substitute(a:line, '\s\+' . a:attribute . '="[^"]\{-}"', ' ' . a:attribute . '="' . escape(a:value, '\%&') . '"', '')
1689 call s:substitute(a:line, '\(^.\+$\)', '\1 ' . a:attribute . '="' . escape(a:value, '\%&') . '"', '')
1693 " Function s:updatePath() {{{2
1694 function s:updatePath(line)
1695 let path = s:getNestedPath(a:line)
1698 let [pathLine, currentPath] = path
1701 let name = s:getName(pathLine)
1702 let newPath = s:cleanPath(s:inputRealPath('Update path for ''' . name . ''': ', '', 1))
1705 if newPath == currentPath
1706 call s:echo('Path not updated for ''' . name . '''.')
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 . '''.')
1714 call s:error(v:exception)
1719 " Function s:updateCd() {{{2
1720 function s:updateCd(line)
1721 let cd = s:getNestedCd(a:line)
1724 let [cdLine, currentCd] = cd
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 . '''.')
1733 call s:echo('Update working directory with ''' . newCd . ''' on ''' . path . '''...')
1734 call s:updateAttribute(cdLine, 'cd', s:escape(newCd))
1736 call s:message('Working directory updated with ''' . newCd . ''' on ''' . path . '''.')
1739 call s:error(v:exception)
1744 " Function s:updateFilter() {{{2
1745 function s:updateFilter(line)
1746 let filter = s:getNestedFilter(a:line)
1749 let [filterLine, currentFilter] = filter
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 . '''.')
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 . '''.')
1765 call s:error(v:exception)
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]
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)
1795 call s:message('Mappings updated on ''' . path . '''.')
1799 " Function s:updateMake() {{{2
1800 function s:updateMake(line)
1801 let make = s:getNestedMake(a:line)
1804 let [makeLine, currentMake] = make
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 . '''.')
1813 call s:echo('Update make with ''' . newMake . ''' on ''' . path . '''...')
1814 call s:updateAttribute(makeLine, 'make', newMake)
1816 call s:message('Make updated with ''' . newMake . ''' on ''' . path . '''.')
1819 call s:error(v:exception)
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
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 . '''.')
1838 call s:echo('Update error format with ''' . newErrorFormat . ''' on ''' . path . '''...')
1839 call s:updateAttribute(errorFormatLine, 'errorformat', newErrorFormat)
1841 call s:message('Error format updated with ''' . newErrorFormat . ''' on ''' . path . '''.')
1844 call s:error(v:exception)
1850 " Function s:updateTest() {{{2
1851 function s:updateTest(line)
1852 let test = s:getNestedTest(a:line)
1855 let [testLine, currentTest] = test
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 . '''.')
1864 call s:echo('Update test with ''' . newTest . ''' on ''' . path . '''...')
1865 call s:updateAttribute(testLine, 'test', newTest)
1867 call s:message('Test updated with ''' . newTest . ''' on ''' . path . '''.')
1870 call s:error(v:exception)
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)
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.'
1892 let output = system(a:bin . ' ' . a:arguments)
1902 " Function s:svn() {{{2
1903 function s:svn(arguments)
1904 return s:system('svn', a:arguments)
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)
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)
1927 " Function s:svnStatus() {{{2
1928 function s:svnStatus(line)
1929 let path = s:getPath(a:line)
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 . '''.')
1938 call s:svnError('Svn status failed on ''' . path . ''' :', v:exception)
1943 " Function s:svnUpdate() {{{2
1944 function s:svnUpdate(line)
1945 let path = s:getPath(a:line)
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'")
1955 if g:myprojects_sort_svn
1956 let files = sort(files)
1959 call s:refresh(a:line, 0)
1962 call s:putInMyProjectsWindow(files)
1963 call s:message('Svn update done on ''' . path . '''.')
1965 call s:svnError('Svn update failed on ''' . path . ''' :', v:exception)
1970 " Function s:svnCommitStepOne() {{{2
1971 function s:svnCommitStepOne(line)
1972 let path = s:getPath(a:line)
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
1985 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnCommitStepTwo()'
1987 call s:svnError('Unable to retrieve files to revert in ''' . path . ''' :', v:exception)
1992 " Function s:svnCommitStepTwo() {{{2
1993 function s:svnCommitStepTwo()
1996 let files = getbufline('%', 1, '$')
1998 call filter(files, 'strpart(v:val, 0, 6) =~# "[MDAR]"')
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)
2008 setlocal buftype=acwrite
2010 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnCommitStepThree()'
2014 " Function s:svnCommitStepThree() {{{2
2015 function s:svnCommitStepThree()
2019 let message = filter(getbufline('%', 1, '$'), "v:val !~# '^" . escape(s:prompt, '[]') . "'")
2023 call map(files, "substitute(v:val, '^[^\\s]\\+\\s', '', '')")
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, ', ') . '.')
2030 call s:svnError('Svn commit failed on files ''' . join(files, ''', ''') . ''':', v:exception)
2034 " Function s:svnRevertStepOne() {{{2
2035 function s:svnRevertStepOne(line)
2036 let path = s:getPath(a:line)
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
2048 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnRevertStepTwo()'
2050 call s:svnError('Unable to retrieve files to revert in ''' . path . ''':', v:exception)
2055 " Function s:svnRevertStepTwo() {{{2
2056 function s:svnRevertStepTwo()
2059 let files = filter(getbufline('%', 1, '$'), 'strpart(v:val, 0, 6) =~# ''\%(M\|D\|R\|C\)''')
2061 silent! execute 'bwipeout ' . s:sid . 'svn'
2064 call map(files, "substitute(v:val, '^[^\\s]\\+\\s', '', '')")
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, ', ') . '.')
2071 call s:svnError('Svn revert failed on ''' . path . ''':', v:exception)
2076 " Function s:svnAddStepOne() {{{2
2077 function s:svnAddStepOne(line)
2078 let path = s:getPath(a:line)
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
2090 execute 'au! ' . s:plugin . ' BufWriteCmd <buffer> call ' . s:sid . 'svnAddStepTwo()'
2092 call s:svnError('Unable to retrieve files to add in ''' . path . ''':', v:exception)
2097 " Function s:svnAddStepTwo() {{{2
2098 function s:svnAddStepTwo()
2101 let files = getbufline('%', 1, '$')
2103 silent! execute 'bwipeout ' . s:sid . 'svn'
2105 call filter(files, "v:val =~ '^?'")
2108 call map(files, "substitute(v:val, '^[^\\s]\\+\\s', '', '')")
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, ', ') . '.')
2115 call s:svnError('Svn add failed on ''' . path . ''':', v:exception)
2120 " Function s:svnDiff() {{{2
2121 function s:svnDiff(line)
2122 let path = s:getPath(a:line)
2125 let path = resolve(path)
2127 if getftype(path) != 'file'
2128 call s:error('Unable to diff ''' . path . ''' because it is not a file.')
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'
2142 if !s:diffBuffers[0]['wrap']
2146 silent execute 'setlocal foldmethod=' . s:diffBuffers[0]['foldmethod']
2147 silent execute 'setlocal foldcolumn=' . s:diffBuffers[0]['foldcolumn']
2151 if bufexists(s:diffBuffers[1])
2152 silent execute 'bwipeout ' . s:diffBuffers[1]
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
2167 silent execute 'setlocal filetype=' . filetype
2168 setlocal bufhidden=delete
2169 setlocal buftype=nofile
2170 setlocal nobuflisted
2172 silent! 0put=previousVersion
2175 setlocal nomodifiable
2179 call add(s:diffBuffers, bufnr('%'))
2181 let file = s:prompt .'Svn diff of ''' . path . ''''
2184 let &titlestring = file
2186 silent execute 'augroup ' . s:plugin
2187 silent execute 'au! BufEnter <buffer> let &titlestring ="' . file . '"'
2192 call s:error('Unable to diff ''' . path . ''' : ' . v:exception . '.')
2198 " Function s:svnBlame() {{{2
2199 function s:svnBlame(line)
2200 let path = s:getPath(a:line)
2203 let path = resolve(path)
2205 if getftype(path) != 'file'
2206 call s:error('Unable to blame ''' . path . ''' because it is not a file.')
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
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]
2235 setlocal nomodifiable
2237 let file = s:prompt .'Svn blame of ''' . path . ''''
2240 let &titlestring = file
2242 silent execute 'augroup ' . s:plugin
2243 silent execute 'au! BufEnter <buffer> let &titlestring ="' . file . '"'
2246 call s:error('Unable to blame ''' . path . ''' : ' . v:exception . '.')
2252 " Function s:svnCheckout() {{{2
2253 function s:svnCheckout(line)
2254 let indent = s:indent(a:line)
2258 let project = s:defineProject()
2260 let svn = s:input('Svn reporitory of project ''' . project[0] . ''': ', '')
2263 throw 'Svn repository must not be empty.'
2265 let svnCommand = 'checkout --non-interactive ' . shellescape(svn)
2267 let svnUser = s:input('Svn user of project ''' . project[0] . ''': ', '')
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)
2279 let svnCommand .= ' ' . shellescape(project[1][project[0]]['attributes']['path'])
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))
2290 call s:svnError('Unable to checkout ''' . svn . ''' in ''' . project[1][project[0]]['attributes']['path'] . ''':', v:exception)
2294 call s:error(v:exception)
2299 " Function s:svnLog() {{{2
2300 function s:svnLog(line)
2301 let path = s:getPath(a:line)
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.')
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 . '''.')
2327 call s:svnError('Svn status failed on ''' . path . ''' :', v:exception)
2333 " Function s:refreshSvnConflictWindow() {{{2
2334 function s:refreshSvnConflictWindow(path)
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 . '''.')
2341 call s:svnError('Unable to retrieve conflict files in ''' . a:path . ''':', v:exception)
2345 " Function s:svnResolve() {{{2
2346 function s:svnResolve(line)
2347 let path = s:getPath(a:line)
2350 call s:refreshSvnConflictWindow(path)
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 . '''.')
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>'
2368 call s:svnError('Unable to resolve conflict for file ''' . path . ''':', v:exception)
2373 " Function s:svnInfo() {{{2
2374 function s:svnInfo(line)
2375 let path = s:getPath(a:line)
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")
2387 let lineLength = strlen(substitute(line, '^\([^:]\+:\).*$', '\1', ''))
2389 if lineLength > maxLength
2390 let maxLength = lineLength
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 . '''.')
2398 call s:svnError('Svn info failed on ''' . path . ''':', v:exception)
2403 " Function s:getRawBuffers() {{{2
2404 function s:getRawBuffers(hidden)
2415 return split(rawBuffers, "\n")
2418 " Function s:getBuffers() {{{2
2419 function s:getBuffers(hidden)
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
2435 " Function s:getProjectBuffers() {{{2
2436 function s:getProjectBuffers(project, path, delete)
2437 let projectBuffers = []
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)
2446 let projectBuffers = values(buffers)
2448 if g:myprojects_sort_buffers
2449 let projectBuffers = sort(projectBuffers)
2452 call map(projectBuffers, 'substitute(v:val, ''^' . a:path . ''', '''', '''')')
2455 return projectBuffers
2458 " Function s:toggleProjectBuffers() {{{2
2459 function s:toggleProjectBuffers(project, path, delete)
2461 if !s:createBufferWindow('Buffers of project ''' . a:project . ''' in ''' . a:path . '''', a:project, a:path)
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>'') . ")"'
2472 call s:putInMyProjectsWindow(s:getProjectBuffers(a:project, a:path, a:delete))
2477 " Function s:refreshProjectBuffers() {{{2
2478 function s:refreshProjectBuffers(project, path, delete)
2479 if s:refreshProjectBuffers
2480 let window = bufwinnr(s:sid . a:project)
2483 silent execute window . 'wincmd w'
2484 call s:putInMyProjectsWindow(s:getProjectBuffers(a:project, a:path, a:delete))
2490 " Function s:deleteProjectBuffers() {{{2
2491 function s:deleteProjectBuffers(line, path)
2492 let line = a:path . getline(a:line)
2495 let buffer = bufnr(line)
2498 if getbufvar(buffer, '&modified') == 1
2499 call s:error('Sorry, no write since last change for buffer ' . line . ', unable to delete')
2501 let position = getpos('.')
2502 let currentBuffer = bufnr('%')
2504 silent! execute 'bdelete ' . buffer
2507 silent! execute bufwinnr(currentBuffer) . ' wincmd w'
2508 call setpos('.', position)
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)
2520 " Function s:echoMyprojectsFile() {{{2
2521 function s:echoMyprojectsFile()
2522 call s:echo('Currently used file ' . g:myprojects_file)
2525 " Function s:getSessionFile() {{{2
2526 function s:getSessionFile(line)
2529 let projectPath = s:getProjectPath(a:line)
2532 let projectPath = substitute(projectPath, '^[a-zA-Z]:\(.*\)', '', '')
2535 if projectPath != ''
2536 let path = g:myprojects_sessions_directory . projectPath
2542 " Function s:saveSession() {{{2
2543 function s:saveSession(line)
2544 call s:goToMyProjectsWindow()
2547 if !isdirectory(g:myprojects_sessions_directory)
2548 call s:mkdir(g:myprojects_sessions_directory)
2551 if !isdirectory(g:myprojects_sessions_directory)
2552 throw 'Unable to create session, directory ' . g:myprojects_sessions_directory . ' does not exist.'
2554 let session = s:getSessionFile(a:line)
2557 throw 'Unable to create session.'
2559 let head = fnamemodify(session, ':h')
2561 let headType = getftype(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.'
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', '')
2579 execute 'mksession! ' . session
2581 call s:echo('Session saved in ''' . session . '''.')
2585 call s:error(v:exception)
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 . '''.')
2598 let s:quitVimIfMyProjectsIsAlone = 0
2599 execute 'source ' . session
2600 let s:quitVimIfMyProjectsIsAlone = 1
2602 if has('syntax') && g:myprojects_syntax
2606 call s:echo('Session loaded from ''' . session . '''.')
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 . '.')
2621 " Function s:getMyProjects() {{{2
2622 function s:getMyProjects(line)
2625 let name = s:unescape(s:getName(a:line))
2628 let myprojects[name] = {}
2632 let pathAttribute = s:extractPathFromLine(a:line)
2634 if pathAttribute != ''
2635 let attributes['path'] = pathAttribute
2638 let cdAttribute = s:extractCdFromLine(a:line, 0)
2640 if cdAttribute != ''
2641 let attributes['cd'] = cdAttribute
2644 if s:hasFilter(a:line)
2645 let attributes['filter'] = s:extractFilterFromLine(a:line)
2648 let mappings = s:extractMappingsFromLine(a:line)
2651 let attributes['mappings'] = mappings
2654 let make = s:extractMakeFromLine(a:line)
2657 let attributes['make'] = make
2660 let errorFormat = s:extractErrorFormatFromLine(a:line)
2662 if !empty(errorFormat)
2663 let attributes['errorformat'] = errorFormat
2666 let test = s:extractTestFromLine(a:line)
2669 let attributes['test'] = test
2672 let refresh = s:extractRefreshFromLine(a:line)
2675 let attributes['refresh'] = refresh
2678 if !empty(attributes)
2679 let myprojects[name]['attributes'] = attributes
2682 if s:isFolder(a:line)
2683 let oldPosition = s:setCursorPosition([0, a:line, 1])
2685 let endLine = s:getLastFolderLine(a:line)
2686 let regex = '^' . repeat('\t', (s:indent(a:line) + 1)) . '[^\t]\+$'
2687 let file = search(regex, '', endLine)
2690 call add(files, s:getMyProjects(file))
2691 let file = search(regex, '', endLine)
2695 let myprojects[name]['files'] = files
2698 call s:setCursorPosition(oldPosition)
2705 " Function s:buildMyProjects() {{{2
2706 function s:buildMyProjects(path, filter, myprojects, refresh, indent)
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']))
2723 if has_key(meta['attributes'], 'cd') && meta['attributes']['cd'] != ''
2724 let myprojects .= ' cd="' . s:escape(s:cleanPath(meta['attributes']['cd'])) . '"'
2727 if has_key(meta['attributes'], 'filter')
2728 let myprojects .= ' filter="' . meta['attributes']['filter'] . '"'
2729 let filter = meta['attributes']['filter']
2732 if has_key(meta['attributes'], 'make') && meta['attributes']['make'] != ''
2733 let myprojects .= ' make="' . meta['attributes']['make'] . '"'
2736 if has_key(meta['attributes'], 'errorformat') && meta['attributes']['errorformat'] != ''
2737 let myprojects .= ' errorformat="' . meta['attributes']['errorformat'] . '"'
2740 if has_key(meta['attributes'], 'refresh') && meta['attributes']['refresh'] != ''
2741 let refresh = meta['attributes']['refresh']
2744 if has_key(meta['attributes'], 'test') && meta['attributes']['test'] != ''
2745 let myprojects .= ' test="' . meta['attributes']['test'] . '"'
2748 if has_key(meta['attributes'], 'mappings')
2749 for [index, mapping] in items(meta['attributes']['mappings'])
2750 let myprojects .= ' F' . index . '="' . mapping . '"'
2755 if getftype(path) != 'dir'
2756 let myprojects .= "\n"
2758 let myprojects .= ' refresh="' . localtime() . '"' . "\n"
2760 let subFiles = !has_key(meta, 'files') ? [] : meta['files']
2764 for subName in subFiles
2765 let files .= s:buildMyProjects(path, filter, subName, refresh, a:indent + 1)
2768 let notInMyProjectsFiles = s:getFilesNotInMyprojects(path, filter, a:indent, refresh, subFiles)
2770 if g:myprojects_new_file_on_bottom
2771 let files .= notInMyProjectsFiles
2773 let files = notInMyProjectsFiles . files
2776 if files != '' || g:myprojects_display_empty_folder
2777 let myprojects .= files
2788 " Function s:isInMyprojects() {{{2
2789 function s:isInMyprojects(name, files)
2791 if has_key(file, a:name)
2799 " Function s:getFilesNotInMyprojects() {{{2
2800 function s:getFilesNotInMyprojects(path, filter, indent, refresh, myprojects)
2803 let path = resolve(a:path)
2805 if getftype(path) != 'dir'
2806 call s:warningMessage('Path ''' . path . ''' is not a directory.')
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)
2819 silent execute 'lcd ' . fnameescape(cwd)
2821 call s:warningMessage('Unable to go to working directory ''' . path . '''.')
2828 " Function s:getLineOfPath() {{{2
2829 function s:getLineOfPath(path)
2832 if getftype(a:path) == 'file'
2833 call s:openMyProjectsWindow()
2834 let line = s:searchPath(a:path, 0)
2840 " Function s:openFromMyProjectsWindow() {{{2
2841 function s:openFromMyProjectsWindow(command, path)
2842 let line = s:getLineOfPath(resolve(a:path))
2847 call s:edit(a:command, line)
2851 " Function s:openTest() {{{2
2852 function s:openTest(command, path, test)
2853 let line = s:getLineOfPath(a:path)
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)
2865 let lines[line] = s:getPath(line)
2866 let line = search('\%(^\t*\|\/\)' . a:test . '\%(\s\|=\|$\)', 'W', lastProjectLine)
2869 call s:setCursorPosition(oldPosition)
2871 let linesLength = len(lines)
2874 call s:error('No test file ''' . a:test . ''' found for ''' . a:path . '''')
2879 let line = get(keys(lines), 0)
2881 let list = ['There is several test file ''' . a:test . ''' found for ''' . a:path . ''':']
2886 for [line, path] in items(lines)
2887 let list = add(list, index . '. ' . path)
2888 let keys[index] = line
2892 let index = inputlist(list)
2894 if has_key(keys, index)
2895 let line = keys[index]
2901 call s:edit(a:command, line)
2903 call s:error(v:exception)
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
2921 " Function s:resolveSvnConflict() {{{2
2922 function s:resolveSvnConflict(command, path)
2924 call s:openFromSvnWindow(a:command)
2925 execute 'au! ' . s:plugin . ' BufWritePost <buffer> call ' . s:sid . 'svnMarkAsResolved(''' . a:path . ''')'
2927 call s:error(v:exception)
2931 " Function s:openFromSvnWindow() {{{2
2932 function s:openFromSvnWindow(command)
2934 call s:openFromMyProjectsWindow(a:command, substitute(getline('.'), '^[[:space:]ACDIMRX?!~]\?[[:space:]CM]\?[[:space:]L]\?[[:space:]+]\?[[:space:]SX]\?[[:space:]K]\?[[:space:]C]\?\s*', '', ''))
2936 call s:error(v:exception)
2940 " Function s:openFromBuffersWindow() {{{2
2941 function s:openFromBuffersWindow(command, path)
2943 call s:openFromMyProjectsWindow(a:command, a:path . getline('.'))
2945 call s:error(v:exception)
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)
2958 call s:svnDiff(line)
2962 " Function s:svnDiffFromSvnWindow() {{{2
2963 function s:svnDiffFromSvnWindow()
2964 call s:svnDiffFromMyProjectWindow(getline('.'))
2968 " Function s:setCursorPosition() {{{2
2969 function s:setCursorPosition(position)
2970 let oldPosition = getpos('.')
2971 call setpos('.', a:position)
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
2984 " Function s:autowrite() {{{2
2985 function s:autowrite()
2986 if g:myprojects_autowrite
2991 " Function s:sid() {{{2
2993 return matchstr(expand('<sfile>'), '<SNR>\d\+_\zesid$')
2996 " Function s:setLocal() {{{2
2997 function s:setLocal(name, bool)
2998 silent execute 'setlocal ' . (a:bool ? a:name : 'no' . a:name)
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
3010 " Function s:input() {{{2
3011 function s:input(prompt, ...)
3014 let prompt = s:getPromptedString(a:prompt)
3017 return input(prompt)
3019 return input(prompt, a:1)
3021 return input(prompt, a:1, a:2)
3025 " Function s:inputSecret() {{{2
3026 function s:inputSecret(prompt, ...)
3029 let prompt = s:getPromptedString(a:prompt)
3032 return inputsecret(prompt)
3034 return inputsecret(prompt, a:1)
3037 " Function s:indent() {{{2
3038 function s:indent(line)
3039 return indent(a:line) / &tabstop
3042 " Function s:put() {{{2
3043 function s:put(data, line)
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'
3053 call s:goToLine(a:line)
3057 " Function s:putInMyProjectsWindow() {{{2
3058 function s:putInMyProjectsWindow(lines)
3061 silent! 0put =substitute(join(a:lines, \"\n\"), '\n\s*$', '', '')
3063 setlocal nomodifiable
3065 setlocal buftype=nofile
3068 call s:setWindowHeight(line('$'))
3071 " Function s:getPromptedString() {{{2
3072 function s:getPromptedString(message)
3073 return s:prompt . substitute(a:message, '^@', '', 'g')
3076 " Function s:getPromptedStringLength() {{{2
3077 function s:getPromptedStringLength(message)
3078 return strlen(s:getPromptedString(a:message)) + 20
3081 " Function s:echo() {{{2
3082 function s:echo(message)
3084 echo s:getPromptedString(a:message)
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
3110 " Function s:error() {{{2
3111 function s:error(message)
3113 call s:echo(a:message)
3117 " Function s:message() {{{2
3118 function s:message(message)
3120 echomsg s:getPromptedString(a:message)
3123 " Function s:errorMessage() {{{2
3124 function s:errorMessage(message)
3126 call s:message(a:message)
3130 " Function s:warningMessage() {{{2
3131 function s:warningMessage(message)
3133 call s:message(a:message)
3137 " Function s:escape() {{{2
3138 function s:escape(path)
3139 return substitute(a:path, '\%(\\\)\@<!\([ "=]\)', '\\\1', 'g')
3142 " Function s:unescape() {{{2
3143 function s:unescape(path)
3144 return substitute(a:path, '\\\([ ="]\)', '\1', 'g')
3147 " Function s:goToLine() {{{2
3148 function s:goToLine(line)
3149 silent execute 'normal! ' . a:line . 'G'
3153 " Function s:getFiles() {{{2
3154 function s:getFiles(path, filter)
3157 let path = resolve(a:path)
3159 if !isdirectory(path)
3160 call s:warningMessage('Path ''' . path . ''' is not a directory.')
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
3177 silent execute 'lcd ' . cwd
3179 call s:warningMessage('Unable to go to directory ''' . path . '''.')
3186 " Function s:pathExists() {{{2
3187 function s:pathExists(path)
3188 let type = getftype(a:path)
3190 return type == 'dir' || type == 'file'
3193 " Function s:searchPath() {{{2
3194 function s:searchPath(path, line)
3197 let file = fnamemodify(a:path, ':t')
3200 let oldPosition = s:setCursorPosition([0, a:line, 1])
3202 let line = search('\%(^\t*\|\/\)' . file . '\%(\s\|=\|$\)', 'W')
3205 let path = s:getPath(line)
3208 call s:setCursorPosition(oldPosition)
3211 let line = search('\%(^\t*\|\/\)' . file . '\%(\s\|=\|$\)', 'W')
3216 call s:setCursorPosition(oldPosition)
3220 " Function s:cleanPath() {{{2
3221 function s:cleanPath(path)
3222 return substitute(a:path, escape(s:osSlash, '\') . '\+$', '', '')
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.')
3230 call mkdir(a:path, 'p')
3232 if getftype(a:path) != 'dir'
3233 throw 'Unable to create directory ' . a:path . '.')
3238 " Function s:moveWindowToTopLeftCorner() {{{2
3239 function s:moveWindowToTopLeftCorner()
3243 " Function s:setWindowWidth() {{{2
3244 function s:setWindowWidth(width)
3245 silent execute 'vertical resize ' . a:width
3248 " Function s:setWindowHeight() {{{2
3249 function s:setWindowHeight(height)
3250 silent execute 'resize ' . a:height
3257 " Enable myprojects {{{2
3258 let g:myprojects_enable = 1
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')
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"
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')
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"
3330 " vim:filetype=vim foldmethod=marker shiftwidth=3 tabstop=3