diff options
Diffstat (limited to 'modules/vim/vim.dot.link/plugin/project.vim')
-rw-r--r-- | modules/vim/vim.dot.link/plugin/project.vim | 1293 |
1 files changed, 1293 insertions, 0 deletions
diff --git a/modules/vim/vim.dot.link/plugin/project.vim b/modules/vim/vim.dot.link/plugin/project.vim new file mode 100644 index 0000000..47bd379 --- /dev/null +++ b/modules/vim/vim.dot.link/plugin/project.vim @@ -0,0 +1,1293 @@ +"============================================================================= +" File: project.vim +" Author: Aric Blumer (Aric.Blumer at aricvim@charter.net) +" Last Change: Fri 13 Oct 2006 09:47:08 AM EDT +" Version: 1.4.1 +"============================================================================= +" See documentation in accompanying help file +" You may use this code in whatever way you see fit. + +if exists('loaded_project') || &cp + finish +endif +let loaded_project=1 + +function! s:Project(filename) " <<< + " Initialization <<< + if exists("g:proj_running") + if strlen(a:filename) != 0 + call confirm('Project already loaded; ignoring filename "'.a:filename."\".\n".'See ":help project-invoking" for information about changing project files.', "&OK", 1) + endif + let filename=bufname(g:proj_running) + else + if strlen(a:filename) == 0 + let filename ='~/.vimprojects' " Default project filename + else + let filename = a:filename + endif + endif + if !exists('g:proj_window_width') + let g:proj_window_width=24 " Default project window width + endif + if !exists('g:proj_window_increment') + let g:proj_window_increment=100 " Project Window width increment + endif + if !exists('g:proj_flags') + if has("win32") || has("mac") + let g:proj_flags='imst' " Project default flags for windows/mac + else + let g:proj_flags='imstb' " Project default flags for everything else + endif + endif + if !exists("g:proj_running") || (bufwinnr(g:proj_running) == -1) " Open the Project Window + exec 'silent vertical new '.filename + if match(g:proj_flags, '\CF') == -1 " We're floating + silent! wincmd H + exec 'vertical resize '.g:proj_window_width + endif + setlocal nomodeline + else + silent! 99wincmd h + if bufwinnr(g:proj_running) == -1 + vertical split + let v:errmsg="nothing" + silent! bnext + if 'nothing' != v:errmsg + enew + endif + endif + return + endif + " Process the flags + let b:proj_cd_cmd='cd' + if match(g:proj_flags, '\Cl') != -1 + let b:proj_cd_cmd = 'lcd' + endif + + let b:proj_locate_command='silent! wincmd H' + let b:proj_resize_command='exec ''vertical resize ''.g:proj_window_width' + if match(g:proj_flags, '\CF') != -1 " Set the resize commands to nothing + let b:proj_locate_command='' + let b:proj_resize_command='' + endif + + let g:proj_last_buffer = -1 + ">>> + " ProjFoldText() <<< + " The foldtext function for displaying just the description. + function! ProjFoldText() + let line=substitute(getline(v:foldstart),'^[ \t#]*\([^=]*\).*', '\1', '') + let line=strpart(' ', 0, (v:foldlevel - 1)).substitute(line,'\s*{\+\s*', '', '') + return line + endfunction ">>> + " s:DoSetup() <<< + " Ensure everything is set up + function! s:DoSetup() + setlocal foldenable foldmethod=marker foldmarker={,} commentstring=%s foldcolumn=0 nonumber noswapfile shiftwidth=1 + setlocal foldtext=ProjFoldText() nobuflisted nowrap + setlocal winwidth=1 + if match(g:proj_flags, '\Cn') != -1 + setlocal number + endif + endfunction ">>> + call s:DoSetup() + " Syntax Stuff <<< + if match(g:proj_flags, '\Cs')!=-1 && has('syntax') && exists('g:syntax_on') && !has('syntax_items') + syntax match projectDescriptionDir '^\s*.\{-}=\s*\(\\ \|\f\|:\|"\)\+' contains=projectDescription,projectWhiteError + syntax match projectDescription '\<.\{-}='he=e-1,me=e-1 contained nextgroup=projectDirectory contains=projectWhiteError + syntax match projectDescription '{\|}' + syntax match projectDirectory '=\(\\ \|\f\|:\)\+' contained + syntax match projectDirectory '=".\{-}"' contained + syntax match projectScriptinout '\<in\s*=\s*\(\\ \|\f\|:\|"\)\+' contains=projectDescription,projectWhiteError + syntax match projectScriptinout '\<out\s*=\s*\(\\ \|\f\|:\|"\)\+' contains=projectDescription,projectWhiteError + syntax match projectComment '#.*' + syntax match projectCD '\<CD\s*=\s*\(\\ \|\f\|:\|"\)\+' contains=projectDescription,projectWhiteError + syntax match projectFilterEntry '\<filter\s*=.*"' contains=projectWhiteError,projectFilterError,projectFilter,projectFilterRegexp + syntax match projectFilter '\<filter='he=e-1,me=e-1 contained nextgroup=projectFilterRegexp,projectFilterError,projectWhiteError + syntax match projectFlagsEntry '\<flags\s*=\( \|[^ ]*\)' contains=projectFlags,projectWhiteError + syntax match projectFlags '\<flags' contained nextgroup=projectFlagsValues,projectWhiteError + syntax match projectFlagsValues '=[^ ]* 'hs=s+1,me=e-1 contained contains=projectFlagsError + syntax match projectFlagsError '[^rtTsSwl= ]\+' contained + syntax match projectWhiteError '=\s\+'hs=s+1 contained + syntax match projectWhiteError '\s\+='he=e-1 contained + syntax match projectFilterError '=[^"]'hs=s+1 contained + syntax match projectFilterRegexp '=".*"'hs=s+1 contained + syntax match projectFoldText '^[^=]\+{' + + highlight def link projectDescription Identifier + highlight def link projectScriptinout Identifier + highlight def link projectFoldText Identifier + highlight def link projectComment Comment + highlight def link projectFilter Identifier + highlight def link projectFlags Identifier + highlight def link projectDirectory Constant + highlight def link projectFilterRegexp String + highlight def link projectFlagsValues String + highlight def link projectWhiteError Error + highlight def link projectFlagsError Error + highlight def link projectFilterError Error + endif ">>> + " s:SortR(start, end) <<< + " Sort lines. SortR() is called recursively. + " from ":help eval-examples" by Robert Webb, slightly modified + function! s:SortR(start, end) + if (a:start >= a:end) + return + endif + let partition = a:start - 1 + let middle = partition + let partStr = getline((a:start + a:end) / 2) + let i = a:start + while (i <= a:end) + let str = getline(i) + if str < partStr + let result = -1 + elseif str > partStr + let result = 1 + else + let result = 0 + endif + if (result <= 0) + let partition = partition + 1 + if (result == 0) + let middle = partition + endif + if (i != partition) + let str2 = getline(partition) + call setline(i, str2) + call setline(partition, str) + endif + endif + let i = i + 1 + endwhile + if (middle != partition) + let str = getline(middle) + let str2 = getline(partition) + call setline(middle, str2) + call setline(partition, str) + endif + call s:SortR(a:start, partition - 1) + call s:SortR(partition + 1, a:end) + endfunc ">>> + " s:IsAbsolutePath(path) <<< + " Returns true if filename has an absolute path. + function! s:IsAbsolutePath(path) + if a:path =~ '^ftp:' || a:path =~ '^rcp:' || a:path =~ '^scp:' || a:path =~ '^http:' + return 2 + endif + if a:path =~ '\$' + let path=expand(a:path) " Expand any environment variables that might be in the path + else + let path=a:path + endif + if path[0] == '/' || path[0] == '~' || path[0] == '\\' || path[1] == ':' + return 1 + endif + return 0 + endfunction " >>> + " s:DoSetupAndSplit() <<< + " Call DoSetup to ensure the settings are correct. Split to the next + " file. + function! s:DoSetupAndSplit() + call s:DoSetup() " Ensure that all the settings are right + let n = winnr() " Determine if there is a CTRL_W-p window + silent! wincmd p + if n == winnr() + silent! wincmd l + endif + if n == winnr() + " If n == winnr(), then there is no CTRL_W-p window + " So we have to create a new one + if bufnr('%') == g:proj_running + exec 'silent vertical new' + else + exec 'silent vertical split | silent! bnext' + endif + wincmd p " Go back to the Project Window and ensure it is the right width + exec b:proj_locate_command + exec b:proj_resize_command + wincmd p + endif + endfunction ">>> + " s:DoSetupAndSplit_au() <<< + " Same as above but ensure that the Project window is the current + " window. Only called from an autocommand + function! s:DoSetupAndSplit_au() + if winbufnr(0) != g:proj_running + return + endif + call s:DoSetup() " Ensure that all the settings are right + if winbufnr(2) == -1 " We're the only window right now. + exec 'silent vertical split | bnext' + if bufnr('%') == g:proj_running + enew + endif + if bufnr('%') == g:proj_last_buffer | bnext | bprev | bnext | endif + wincmd p " Go back to the Project Window and ensure it is the right width + exec b:proj_locate_command + exec b:proj_resize_command + elseif(winnr() != 1) + exec b:proj_locate_command + exec b:proj_resize_command + endif + endfunction + function! s:RecordPrevBuffer_au() + let g:proj_last_buffer = bufnr('%') + endfunction ">>> + " s:RecursivelyConstructDirectives(lineno) <<< + " Construct the inherited directives + function! s:RecursivelyConstructDirectives(lineno) + let lineno=s:FindFoldTop(a:lineno) + let foldlineno = lineno + let foldlev=foldlevel(lineno) + let parent_infoline = '' + if foldlev > 1 + while foldlevel(lineno) >= foldlev " Go to parent fold + if lineno < 1 + echoerr 'Some kind of fold error. Check your syntax.' + return + endif + let lineno = lineno - 1 + endwhile + let parent_infoline = s:RecursivelyConstructDirectives(lineno) + endif + let parent_home = s:GetHome(parent_infoline, '') + let parent_c_d = s:GetCd(parent_infoline, parent_home) + let parent_scriptin = s:GetScriptin(parent_infoline, parent_home) + let parent_scriptout = s:GetScriptout(parent_infoline, parent_home) + let parent_filter = s:GetFilter(parent_infoline, '*') + let infoline = getline(foldlineno) + " Extract the home directory of this fold + let home=s:GetHome(infoline, parent_home) + if home != '' + if (foldlevel(foldlineno) == 1) && !s:IsAbsolutePath(home) + call confirm('Outermost Project Fold must have absolute path! Or perhaps the path does not exist.', "&OK", 1) + let home = '~' " Some 'reasonable' value + endif + endif + " Extract any CD information + let c_d = s:GetCd(infoline, home) + if c_d != '' + if (foldlevel(foldlineno) == 1) && !s:IsAbsolutePath(c_d) + call confirm('Outermost Project Fold must have absolute CD path! Or perhaps the path does not exist.', "&OK", 1) + let c_d = '.' " Some 'reasonable' value + endif + else + let c_d=parent_c_d + endif + " Extract scriptin + let scriptin = s:GetScriptin(infoline, home) + if scriptin == '' + let scriptin = parent_scriptin + endif + " Extract scriptout + let scriptout = s:GetScriptout(infoline, home) + if scriptout == '' + let scriptout = parent_scriptout + endif + " Extract filter + let filter = s:GetFilter(infoline, parent_filter) + if filter == '' | let filter = parent_filter | endif + return s:ConstructInfo(home, c_d, scriptin, scriptout, '', filter) + endfunction ">>> + " s:ConstructInfo(home, c_d, scriptin, scriptout, flags, filter) <<< + function! s:ConstructInfo(home, c_d, scriptin, scriptout, flags, filter) + let retval='Directory='.a:home + if a:c_d[0] != '' + let retval=retval.' CD='.a:c_d + endif + if a:scriptin[0] != '' + let retval=retval.' in='.a:scriptin + endif + if a:scriptout[0] != '' + let retval=retval.' out='.a:scriptout + endif + if a:filter[0] != '' + let retval=retval.' filter="'.a:filter.'"' + endif + return retval + endfunction ">>> + " s:OpenEntry(line, precmd, editcmd) <<< + " Get the filename under the cursor, and open a window with it. + function! s:OpenEntry(line, precmd, editcmd, dir) + silent exec a:precmd + if (a:editcmd[0] != '') + if a:dir + let fname='.' + else + if (foldlevel(a:line) == 0) && (a:editcmd[0] != '') + return 0 " If we're outside a fold, do nothing + endif + let fname=substitute(getline(a:line), '\s*#.*', '', '') " Get rid of comments and whitespace before comment + let fname=substitute(fname, '^\s*\(.*\)', '\1', '') " Get rid of leading whitespace + if strlen(fname) == 0 + return 0 " The line is blank. Do nothing. + endif + endif + else + let fname='.' + endif + let infoline = s:RecursivelyConstructDirectives(a:line) + let retval=s:OpenEntry2(a:line, infoline, fname, a:editcmd) + call s:DisplayInfo() + return retval + endfunction + ">>> + " s:OpenEntry2(line, infoline, precmd, editcmd) <<< + " Get the filename under the cursor, and open a window with it. + function! s:OpenEntry2(line, infoline, fname, editcmd) + let fname=escape(a:fname, ' %#') " Thanks to Thomas Link for cluing me in on % and # + let home=s:GetHome(a:infoline, '').'/' + if home=='/' + echoerr 'Project structure error. Check your syntax.' + return + endif + "Save the cd command + let cd_cmd = b:proj_cd_cmd + if a:editcmd[0] != '' " If editcmd is '', then just set up the environment in the Project Window + call s:DoSetupAndSplit() + " If it is an absolute path, don't prepend home + if !s:IsAbsolutePath(fname) + let fname=home.fname + endif + if s:IsAbsolutePath(fname) == 2 + exec a:editcmd.' '.fname + else + silent exec 'silent '.a:editcmd.' '.fname + endif + else " only happens in the Project File + exec 'au! BufEnter,BufLeave '.expand('%:p') + endif + " Extract any CD information + let c_d = s:GetCd(a:infoline, home) + if c_d != '' && (s:IsAbsolutePath(home) != 2) + if match(g:proj_flags, '\CL') != -1 + call s:SetupAutoCommand(c_d) + endif + if !isdirectory(glob(c_d)) + call confirm("From this fold's entry,\nCD=".'"'.c_d.'" is not a valid directory.', "&OK", 1) + else + silent exec cd_cmd.' '.c_d + endif + endif + " Extract any scriptin information + let scriptin = s:GetScriptin(a:infoline, home) + if scriptin != '' + if !filereadable(glob(scriptin)) + call confirm('"'.scriptin.'" not found. Ignoring.', "&OK", 1) + else + call s:SetupScriptAutoCommand('BufEnter', scriptin) + exec 'source '.scriptin + endif + endif + let scriptout = s:GetScriptout(a:infoline, home) + if scriptout != '' + if !filereadable(glob(scriptout)) + call confirm('"'.scriptout.'" not found. Ignoring.', "&OK", 1) + else + call s:SetupScriptAutoCommand('BufLeave', scriptout) + endif + endif + return 1 + endfunction + ">>> + " s:DoFoldOrOpenEntry(cmd0, cmd1) <<< + " Used for double clicking. If the mouse is on a fold, open/close it. If + " not, try to open the file. + function! s:DoFoldOrOpenEntry(cmd0, cmd1) + if getline('.')=~'{\|}' || foldclosed('.') != -1 + normal! za + else + call s:DoEnsurePlacementSize_au() + call s:OpenEntry(line('.'), a:cmd0, a:cmd1, 0) + if (match(g:proj_flags, '\Cc') != -1) + let g:proj_mywinnumber = winbufnr(0) + Project + hide + if(g:proj_mywinnumber != winbufnr(0)) + wincmd p + endif + wincmd = + endif + endif + endfunction ">>> + " s:VimDirListing(filter, padding, separator, filevariable, filecount, dirvariable, dircount) <<< + function! s:VimDirListing(filter, padding, separator, filevariable, filecount, dirvariable, dircount) + let end = 0 + let files='' + let filter = a:filter + " Chop up the filter + " Apparently glob() cannot take something like this: glob('*.c *.h') + let while_var = 1 + while while_var + let end = stridx(filter, ' ') + if end == -1 + let end = strlen(filter) + let while_var = 0 + endif + let single=glob(strpart(filter, 0, end)) + if strlen(single) != 0 + let files = files.single."\010" + endif + let filter = strpart(filter, end + 1) + endwhile + " files now contains a list of everything in the directory. We need to + " weed out the directories. + let fnames=files + let {a:filevariable}='' + let {a:dirvariable}='' + let {a:filecount}=0 + let {a:dircount}=0 + while strlen(fnames) > 0 + let fname = substitute(fnames, '\(\(\f\|[ :\[\]]\)*\).*', '\1', '') + let fnames = substitute(fnames, '\(\f\|[ :\[\]]\)*.\(.*\)', '\2', '') + if isdirectory(glob(fname)) + let {a:dirvariable}={a:dirvariable}.a:padding.fname.a:separator + let {a:dircount}={a:dircount} + 1 + else + let {a:filevariable}={a:filevariable}.a:padding.fname.a:separator + let {a:filecount}={a:filecount} + 1 + endif + endwhile + endfunction ">>> + " s:GenerateEntry(recursive, name, absolute_dir, dir, c_d, filter_directive, filter, foldlev, sort) <<< + function! s:GenerateEntry(recursive, line, name, absolute_dir, dir, c_d, filter_directive, filter, foldlev, sort) + let line=a:line + if a:dir =~ '\\ ' + let dir='"'.substitute(a:dir, '\\ ', ' ', 'g').'"' + else + let dir=a:dir + endif + let spaces=strpart(' ', 0, a:foldlev) + let c_d=(strlen(a:c_d) > 0) ? 'CD='.a:c_d.' ' : '' + let c_d=(strlen(a:filter_directive) > 0) ? c_d.'filter="'.a:filter_directive.'" ': c_d + call append(line, spaces.'}') + call append(line, spaces.a:name.'='.dir.' '.c_d.'{') + if a:recursive + exec 'cd '.a:absolute_dir + call s:VimDirListing("*", '', "\010", 'b:files', 'b:filecount', 'b:dirs', 'b:dircount') + cd - + let dirs=b:dirs + let dcount=b:dircount + unlet b:files b:filecount b:dirs b:dircount + while dcount > 0 + let dname = substitute(dirs, '\(\( \|\f\|:\)*\).*', '\1', '') + let edname = escape(dname, ' ') + let dirs = substitute(dirs, '\( \|\f\|:\)*.\(.*\)', '\2', '') + let line=s:GenerateEntry(1, line + 1, dname, a:absolute_dir.'/'.edname, edname, '', '', a:filter, a:foldlev+1, a:sort) + let dcount=dcount-1 + endwhile + endif + return line+1 + endfunction " >>> + " s:DoEntryFromDir(line, name, absolute_dir, dir, c_d, filter_directive, filter, foldlev, sort) <<< + " Generate the fold from the directory hierarchy (if recursive), then + " fill it in with RefreshEntriesFromDir() + function! s:DoEntryFromDir(recursive, line, name, absolute_dir, dir, c_d, filter_directive, filter, foldlev, sort) + call s:GenerateEntry(a:recursive, a:line, a:name, escape(a:absolute_dir, ' '), escape(a:dir, ' '), escape(a:c_d, ' '), a:filter_directive, a:filter, a:foldlev, a:sort) + normal! j + call s:RefreshEntriesFromDir(1) + endfunction ">>> + " s:CreateEntriesFromDir(recursive) <<< + " Prompts user for information and then calls s:DoEntryFromDir() + function! s:CreateEntriesFromDir(recursive) + " Save a mark for the current cursor position + normal! mk + let line=line('.') + let name = inputdialog('Enter the Name of the Entry: ') + if strlen(name) == 0 + return + endif + let foldlev=foldlevel(line) + if (foldclosed(line) != -1) || (getline(line) =~ '}') + let foldlev=foldlev - 1 + endif + let absolute = (foldlev <= 0)?'Absolute ': '' + let home='' + let filter='*' + if (match(g:proj_flags, '\Cb') != -1) && has('browse') + " Note that browse() is inconsistent: On Win32 you can't select a + " directory, and it gives you a relative path. + let dir = browse(0, 'Enter the '.absolute.'Directory to Load: ', '', '') + let dir = fnamemodify(dir, ':p') + else + let dir = inputdialog('Enter the '.absolute.'Directory to Load: ', '') + endif + if (dir[strlen(dir)-1] == '/') || (dir[strlen(dir)-1] == '\\') + let dir=strpart(dir, 0, strlen(dir)-1) " Remove trailing / or \ + endif + let dir = substitute(dir, '^\~', $HOME, 'g') + if (foldlev > 0) + let parent_directive=s:RecursivelyConstructDirectives(line) + let filter = s:GetFilter(parent_directive, '*') + let home=s:GetHome(parent_directive, '') + if home[strlen(home)-1] != '/' && home[strlen(home)-1] != '\\' + let home=home.'/' + endif + unlet parent_directive + if s:IsAbsolutePath(dir) + " It is not a relative path Try to make it relative + let hend=matchend(dir, '\C'.glob(home)) + if hend != -1 + let dir=strpart(dir, hend) " The directory can be a relative path + else + let home="" + endif + endif + endif + if strlen(home.dir) == 0 + return + endif + if !isdirectory(home.dir) + if has("unix") + silent exec '!mkdir '.home.dir.' > /dev/null' + else + call confirm('"'.home.dir.'" is not a valid directory.', "&OK", 1) + return + endif + endif + let c_d = inputdialog('Enter the CD parameter: ', '') + let filter_directive = inputdialog('Enter the File Filter: ', '') + if strlen(filter_directive) != 0 + let filter = filter_directive + endif + " If I'm on a closed fold, go to the bottom of it + if foldclosedend(line) != -1 + let line = foldclosedend(line) + endif + let foldlev = foldlevel(line) + " If we're at the end of a fold . . . + if getline(line) =~ '}' + let foldlev = foldlev - 1 " . . . decrease the indentation by 1. + endif + " Do the work + call s:DoEntryFromDir(a:recursive, line, name, home.dir, dir, c_d, filter_directive, filter, foldlev, 0) + " Restore the cursor position + normal! `k + endfunction ">>> + " s:RefreshEntriesFromDir(recursive) <<< + " Finds metadata at the top of the fold, and then replaces all files + " with the contents of the directory. Works recursively if recursive is 1. + function! s:RefreshEntriesFromDir(recursive) + if foldlevel('.') == 0 + echo 'Nothing to refresh.' + return + endif + " Open the fold. + if getline('.') =~ '}' + normal! zo[z + else + normal! zo]z[z + endif + let just_a_fold=0 + let infoline = s:RecursivelyConstructDirectives(line('.')) + let immediate_infoline = getline('.') + if strlen(substitute(immediate_infoline, '[^=]*=\(\(\f\|:\|\\ \)*\).*', '\1', '')) == strlen(immediate_infoline) + let just_a_fold = 1 + endif + " Extract the home directory of the fold + let home = s:GetHome(infoline, '') + if home == '' + " No Match. This means that this is just a label with no + " directory entry. + if a:recursive == 0 + return " We're done--nothing to do + endif + " Mark that it is just a fold, so later we don't delete filenames + " that aren't there. + let just_a_fold = 1 + endif + if just_a_fold == 0 + " Extract the filter between quotes (we don't care what CD is). + let filter = s:GetFilter(infoline, '*') + " Extract the description (name) of the fold + let name = substitute(infoline, '^[#\t ]*\([^=]*\)=.*', '\1', '') + if strlen(name) == strlen(infoline) + return " If there's no name, we're done. + endif + if (home == '') || (name == '') + return + endif + " Extract the flags + let flags = s:GetFlags(immediate_infoline) + let sort = (match(g:proj_flags, '\CS') != -1) + if flags != '' + if match(flags, '\Cr') != -1 + " If the flags do not contain r (refresh), then treat it just + " like a fold + let just_a_fold = 1 + endif + if match(flags, '\CS') != -1 + let sort = 1 + endif + if match(flags, '\Cs') != -1 + let sort = 0 + endif + else + let flags='' + endif + endif + " Move to the first non-fold boundary line + normal! j + " Delete filenames until we reach the end of the fold + while getline('.') !~ '}' + if line('.') == line('$') + break + endif + if getline('.') !~ '{' + " We haven't reached a sub-fold, so delete what's there. + if (just_a_fold == 0) && (getline('.') !~ '^\s*#') && (getline('.') !~ '#.*pragma keep') + d _ + else + " Skip lines only in a fold and comment lines + normal! j + endif + else + " We have reached a sub-fold. If we're doing recursive, then + " call this function again. If not, find the end of the fold. + if a:recursive == 1 + call s:RefreshEntriesFromDir(1) + normal! ]zj + else + if foldclosed('.') == -1 + normal! zc + endif + normal! j + endif + endif + endwhile + if just_a_fold == 0 + " We're not just in a fold, and we have deleted all the filenames. + " Now it is time to regenerate what is in the directory. + if !isdirectory(glob(home)) + call confirm('"'.home.'" is not a valid directory.', "&OK", 1) + else + let foldlev=foldlevel('.') + " T flag. Thanks Tomas Z. + if (match(flags, '\Ct') != -1) || ((match(g:proj_flags, '\CT') == -1) && (match(flags, '\CT') == -1)) + " Go to the top of the fold (force other folds to the + " bottom) + normal! [z + normal! j + " Skip any comments + while getline('.') =~ '^\s*#' + normal! j + endwhile + endif + normal! k + let cwd=getcwd() + let spaces=strpart(' ', 0, foldlev) + exec 'cd '.home + if match(g:proj_flags, '\Ci') != -1 + echon home."\r" + endif + call s:VimDirListing(filter, spaces, "\n", 'b:files', 'b:filecount', 'b:dirs', 'b:dircount') + if b:filecount > 0 + normal! mk + silent! put =b:files + normal! `kj + if sort + call s:SortR(line('.'), line('.') + b:filecount - 1) + endif + else + normal! j + endif + unlet b:files b:filecount b:dirs b:dircount + exec 'cd '.cwd + endif + endif + " Go to the top of the refreshed fold. + normal! [z + endfunction ">>> + " s:MoveUp() <<< + " Moves the entity under the cursor up a line. + function! s:MoveUp() + let lineno=line('.') + if lineno == 1 + return + endif + let fc=foldclosed('.') + let a_reg=@a + if lineno == line('$') + normal! "add"aP + else + normal! "addk"aP + endif + let @a=a_reg + if fc != -1 + normal! zc + endif + endfunction ">>> + " s:MoveDown() <<< + " Moves the entity under the cursor down a line. + function! s:MoveDown() + let fc=foldclosed('.') + let a_reg=@a + normal! "add"ap + let @a=a_reg + if (fc != -1) && (foldclosed('.') == -1) + normal! zc + endif + endfunction " >>> + " s:DisplayInfo() <<< + " Displays filename and current working directory when i (info) is in + " the flags. + function! s:DisplayInfo() + if match(g:proj_flags, '\Ci') != -1 + echo 'file: '.expand('%').', cwd: '.getcwd().', lines: '.line('$') + endif + endfunction ">>> + " s:SetupAutoCommand(cwd) <<< + " Sets up an autocommand to ensure that the cwd is set to the one + " desired for the fold regardless. :lcd only does this on a per-window + " basis, not a per-buffer basis. + function! s:SetupAutoCommand(cwd) + if !exists("b:proj_has_autocommand") + let b:proj_cwd_save = escape(getcwd(), ' ') + let b:proj_has_autocommand = 1 + let bufname=escape(substitute(expand('%:p', 0), '\\', '/', 'g'), ' ') + exec 'au BufEnter '.bufname." let b:proj_cwd_save=escape(getcwd(), ' ') | cd ".a:cwd + exec 'au BufLeave '.bufname.' exec "cd ".b:proj_cwd_save' + exec 'au BufWipeout '.bufname.' au! * '.bufname + endif + endfunction ">>> + " s:SetupScriptAutoCommand(bufcmd, script) <<< + " Sets up an autocommand to run the scriptin script. + function! s:SetupScriptAutoCommand(bufcmd, script) + if !exists("b:proj_has_".a:bufcmd) + let b:proj_has_{a:bufcmd} = 1 + exec 'au '.a:bufcmd.' '.escape(substitute(expand('%:p', 0), '\\', '/', 'g'), ' ').' source '.a:script + endif + endfunction " >>> + " s:DoEnsurePlacementSize_au() <<< + " Ensure that the Project window is on the left of the window and has + " the correct size. Only called from an autocommand + function! s:DoEnsurePlacementSize_au() + if (winbufnr(0) != g:proj_running) || (winnr() != 1) + if exists("g:proj_doinghelp") + if g:proj_doinghelp > 0 + let g:proj_doinghelp = g:proj_doinghelp - 1 + return + endif + unlet g:proj_doinghelp + return + endif + exec b:proj_locate_command + endif + exec b:proj_resize_command + endfunction ">>> + " s:Spawn(number) <<< + " Spawn an external command on the file + function! s:Spawn(number) + echo | if exists("g:proj_run".a:number) + let fname=getline('.') + if fname!~'{\|}' + let fname=substitute(fname, '\s*#.*', '', '') + let fname=substitute(fname, '^\s*\(.*\)\s*', '\1', '') + if fname == '' | return | endif + let parent_infoline = s:RecursivelyConstructDirectives(line('.')) + let home=expand(s:GetHome(parent_infoline, '')) + let c_d=expand(s:GetCd(parent_infoline, '')) + let command=substitute(g:proj_run{a:number}, '%%', "\010", 'g') + let command=substitute(command, '%f', escape(home.'/'.fname, '\'), 'g') + let command=substitute(command, '%F', substitute(escape(home.'/'.fname, '\'), ' ', '\\\\ ', 'g'), 'g') + let command=substitute(command, '%s', escape(home.'/'.fname, '\'), 'g') + let command=substitute(command, '%n', escape(fname, '\'), 'g') + let command=substitute(command, '%N', substitute(fname, ' ', '\\\\ ', 'g'), 'g') + let command=substitute(command, '%h', escape(home, '\'), 'g') + let command=substitute(command, '%H', substitute(escape(home, '\'), ' ', '\\\\ ', 'g'), 'g') + if c_d != '' + if c_d == home + let percent_r='.' + else + let percent_r=substitute(home, escape(c_d.'/', '\'), '', 'g') + endif + else + let percent_r=home + endif + let command=substitute(command, '%r', percent_r, 'g') + let command=substitute(command, '%R', substitute(percent_r, ' ', '\\\\ ', 'g'), 'g') + let command=substitute(command, '%d', escape(c_d, '\'), 'g') + let command=substitute(command, '%D', substitute(escape(c_d, '\'), ' ', '\\\\ ', 'g'), 'g') + let command=substitute(command, "\010", '%', 'g') + exec command + endif + endif + endfunction ">>> + " s:ListSpawn(varnamesegment) <<< + " List external commands + function! s:ListSpawn(varnamesegment) + let number = 1 + while number < 10 + if exists("g:proj_run".a:varnamesegment.number) + echohl LineNr | echo number.':' | echohl None | echon ' '.substitute(escape(g:proj_run{a:varnamesegment}{number}, '\'), "\n", '\\n', 'g') + else + echohl LineNr | echo number.':' | echohl None + endif + let number=number + 1 + endwhile + endfunction ">>> + " s:FindFoldTop(line) <<< + " Return the line number of the directive line + function! s:FindFoldTop(line) + let lineno=a:line + if getline(lineno) =~ '}' + let lineno = lineno - 1 + endif + while getline(lineno) !~ '{' && lineno > 1 + if getline(lineno) =~ '}' + let lineno=s:FindFoldTop(lineno) + endif + let lineno = lineno - 1 + endwhile + return lineno + endfunction ">>> + " s:FindFoldBottom(line) <<< + " Return the line number of the directive line + function! s:FindFoldBottom(line) + let lineno=a:line + if getline(lineno) =~ '{' + let lineno=lineno + 1 + endif + while getline(lineno) !~ '}' && lineno < line('$') + if getline(lineno) =~ '{' + let lineno=s:FindFoldBottom(lineno) + endif + let lineno = lineno + 1 + endwhile + return lineno + endfunction ">>> + " s:LoadAll(recurse, line) <<< + " Load all files in a project + function! s:LoadAll(recurse, line) + let b:loadcount=0 + function! s:SpawnExec(infoline, fname, lineno, data) + if s:OpenEntry2(a:lineno, a:infoline, a:fname, 'e') + wincmd p + let b:loadcount=b:loadcount+1 + echon b:loadcount."\r" + if getchar(0) != 0 + let b:stop_everything=1 + endif + endif + endfunction + call Project_ForEach(a:recurse, line('.'), "*<SID>SpawnExec", 0, '^\(.*l\)\@!') + delfunction s:SpawnExec + echon b:loadcount." Files Loaded\r" + unlet b:loadcount + if exists("b:stop_everything") | unlet b:stop_everything | endif + endfunction ">>> + " s:WipeAll(recurse, line) <<< + " Wipe all files in a project + function! s:WipeAll(recurse, line) + let b:wipecount=0 + let b:totalcount=0 + function! s:SpawnExec(home, c_d, fname, lineno, data) + let fname=escape(a:fname, ' ') + if s:IsAbsolutePath(fname) + let fname=fnamemodify(fname, ':n') " :n is coming, won't break anything now + else + let fname=fnamemodify(a:home.'/'.fname, ':n') " :n is coming, won't break anything now + endif + let b:totalcount=b:totalcount+1 + let fname=substitute(fname, '^\~', $HOME, 'g') + if bufloaded(substitute(fname, '\\ ', ' ', 'g')) + if getbufvar(fname.'\>', '&modified') == 1 + exec 'sb '.fname + wincmd L + w + wincmd p + endif + let b:wipecount=b:wipecount+1 + exec 'bwipe! '.fname + endif + if b:totalcount % 5 == 0 + echon b:wipecount.' of '.b:totalcount."\r" + redraw + endif + if getchar(0) != 0 + let b:stop_everything=1 + endif + endfunction + call Project_ForEach(a:recurse, line('.'), "<SID>SpawnExec", 0, '^\(.*w\)\@!') + delfunction s:SpawnExec + echon b:wipecount.' of '.b:totalcount." Files Wiped\r" + unlet b:wipecount b:totalcount + if exists("b:stop_everything") | unlet b:stop_everything | endif + endfunction ">>> + " s:LoadAllSplit(recurse, line) <<< + " Load all files in a project using split windows. + " Contributed by A. Harrison + function! s:LoadAllSplit(recurse, line) + let b:loadcount=0 + function! s:SpawnExec(infoline, fname, lineno, data) + let winNr = winnr() "get ProjectWindow number + if s:OpenEntry2(a:lineno, a:infoline, a:fname, 'sp') + exec winNr."wincmd w" + let b:loadcount=b:loadcount+1 + echon b:loadcount."\r" + if getchar(0) != 0 + let b:stop_everything=1 + endif + endif + endfunction + call Project_ForEach(a:recurse, line('.'), "*<SID>SpawnExec", 0, '^\(.*l\)\@!') + delfunction s:SpawnExec + echon b:loadcount." Files Loaded\r" + unlet b:loadcount + if exists("b:stop_everything") | unlet b:stop_everything | endif + endfunction ">>> + " s:GrepAll(recurse, lineno, pattern) <<< + " Grep all files in a project, optionally recursively + function! s:GrepAll(recurse, lineno, pattern) + cunmap <buffer> help + let pattern=(a:pattern[0] == '')?input("GREP options and pattern: "):a:pattern + cnoremap <buffer> help let g:proj_doinghelp = 1<CR>:help + if pattern[0] == '' + return + endif + let b:escape_spaces=1 + let fnames=Project_GetAllFnames(a:recurse, a:lineno, ' ') + unlet b:escape_spaces + cclose " Make sure grep window is closed + call s:DoSetupAndSplit() + if match(g:proj_flags, '\Cv') == -1 + silent! exec 'silent! grep '.pattern.' '.fnames + if v:shell_error != 0 + echo 'GREP error. Perhaps there are too many filenames.' + else + copen + endif + else + silent! exec 'silent! vimgrep '.pattern.' '.fnames + copen + endif + endfunction ">>> + " GetXXX Functions <<< + function! s:GetHome(info, parent_home) + " Thanks to Adam Montague for pointing out the need for @ in urls. + let home=substitute(a:info, '^[^=]*=\(\(\\ \|\f\|:\|@\)\+\).*', '\1', '') + if strlen(home) == strlen(a:info) + let home=substitute(a:info, '.\{-}"\(.\{-}\)".*', '\1', '') + if strlen(home) != strlen(a:info) | let home=escape(home, ' ') | endif + endif + if strlen(home) == strlen(a:info) + let home=a:parent_home + elseif home=='.' + let home=a:parent_home + elseif !s:IsAbsolutePath(home) + let home=a:parent_home.'/'.home + endif + return home + endfunction + function! s:GetFilter(info, parent_filter) + let filter = substitute(a:info, '.*\<filter="\([^"]*\).*', '\1', '') + if strlen(filter) == strlen(a:info) | let filter = a:parent_filter | endif + return filter + endfunction + function! s:GetCd(info, home) + let c_d=substitute(a:info, '.*\<CD=\(\(\\ \|\f\|:\)\+\).*', '\1', '') + if strlen(c_d) == strlen(a:info) + let c_d=substitute(a:info, '.*\<CD="\(.\{-}\)".*', '\1', '') + if strlen(c_d) != strlen(a:info) | let c_d=escape(c_d, ' ') | endif + endif + if strlen(c_d) == strlen(a:info) + let c_d='' + elseif c_d == '.' + let c_d = a:home + elseif !s:IsAbsolutePath(c_d) + let c_d = a:home.'/'.c_d + endif + return c_d + endfunction + function! s:GetScriptin(info, home) + let scriptin = substitute(a:info, '.*\<in=\(\(\\ \|\f\|:\)\+\).*', '\1', '') + if strlen(scriptin) == strlen(a:info) + let scriptin=substitute(a:info, '.*\<in="\(.\{-}\)".*', '\1', '') + if strlen(scriptin) != strlen(a:info) | let scriptin=escape(scriptin, ' ') | endif + endif + if strlen(scriptin) == strlen(a:info) | let scriptin='' | else + if !s:IsAbsolutePath(scriptin) | let scriptin=a:home.'/'.scriptin | endif | endif + return scriptin + endfunction + function! s:GetScriptout(info, home) + let scriptout = substitute(a:info, '.*\<out=\(\(\\ \|\f\|:\)\+\).*', '\1', '') + if strlen(scriptout) == strlen(a:info) + let scriptout=substitute(a:info, '.*\<out="\(.\{-}\)".*', '\1', '') + if strlen(scriptout) != strlen(a:info) | let scriptout=escape(scriptout, ' ') | endif + endif + if strlen(scriptout) == strlen(a:info) | let scriptout='' | else + if !s:IsAbsolutePath(scriptout) | let scriptout=a:home.'/'.scriptout | endif | endif + return scriptout + endfunction + function! s:GetFlags(info) + let flags=substitute(a:info, '.*\<flags=\([^ {]*\).*', '\1', '') + if (strlen(flags) == strlen(a:info)) + let flags='' + endif + return flags + endfunction ">>> + " Project_GetAllFnames(recurse, lineno, separator) <<< + " Grep all files in a project, optionally recursively + function! Project_GetAllFnames(recurse, lineno, separator) + let b:fnamelist='' + function! s:SpawnExec(home, c_d, fname, lineno, data) + if exists('b:escape_spaces') + let fname=escape(a:fname, ' ') + else + let fname=a:fname + endif + if !s:IsAbsolutePath(a:fname) + let fname=a:home.'/'.fname + endif + let b:fnamelist=b:fnamelist.a:data.fname + endfunction + call Project_ForEach(a:recurse, line('.'), "<SID>SpawnExec", a:separator, '') + delfunction s:SpawnExec + let retval=b:fnamelist + unlet b:fnamelist + return retval + endfunction ">>> + " Project_GetAllFnames(recurse, lineno, separator) <<< + " Grep all files in a project, optionally recursively + function! Project_GetFname(line) + if (foldlevel(a:line) == 0) + return '' + endif + let fname=substitute(getline(a:line), '\s*#.*', '', '') " Get rid of comments and whitespace before comment + let fname=substitute(fname, '^\s*\(.*\)', '\1', '') " Get rid of leading whitespace + if strlen(fname) == 0 + return '' " The line is blank. Do nothing. + endif + if s:IsAbsolutePath(fname) + return fname + endif + let infoline = s:RecursivelyConstructDirectives(a:line) + return s:GetHome(infoline, '').'/'.fname + endfunction ">>> + " Project_ForEach(recurse, lineno, cmd, data, match) <<< + " Grep all files in a project, optionally recursively + function! Project_ForEach(recurse, lineno, cmd, data, match) + let info=s:RecursivelyConstructDirectives(a:lineno) + let lineno=s:FindFoldTop(a:lineno) + 1 + let flags=s:GetFlags(getline(lineno - 1)) + if (flags == '') || (a:match=='') || (match(flags, a:match) != -1) + call s:Project_ForEachR(a:recurse, lineno, info, a:cmd, a:data, a:match) + endif + endfunction + function! s:Project_ForEachR(recurse, lineno, info, cmd, data, match) + let home=s:GetHome(a:info, '') + let c_d=s:GetCd(a:info, home) + let scriptin = s:GetScriptin(a:info, home) + let scriptout = s:GetScriptout(a:info, home) + let filter = s:GetFilter(a:info, '') + let lineno = a:lineno + let curline=getline(lineno) + while (curline !~ '}') && (curline < line('$')) + if exists("b:stop_everything") && b:stop_everything | return 0 | endif + if curline =~ '{' + if a:recurse + let flags=s:GetFlags(curline) + if (flags == '') || (a:match=='') || (match(flags, a:match) != -1) + let this_home=s:GetHome(curline, home) + let this_cd=s:GetCd(curline, this_home) + if this_cd=='' | let this_cd=c_d | endif + let this_scriptin=s:GetScriptin(curline, this_home) + if this_scriptin == '' | let this_scriptin=scriptin | endif + let this_scriptout=s:GetScriptin(curline, this_home) + if this_scriptout == '' | let this_scriptout=scriptout | endif + let this_filter=s:GetFilter(curline, filter) + let lineno=s:Project_ForEachR(1, lineno+1, + \s:ConstructInfo(this_home, this_cd, this_scriptin, this_scriptout, flags, this_filter), a:cmd, a:data, a:match) + else + let lineno=s:FindFoldBottom(lineno) + endif + else + let lineno=s:FindFoldBottom(lineno) + endif + else + let fname=substitute(curline, '\s*#.*', '', '') + let fname=substitute(fname, '^\s*\(.*\)', '\1', '') + if (strlen(fname) != strlen(curline)) && (fname[0] != '') + if a:cmd[0] == '*' + call {strpart(a:cmd, 1)}(a:info, fname, lineno, a:data) + else + call {a:cmd}(home, c_d, fname, lineno, a:data) + endif + endif + endif + let lineno=lineno + 1 + let curline=getline(lineno) + endwhile + return lineno + endfunction ">>> + " s:SpawnAll(recurse, number) <<< + " Spawn an external command on the files of a project + function! s:SpawnAll(recurse, number) + echo | if exists("g:proj_run_fold".a:number) + if g:proj_run_fold{a:number}[0] == '*' + function! s:SpawnExec(home, c_d, fname, lineno, data) + let command=substitute(strpart(g:proj_run_fold{a:data}, 1), '%s', escape(a:fname, ' \'), 'g') + let command=substitute(command, '%f', escape(a:fname, '\'), 'g') + let command=substitute(command, '%h', escape(a:home, '\'), 'g') + let command=substitute(command, '%d', escape(a:c_d, '\'), 'g') + let command=substitute(command, '%F', substitute(escape(a:fname, '\'), ' ', '\\\\ ', 'g'), 'g') + exec command + endfunction + call Project_ForEach(a:recurse, line('.'), "<SID>SpawnExec", a:number, '.') + delfunction s:SpawnExec + else + let info=s:RecursivelyConstructDirectives(line('.')) + let home=s:GetHome(info, '') + let c_d=s:GetCd(info, '') + let b:escape_spaces=1 + let fnames=Project_GetAllFnames(a:recurse, line('.'), ' ') + unlet b:escape_spaces + let command=substitute(g:proj_run_fold{a:number}, '%f', substitute(escape(fnames, '\'), '\\ ', ' ', 'g'), 'g') + let command=substitute(command, '%s', escape(fnames, '\'), 'g') + let command=substitute(command, '%h', escape(home, '\'), 'g') + let command=substitute(command, '%d', escape(c_d, '\'), 'g') + let command=substitute(command, '%F', escape(fnames, '\'), 'g') + exec command + if v:shell_error != 0 + echo 'Shell error. Perhaps there are too many filenames.' + endif + endif + endif + endfunction ">>> + if !exists("g:proj_running") + " s:DoProjectOnly(void) <<< + " Make the file window the only one. + function! s:DoProjectOnly() + if winbufnr(0) != g:proj_running + let lzsave=&lz + set lz + only + Project + silent! wincmd p + let &lz=lzsave + unlet lzsave + endif + endfunction + " >>> + + " Mappings <<< + nnoremap <buffer> <silent> <Return> \|:call <SID>DoFoldOrOpenEntry('', 'e')<CR> + nnoremap <buffer> <silent> <S-Return> \|:call <SID>DoFoldOrOpenEntry('', 'sp')<CR> + nnoremap <buffer> <silent> <C-Return> \|:call <SID>DoFoldOrOpenEntry('silent! only', 'e')<CR> + nnoremap <buffer> <silent> <LocalLeader>T \|:call <SID>DoFoldOrOpenEntry('', 'tabe')<CR> + nmap <buffer> <silent> <LocalLeader>s <S-Return> + nnoremap <buffer> <silent> <LocalLeader>S \|:call <SID>LoadAllSplit(0, line('.'))<CR> + nmap <buffer> <silent> <LocalLeader>o <C-Return> + nnoremap <buffer> <silent> <LocalLeader>i :echo <SID>RecursivelyConstructDirectives(line('.'))<CR> + nnoremap <buffer> <silent> <LocalLeader>I :echo Project_GetFname(line('.'))<CR> + nmap <buffer> <silent> <M-CR> <Return><C-W>p + nmap <buffer> <silent> <LocalLeader>v <M-CR> + nnoremap <buffer> <silent> <LocalLeader>l \|:call <SID>LoadAll(0, line('.'))<CR> + nnoremap <buffer> <silent> <LocalLeader>L \|:call <SID>LoadAll(1, line('.'))<CR> + nnoremap <buffer> <silent> <LocalLeader>w \|:call <SID>WipeAll(0, line('.'))<CR> + nnoremap <buffer> <silent> <LocalLeader>W \|:call <SID>WipeAll(1, line('.'))<CR> + nnoremap <buffer> <silent> <LocalLeader>W \|:call <SID>WipeAll(1, line('.'))<CR> + nnoremap <buffer> <silent> <LocalLeader>g \|:call <SID>GrepAll(0, line('.'), "")<CR> + nnoremap <buffer> <silent> <LocalLeader>G \|:call <SID>GrepAll(1, line('.'), "")<CR> + nnoremap <buffer> <silent> <2-LeftMouse> \|:call <SID>DoFoldOrOpenEntry('', 'e')<CR> + nnoremap <buffer> <silent> <S-2-LeftMouse> \|:call <SID>DoFoldOrOpenEntry('', 'sp')<CR> + nnoremap <buffer> <silent> <M-2-LeftMouse> <M-CR> + nnoremap <buffer> <silent> <S-LeftMouse> <LeftMouse> + nmap <buffer> <silent> <C-2-LeftMouse> <C-Return> + nnoremap <buffer> <silent> <C-LeftMouse> <LeftMouse> + nnoremap <buffer> <silent> <3-LeftMouse> <Nop> + nmap <buffer> <silent> <RightMouse> <space> + nmap <buffer> <silent> <2-RightMouse> <space> + nmap <buffer> <silent> <3-RightMouse> <space> + nmap <buffer> <silent> <4-RightMouse> <space> + nnoremap <buffer> <silent> <space> \|:silent exec 'vertical resize '.(match(g:proj_flags, '\Ct')!=-1 && winwidth('.') > g:proj_window_width?(g:proj_window_width):(winwidth('.') + g:proj_window_increment))<CR> + nnoremap <buffer> <silent> <C-Up> \|:silent call <SID>MoveUp()<CR> + nnoremap <buffer> <silent> <C-Down> \|:silent call <SID>MoveDown()<CR> + nmap <buffer> <silent> <LocalLeader><Up> <C-Up> + nmap <buffer> <silent> <LocalLeader><Down> <C-Down> + let k=1 + while k < 10 + exec 'nnoremap <buffer> <LocalLeader>'.k.' \|:call <SID>Spawn('.k.')<CR>' + exec 'nnoremap <buffer> <LocalLeader>f'.k.' \|:call <SID>SpawnAll(0, '.k.')<CR>' + exec 'nnoremap <buffer> <LocalLeader>F'.k.' \|:call <SID>SpawnAll(1, '.k.')<CR>' + let k=k+1 + endwhile + nnoremap <buffer> <LocalLeader>0 \|:call <SID>ListSpawn("")<CR> + nnoremap <buffer> <LocalLeader>f0 \|:call <SID>ListSpawn("_fold")<CR> + nnoremap <buffer> <LocalLeader>F0 \|:call <SID>ListSpawn("_fold")<CR> + nnoremap <buffer> <silent> <LocalLeader>c :call <SID>CreateEntriesFromDir(0)<CR> + nnoremap <buffer> <silent> <LocalLeader>C :call <SID>CreateEntriesFromDir(1)<CR> + nnoremap <buffer> <silent> <LocalLeader>r :call <SID>RefreshEntriesFromDir(0)<CR> + nnoremap <buffer> <silent> <LocalLeader>R :call <SID>RefreshEntriesFromDir(1)<CR> + " For Windows users: same as \R + nnoremap <buffer> <silent> <F5> :call <SID>RefreshEntriesFromDir(1)<CR> + nnoremap <buffer> <silent> <LocalLeader>e :call <SID>OpenEntry(line('.'), '', '', 0)<CR> + nnoremap <buffer> <silent> <LocalLeader>E :call <SID>OpenEntry(line('.'), '', 'e', 1)<CR> + " The :help command stomps on the Project Window. Try to avoid that. + " This is not perfect, but it is alot better than without the mappings. + cnoremap <buffer> help let g:proj_doinghelp = 1<CR>:help + nnoremap <buffer> <F1> :let g:proj_doinghelp = 1<CR><F1> + " This is to avoid changing the buffer, but it is not fool-proof. + nnoremap <buffer> <silent> <C-^> <Nop> + "nnoremap <script> <Plug>ProjectOnly :let lzsave=&lz<CR>:set lz<CR><C-W>o:Project<CR>:silent! wincmd p<CR>:let &lz=lzsave<CR>:unlet lzsave<CR> + nnoremap <script> <Plug>ProjectOnly :call <SID>DoProjectOnly()<CR> + if match(g:proj_flags, '\Cm') != -1 + if !hasmapto('<Plug>ProjectOnly') + nmap <silent> <unique> <C-W>o <Plug>ProjectOnly + nmap <silent> <unique> <C-W><C-O> <C-W>o + endif + endif " >>> + if filereadable(glob('~/.vimproject_mappings')) | source ~/.vimproject_mappings | endif + " Autocommands <<< + " Autocommands to clean up if we do a buffer wipe + " These don't work unless we substitute \ for / for Windows + let bufname=escape(substitute(expand('%:p', 0), '\\', '/', 'g'), ' ') + exec 'au BufWipeout '.bufname.' au! * '.bufname + exec 'au BufWipeout '.bufname.' unlet g:proj_running' + exec 'au BufWipeout '.bufname.' nunmap <C-W>o' + exec 'au BufWipeout '.bufname.' nunmap <C-W><C-O>' + " Autocommands to keep the window the specified size + exec 'au WinLeave '.bufname.' call s:DoEnsurePlacementSize_au()' + exec 'au BufEnter '.bufname.' call s:DoSetupAndSplit_au()' + au WinLeave * call s:RecordPrevBuffer_au() + " >>> + setlocal buflisted + let g:proj_running = bufnr(bufname.'\>') + if g:proj_running == -1 + call confirm('Project/Vim error. Please Enter :Project again and report this bug.', "&OK", 1) + unlet g:proj_running + endif + setlocal nobuflisted + endif +endfunction " >>> + +if exists(':Project') != 2 + command -nargs=? -complete=file Project call <SID>Project('<args>') +endif +" Toggle Mapping +if !exists("*<SID>DoToggleProject()") "<<< + function! s:DoToggleProject() + if !exists('g:proj_running') || bufwinnr(g:proj_running) == -1 + Project + else + let g:proj_mywindow = winnr() + Project + hide + if(winnr() != g:proj_mywindow) + wincmd p + endif + unlet g:proj_mywindow + endif + endfunction +endif ">>> +nnoremap <script> <Plug>ToggleProject :call <SID>DoToggleProject()<CR> +if exists('g:proj_flags') && (match(g:proj_flags, '\Cg') != -1) + if !hasmapto('<Plug>ToggleProject') + nmap <silent> <F12> <Plug>ToggleProject + endif +endif + +finish + +" vim600: set foldmethod=marker foldmarker=<<<,>>> foldlevel=1: |