From 19a30cda6029906dbfadf0ea0e284b518947e429 Mon Sep 17 00:00:00 2001 From: Iain Patterson <me@iain.cx> Date: Sat, 18 Apr 2009 10:12:13 +0100 Subject: [PATCH] Cross merge with CSR. --- .Xdefaults | 11 +- .profile.d/man.bashrc | 22 - .profile.d/p4.bashrc | 3 +- .profile.d/ssh.bashrc | 55 +- .ssh/colours/furryclan.net$ | 2 +- .ssh/hosts/iain.cx/aygalades.cambridge.iain.cx | 2 - .terminfo/r/rxvt-unicode | Bin 2168 -> 2168 bytes .vim/autoload/perforce.vim | 3715 ------------------------ .vim/autoload/perforceutils.vim | 260 -- .vim/doc/perforce.txt | 2441 ---------------- .vim/ftplugin/perforce.vim | 59 - .vim/ftplugin/selectbuf_perforce.vim | 15 - .vim/perforce/bakup.sh | 396 --- .vim/perforce/p4Utils.sh | 24 - .vim/perforce/perforcebugrep.vim | 97 - .vim/perforce/perforcemenu.vim | 335 --- .vim/perforce/perforceutils.vim | 39 - .vim/perforce/restor.sh | 125 - .vim/plugin/info.vim | 396 --- .vim/plugin/perforce.vim | 375 --- .xbindkeys/lock | 2 +- opt/{ => Linux}/bin/phier | 0 opt/bin/sshcolourterm | 24 +- opt/bin/sshterm | 8 +- 24 files changed, 49 insertions(+), 8357 deletions(-) delete mode 100644 .profile.d/man.bashrc delete mode 100755 .ssh/hosts/iain.cx/aygalades.cambridge.iain.cx delete mode 100755 .vim/autoload/perforce.vim delete mode 100755 .vim/autoload/perforceutils.vim delete mode 100755 .vim/doc/perforce.txt delete mode 100755 .vim/ftplugin/perforce.vim delete mode 100755 .vim/ftplugin/selectbuf_perforce.vim delete mode 100755 .vim/perforce/bakup.sh delete mode 100755 .vim/perforce/p4Utils.sh delete mode 100755 .vim/perforce/perforcebugrep.vim delete mode 100755 .vim/perforce/perforcemenu.vim delete mode 100755 .vim/perforce/perforceutils.vim delete mode 100755 .vim/perforce/restor.sh delete mode 100644 .vim/plugin/info.vim delete mode 100755 .vim/plugin/perforce.vim rename opt/{ => Linux}/bin/phier (100%) diff --git a/.Xdefaults b/.Xdefaults index a4b6612..1969367 100644 --- a/.Xdefaults +++ b/.Xdefaults @@ -29,14 +29,18 @@ Dtterm*dtTermView.marginWidth: 0 urxvt.foreground: white urxvt.background: black urxvt.scrollBar_right: True -urxvt.secondaryScroll: True urxvt.font: xft:DejaVu Sans Mono:pixelsize=12:aspect=0.9 urxvt.multichar_encoding: noenc urxvt.title: Penguin terminal -!urxvt.termName: xterm-color +! Centos5 refuses to read ~/.terminfo and find rxvt-unicode. +urxvt.termName: xterm-88color urxvt.saveLines: 512 urxvt.scrollstyle: next +urxvt.secondaryscroll: True urxvt.answerbackString: urxvt +! Change font size. +urxvt.keysym.M-minus: command:\033]50;xft:DejaVu Sans Mono:pixelsize=10:aspect=0.9\007 +urxvt.keysym.M-equal: command:\033]50;xft:DejaVu Sans Mono:pixelsize=12:aspect=0.9\007 ! transparency !rxvt*inheritPixmap: True @@ -45,7 +49,7 @@ rxvt*scrollBar_right: True rxvt*font: fixed rxvt*multichar_encoding: noenc rxvt*title: Penguin terminal -!rxvt*termName: xterm-color +rxvt*termName: xterm-color rxvt*saveLines: 512 !rxvt-big5*inheritPixmap: True @@ -83,4 +87,5 @@ Palette*showGrip: False XTerm.*faceName: DejaVu Sans Mono XTerm.*faceSize: 9 +! Old xterm will fall back to xterm if xterm-256color is not found. XTerm.*termName: xterm-256color diff --git a/.profile.d/man.bashrc b/.profile.d/man.bashrc deleted file mode 100644 index 605b9c6..0000000 --- a/.profile.d/man.bashrc +++ /dev/null @@ -1,22 +0,0 @@ -# Use vim for manpages and infopages. -# Requires vim 5+ and info.vim plugin. -# - -vimmajor=$(vim --help 2>&1 | head -n 1 | sed 's/^VIM[^0-9]*\([0-9]*\)\..*/\1/') - -function vman() { - vim -c "runtime ftplugin/man.vim" -c "Man ${1-man}" \ - -c "set nolist noruler ls=0" +"wincmd o" -} - -function vinfo() { - vim -c "Info ${1-info}" \ - -c "set nolist noruler ls=0" +"wincmd o" -} - -if [ ! -z "$vimmajor" -a $vimmajor -gt 4 ]; then - alias man=vman - alias info=vinfo -fi - -unset vimmajor diff --git a/.profile.d/p4.bashrc b/.profile.d/p4.bashrc index 0422ee8..7cdb1db 100644 --- a/.profile.d/p4.bashrc +++ b/.profile.d/p4.bashrc @@ -1,3 +1,4 @@ +# $Id: p4.bashrc 151 2008-11-20 13:59:19Z iain $ if [ ! -z "$SUDO_USER" ]; then export P4USER=$SUDO_USER export P4TICKETS=/tmp/.p4tickets.$SUDO_USER @@ -10,5 +11,5 @@ export P4EDITOR="vim -S '$HOME/.vim/script/p4'" if [ -z "$DISPLAY" ]; then export P4MERGE="vim -o -c '3wincmd j' -c 'wincmd L'" else - export P4MERGE="p4v -merge" + export P4MERGE="p4merge" fi diff --git a/.profile.d/ssh.bashrc b/.profile.d/ssh.bashrc index 17cd4bb..0bb5011 100644 --- a/.profile.d/ssh.bashrc +++ b/.profile.d/ssh.bashrc @@ -1,46 +1,17 @@ -SOCKET=~/.ssh/agent - -function get_agent_pid() { - ps waux | grep -- ^$USER\ .\*ssh-agent\ -a\ .\*\ -s | grep -v grep | awk '{ print $2 }' | head -n 1 -} - -if [ ! -z "$SSH_CLIENT" ]; then - # Set display if we aren't already forwarding X11 - if [ "$DISPLAY" = "" ]; then - export DISPLAY="$(echo $SSH_CLIENT | cut -s -d ' ' -f 1):0" - fi -fi - -# Try to hook up with already running ssh-agent. if [ $UID -gt 0 ]; then - # Not all OSes support ``ps -wu''. - RUNNING_AGENT="$(get_agent_pid)" - - # Has the socket gone away? - if [ ! -z "$RUNNING_AGENT" -a ! -S "$SOCKET" ]; then - if kill $RUNNING_AGENT; then - RUNNING_AGENT="$(get_agent_pid)" - else - echo >&2 "$SOCKET has gone away but agent is running as PID $RUNNING_AGENT." - fi - fi - - if [ -z "$SSH_AGENT_PID" -o ! "$SSH_AGENT_PID" = "$RUNNING_AGENT" ]; then - export SSH_AGENT_PID="$RUNNING_AGENT" - if [ "$SSH_AGENT_PID" = "" ]; then - unset SSH_AGENT_PID - unset SSH_AUTH_SOCK - # Start ssh-agent up then. - rm -f "$SOCKET" - eval $(/usr/bin/ssh-agent -a "$SOCKET" -s) - trap "kill $SSH_AGENT_PID" 0 - ssh-add - else - export SSH_AUTH_SOCK="$SOCKET" + # Hack to prevent confusion between two agents when launched from xdm. + if [ ! $SHLVL = 1 -o -z "$DESKTOP_SESSION" ]; then + # Read a list of hosts which can run an agent from ~/.ssh/agenthosts. + if [ -f ~/.ssh/agenthosts ]; then + while read allowed; do + if [ "${HOSTNAME%%.*}" = "$allowed" ]; then + eval $(keychain -q --timeout 7200 --agents ssh --eval) + if tty -s; then + ssh-add -l >/dev/null || ssh-add + fi + fi + done < ~/.ssh/agenthosts + unset allowed fi fi - unset RUNNING_AGENT fi - -unset SOCKET -unset get_agent_pid diff --git a/.ssh/colours/furryclan.net$ b/.ssh/colours/furryclan.net$ index ee9ee8b..e19361a 120000 --- a/.ssh/colours/furryclan.net$ +++ b/.ssh/colours/furryclan.net$ @@ -1 +1 @@ -Brown:#a06000 \ No newline at end of file +DarkBrown:#804000 \ No newline at end of file diff --git a/.ssh/hosts/iain.cx/aygalades.cambridge.iain.cx b/.ssh/hosts/iain.cx/aygalades.cambridge.iain.cx deleted file mode 100755 index d394b13..0000000 --- a/.ssh/hosts/iain.cx/aygalades.cambridge.iain.cx +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exec sshterm $(basename "$0") diff --git a/.terminfo/r/rxvt-unicode b/.terminfo/r/rxvt-unicode index 3970893be1575bc984095fb1beb5d1fc6517338a..8bb2b4265821c5b5d8b932f5d531ceb87785c5f9 100644 GIT binary patch delta 40 vcmew%@IzpOA{$3SLSkZCT6+3qb2cqLT}M49ZD$=91J?|<O!v)+Y~oA+4(SWl delta 39 ucmew%@IzpOBAb}DvyO|dqn?w2YeGU|Vp>{ydWKu3`(#Zvt<8yS;!FVh3=7Br diff --git a/.vim/autoload/perforce.vim b/.vim/autoload/perforce.vim deleted file mode 100755 index 460ef9c..0000000 --- a/.vim/autoload/perforce.vim +++ /dev/null @@ -1,3715 +0,0 @@ -" perforce.vim: Please see plugin/perforce.vim - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - - -""" BEGIN: Initializations {{{ - -" Determine the script id. -function! s:MyScriptId() - map <SID>xx <SID>xx - let s:sid = maparg("<SID>xx") - unmap <SID>xx - return substitute(s:sid, "xx$", "", "") -endfunction -let s:myScriptId = s:MyScriptId() -delfunction s:MyScriptId " This is not needed anymore. - -""" BEGIN: One-time initialization of some script variables {{{ -let s:lastMsg = '' -let s:lastMsgGrp = 'None' -" Indicates the current recursion level for executing p4 commands. -let s:recLevel = 0 - -if genutils#OnMS() && match(&shell, '\<bash\>') != -1 - " When using cygwin bash with native vim, p4 gets confused by the PWD, which - " is in cygwin style. - let s:p4CommandPrefix = "unset PWD && " -else - let s:p4CommandPrefix = "" -endif - -" Special characters in a filename that are not acceptable in a filename (as a -" window title) on windows. -let s:specialChars = '\([*:?"<>|]\)' -let s:specialCharsMap = { - \ '*': 'S', - \ ':': 'C', - \ '?': 'Q', - \ '"': 'D', - \ '<': 'L', - \ '>': 'G', - \ '|': 'P', - \ } - -" -" A lot of metadata on perforce command syntax and handling. -" - -let s:p4KnownCmds = split('add,admin,annotate,branch,branches,change,changes,' . - \ 'client,clients,counter,counters,delete,depot,depots,describe,diff,' . - \ 'diff2,dirs,edit,filelog,files,fix,fixes,flush,fstat,get,group,' . - \ 'groups,have,help,info,integ,integrate,integrated,job,jobs,jobspec,' . - \ 'label,labels,labelsync,lock,logger,login,monitor,obliterate,opened,' . - \ 'passwd,print,protect,rename,reopen,resolve,resolved,revert,review,' . - \ 'reviews,set,submit,sync,triggers,typemap,unlock,user,users,verify,' . - \ 'where,workspaces,', ',') -" Add some built-in commands to this list. -let s:builtinCmds = split('vdiff,vdiff2,exec,', ',') -let s:allCommands = s:p4KnownCmds + s:builtinCmds -let s:p4KnownCmdsCompStr = '' - -" Map between the option and the commands that reqire us to pass an argument -" with this option. -let s:p4OptCmdMap = {} -let s:p4OptCmdMap['b'] = split('diff2,integrate', ',') -let s:p4OptCmdMap['c'] = split('add,delete,edit,fix,fstat,integrate,lock,' . - \ 'opened,reopen,r[ver],review,reviews,submit,unlock', ',') -let s:p4OptCmdMap['e'] = ['jobs'] -let s:p4OptCmdMap['j'] = ['fixes'] -let s:p4OptCmdMap['l'] = ['labelsync'] -let s:p4OptCmdMap['m'] = split('changes,filelog,jobs', ',') -let s:p4OptCmdMap['o'] = ['print'] -let s:p4OptCmdMap['s'] = split('changes,integrate', ',') -let s:p4OptCmdMap['t'] = split('add,client,edit,label,reopen', ',') -let s:p4OptCmdMap['O'] = ['passwd'] -let s:p4OptCmdMap['P'] = ['passwd'] -let s:p4OptCmdMap['S'] = ['set'] - -" These built-in options require us to pass an argument. These options start -" with a '+'. -let s:biOptCmdMap = {} -let s:biOptCmdMap['c'] = ['diff'] - -" Map the commands with short name to their long versions. -let s:shortCmdMap = {} -let s:shortCmdMap['p'] = 'print' -let s:shortCmdMap['d'] = 'diff' -let s:shortCmdMap['e'] = 'edit' -let s:shortCmdMap['a'] = 'add' -let s:shortCmdMap['r'] = 'revert' -let s:shortCmdMap['g'] = 'get' -let s:shortCmdMap['o'] = 'open' -let s:shortCmdMap['d2'] = 'diff2' -let s:shortCmdMap['h'] = 'help' - - -" NOTE: The current file is used as the default argument, only when the -" command is not one of the s:askUserCmds and it is not one of -" s:curFileNotDefCmds or s:nofileArgsCmds. -" For these commands, we don't need to default to the current file, as these -" commands can work without any arguments. -let s:curFileNotDefCmds = split('change,changes,client,files,integrate,job,' . - \ 'jobs,jobspec,labels,labelsync,opened,resolve,submit,user,', ',') -" For these commands, we need to ask user for the argument, as we can't assume -" the current file is the default. -let s:askUserCmds = split('admin,branch,counter,depot,fix,group,label,', ',') -" A subset of askUserCmds, that should use a more generic prompt. -let s:genericPromptCmds = split('admin,counter,fix,', ',') -" Commands that essentially display a list of files. -let s:filelistCmds = split('files,have,integrate,opened,', ',') -" Commands that work with a spec. -let s:specCmds = split('branch,change,client,depot,group,job,jobspec,label,' . - \ 'protect,submit,triggers,typemap,user,', ',') -" Out of the above specCmds, these are the only commands that don't -" support '-o' option. Consequently we have to have our own template. -let s:noOutputCmds = ['submit'] -" The following are used only to create a specification, not to view them. -" Consequently, they don't accept a '-d' option to delete the spec. -let s:specOnlyCmds = split('jobspec,submit,', ',') -" These commands might change the fstat of files, requiring an update on some -" or all the buffers loaded into vim. -"let s:statusUpdReqCmds = 'add,delete,edit,get,lock,reopen,revert,sync,unlock,' -"" For these commands we need to call :checktime, as the command might have -"" changed the state of the file. -"let s:checktimeReqCmds = 'edit,get,reopen,revert,sync,' -" For these commands, we can even set 'autoread' along with doing a :checktime. -let s:autoreadCmds = split('edit,get,reopen,revert,sync,', ',') -" These commands don't expect filename arguments, so no special processing for -" file expansion. -let s:nofileArgsCmds = split('branch,branches,change,client,clients,counters,' . - \ 'depot,depots,describe,dirs,group,groups,help,info,job,jobspec,label,' . - \ 'logger,passwd,protect,rename,review,triggers,typemap,user,users,', ',') -" For these commands, the output should not be set to perforce type. -let s:ftNotPerforceCmds = split('diff,diff2,print,vdiff,vdiff2', ',') -" Allows navigation keys in the command window. -let s:navigateCmds = ['help'] -" These commands accept a '-m' argument to limit the list size. -let s:limitListCmds = split('filelog,jobs,changes,', ',') -" These commands take the diff option -dx. -let s:diffCmds = split('describe,diff,diff2,', ',') -" The following commands prefer dialog output. If the output exceeds -" g:p4MaxLinesInDialog, we should switch to showing the output in a window. -let s:dlgOutputCmds = - \ split('add,delete,edit,get,lock,reopen,revert,sync,unlock,', ',') - -" If there is a confirm message, then PFIF() will prompt user before -" continuing with the run. -let s:confirmMsgs{'revert'} = "Reverting file(s) will overwrite any edits to " . - \ "the files(s)\n Do you want to continue?" -let s:confirmMsgs{'submit'} = "This will commit the changelist to the depot." . - \ "\n Do you want to continue?" - -" Settings that are not directly exposed to the user. These can be accessed -" using the public API. -" Refresh the contents of perforce windows, even if the window is already open. -let s:refreshWindowsAlways = 1 - -" List of the global variable names of the user configurable settings. -let s:settings = split('ClientRoot,CmdPath,Presets,' . - \ 'DefaultOptions,DefaultDiffOptions,EnableMenu,EnablePopupMenu,' . - \ 'UseExpandedMenu,UseExpandedPopupMenu,EnableRuler,RulerWidth,' . - \ 'DefaultListSize,EnableActiveStatus,OptimizeActiveStatus,' . - \ 'ASIgnoreDefPattern,ASIgnoreUsrPattern,PromptToCheckout,' . - \ 'CheckOutDefault,UseGUIDialogs,MaxLinesInDialog,SortSettings,' . - \ 'TempDir,SplitCommand,UseVimDiff2,EnableFileChangedShell,' . - \ 'BufHidden,Depot,Autoread,UseClientViewMap,DefaultPreset', ',') -let s:settingsCompStr = '' - -let s:helpWinName = 'P4\ help' - -" Unprotected space. -let s:SPACE_AS_SEP = genutils#CrUnProtectedCharsPattern(' ') -let s:EMPTY_STR = '^\_s*$' - -if !exists('s:p4Client') || s:p4Client =~# s:EMPTY_STR - let s:p4Client = $P4CLIENT -endif -if !exists('s:p4User') || s:p4User =~# s:EMPTY_STR - if exists("$P4USER") && $P4USER !~# s:EMPTY_STR - let s:p4User = $P4USER - elseif genutils#OnMS() && exists("$USERNAME") - let s:p4User = $USERNAME - elseif exists("$LOGNAME") - let s:p4User = $LOGNAME - elseif exists("$USERNAME") " Happens if you are on cygwin too. - let s:p4User = $USERNAME - else - let s:p4User = '' - endif -endif -if !exists('s:p4Port') || s:p4Port =~# s:EMPTY_STR - let s:p4Port = $P4PORT -endif -let s:p4Password = $P4PASSWD - -let s:CM_RUN = 'run' | let s:CM_FILTER = 'filter' | let s:CM_DISPLAY = 'display' -let s:CM_PIPE = 'pipe' - -let s:changesExpr = "matchstr(getline(\".\"), '" . - \ '^Change \zs\d\+\ze ' . "')" -let s:branchesExpr = "matchstr(getline(\".\"), '" . - \ '^Branch \zs[^ ]\+\ze ' . "')" -let s:labelsExpr = "matchstr(getline(\".\"), '" . - \ '^Label \zs[^ ]\+\ze ' . "')" -let s:clientsExpr = "matchstr(getline(\".\"), '" . - \ '^Client \zs[^ ]\+\ze ' . "')" -let s:usersExpr = "matchstr(getline(\".\"), '" . - \ '^[^ ]\+\ze <[^@>]\+@[^>]\+> ([^)]\+)' . "')" -let s:jobsExpr = "matchstr(getline(\".\"), '" . - \ '^[^ ]\+\ze on ' . "')" -let s:depotsExpr = "matchstr(getline(\".\"), '" . - \ '^Depot \zs[^ ]\+\ze ' . "')" -let s:describeExpr = 's:DescribeGetCurrentItem()' -let s:filelogExpr = 's:GetCurrentDepotFile(line("."))' -let s:groupsExpr = 'expand("<cword>")' - -let s:fileBrowseExpr = 's:ConvertToLocalPath(s:GetCurrentDepotFile(line(".")))' -let s:openedExpr = s:fileBrowseExpr -let s:filesExpr = s:fileBrowseExpr -let s:haveExpr = s:fileBrowseExpr -let s:integrateExpr = s:fileBrowseExpr -" Open in describe window should open the local file. -let s:describeOpenItemExpr = s:fileBrowseExpr - -" If an explicit handler is defined, then it will override the default rule of -" finding the command with the singular form. -let s:filelogItemHandler = "s:printHdlr" -let s:changesItemHandler = "s:changeHdlr" -let s:openedItemHandler = "s:OpenFile" -let s:describeItemHandler = "s:OpenFile" -let s:filesItemHandler = "s:OpenFile" -let s:haveItemHandler = "s:OpenFile" - -" Define handlers for built-in commands. These have no arguments, they will -" use the existing parsed command-line vars. Set s:errCode on errors. -let s:builtinCmdHandler{'vdiff'} = 's:VDiffHandler' -let s:builtinCmdHandler{'vdiff2'} = 's:VDiff2Handler' -let s:builtinCmdHandler{'exec'} = 's:ExecHandler' - -let s:vdiffCounter = 0 - -" A stack of contexts. -let s:p4Contexts = [] - -" Cache of client view mappings, with client name as the key. -let s:fromDepotMapping = {} -let s:toDepotMapping = {} - -aug Perforce | aug END " Define autocommand group. -call genutils#AddToFCShellPre('perforce#FileChangedShell') - -""" END: One-time initialization of some script variables }}} - -""" END: Initializations }}} - - -""" BEGIN: Command specific functions {{{ - -function! s:printHdlr(scriptOrigin, outputType, ...) - let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'print'] - \ +a:000) - - if s:StartBufSetup() - let undo = 0 - " The first line printed by p4 for non-q operation causes vim to misjudge - " the filetype. - if getline(1) =~# '//[^#]\+#\d\+ - ' - setlocal modifiable - let firstLine = getline(1) - silent! 1delete _ - endif - - set ft= - doautocmd filetypedetect BufNewFile - " If automatic detection doesn't work... - if &ft == "" - let &ft=s:GuessFileTypeForCurrentWindow() - endif - - if exists('firstLine') - silent! 1put! =firstLine - setlocal nomodifiable - endif - - call s:EndBufSetup() - endif - return retVal -endfunction - -function! s:describeHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'describe']+a:000) - endif - " If -s doesn't exist, and user doesn't intent to see a diff, then let us - " add -s option. In any case he can press enter on the <SHOW DIFFS> to see - " it later. - if index(s:p4CmdOptions, '-s') == -1 && - \ s:indexMatching(s:p4CmdOptions, '^-d.\+$') == -1 - call add(s:p4CmdOptions, '-s') - let s:p4WinName = s:MakeWindowName() " Adjust window name. - endif - - let retVal = perforce#PFIF(2, a:outputType, 'describe') - if s:StartBufSetup() && getline(1) !~# ' - no such changelist' - call s:SetupFileBrowse() - if index(s:p4CmdOptions, '-s') != -1 - setlocal modifiable - silent! 2,$g/^Change \d\+ by \|\%$/ - \ call append(line('.')-1, ['', "\t<SHOW DIFFS>", '']) - setlocal nomodifiable - else - call s:SetupDiff() - endif - - call s:EndBufSetup() - endif - return retVal -endfunction - -function! s:diffHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'diff']+a:000) - endif - - " If a change number is specified in the diff, we need to handle it - " ourselves, as p4 doesn't understand this. - let changeOptIdx = index(s:p4CmdOptions, '++c') - let changeNo = '' - if changeOptIdx != -1 " If a change no. is specified. - let changeNo = s:p4CmdOptions[changeOptIdx+1] - call s:PushP4Context() - try - call extend(s:p4Options, ['++T', '++N'], 0) " Testmode. - let retVal = perforce#PFIF(2, a:outputType, 'diff') " Opens window. - if s:errCode == 0 - setlocal modifiable - exec '%PF ++f opened -c' changeNo - endif - finally - let cntxtStr = s:PopP4Context() - endtry - else - " Any + option is treated like a signal to run external diff. - let externalDiffOptExists = (s:indexMatching(s:p4CmdOptions, '^+\S\+$') != -1) - if externalDiffOptExists - if len(s:p4Arguments) > 1 - return s:SyntaxError('External diff options can not be used with multiple files.') - endif - let needsPop = 0 - try - let _p4Options = copy(s:p4Options) - call insert(s:p4Options, '++T', 0) " Testmode, just open the window. - let retVal = perforce#PFIF(2, 0, 'diff') - let s:p4Options = _p4Options - if s:errCode != 0 - return - endif - call s:PushP4Context() | let needsPop = 1 - PW print -q - if s:errCode == 0 - setlocal modifiable - let fileName = s:ConvertToLocalPath(s:p4Arguments[0]) - call s:PeekP4Context() - " Gather and process only external options. - " Sample: - " '-x +width=10 -du -y +U=20 -z -a -db +tabsize=4' - " to - " '--width=10 -U 20 --tabsize=4' - let diffOpts = [] - for opt in s:p4CmdOptions - if opt =~ '^+' - call add(diffOpts, substitute(opt, '^+\([^= ]\+\)=\(.*\)$', - \ '\=(strlen(submatch(1)) > 1 ? '. - \ '("--".submatch(1).'. - \ '(submatch(2) != "" ? "=".submatch(2) : "")) : '. - \ '("-".submatch(1).'. - \ '(submatch(2) != "" ? " ".submatch(2) : "")))', - \ 'g')) - endif - endfor - if getbufvar(bufnr('#'), '&ff') ==# 'dos' - setlocal ff=dos - endif - silent! exec '%!'. - \ genutils#EscapeCommand('diff', diffOpts+['--', '-', fileName], - \ '') - if v:shell_error > 1 - call s:EchoMessage('Error executing external diff command. '. - \ 'Verify that GNU (or a compatible) diff is in your path.', - \ 'ERROR') - return '' - endif - call genutils#SilentSubstitute("\<CR>$", '%s///') - call genutils#SilentSubstitute('^--- -', '1s;;--- '. - \ s:ConvertToDepotPath(fileName)) - 1 - endif - finally - setlocal nomodifiable - if needsPop - call s:PopP4Context() - endif - endtry - else - let retVal = perforce#PFIF(2, exists('$P4DIFF') ? 5 : a:outputType, 'diff') - endif - endif - - if s:StartBufSetup() - call s:SetupDiff() - - if changeNo != '' && getline(1) !~# 'ile(s) not opened on this client\.' - setl modifiable - call genutils#SilentSubstitute('#.*', '%s///e') - call s:SetP4ContextVars(cntxtStr) " Restore original diff context. - call perforce#PFIF(1, 0, '-x', '-', '++f', '++n', 'diff') - setl nomodifiable - endif - - call s:EndBufSetup() - endif - return retVal -endfunction - -function! s:diff2Hdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'diff2']+a:000) - endif - - let s:p4Arguments = s:GetDiff2Args() - - let retVal = perforce#PFIF(2, exists('$P4DIFF') ? 5 : a:outputType, 'diff2') - if s:StartBufSetup() - call s:SetupDiff() - - call s:EndBufSetup() - endif - return retVal -endfunction - -function! s:passwdHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'passwd']+a:000) - endif - - let oldPasswd = "" - if index(s:p4CmdOptions, '-O') == -1 - let oldPasswd = input('Enter old password: ') - " FIXME: Handle empty passwords. - call add(add(s:p4CmdOptions, '-O'), oldPasswd) - endif - let newPasswd = "" - if index(s:p4CmdOptions, '-P') == -1 - while 1 - let newPasswd = input('Enter new password: ') - if (input('Re-enter new password: ') != newPasswd) - call s:EchoMessage("Passwords don't match", 'Error') - else - " FIXME: Handle empty passwords. - call add(add(s:p4CmdOptions, '-P'), newPasswd) - break - endif - endwhile - endif - let retVal = perforce#PFIF(2, a:outputType, 'passwd') - return retVal -endfunction - -" Only to avoid confirming for -n and -a options. -function! s:revertHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, - \ a:outputType, 'passwd']+a:000) - endif - - if index(s:p4CmdOptions, '-n') != -1 || index(s:p4CmdOptions, '-a') != -1 - call add(s:p4Options, '++y') - endif - let retVal = perforce#PFIF(2, a:outputType, 'revert') - return retVal -endfunction - -function! s:changeHdlrImpl(outputType) - let _p4Arguments = s:p4Arguments - " If argument(s) is not a number... - if len(s:p4Arguments) != 0 && s:indexMatching(s:p4Arguments, '^\d\+$') == -1 - let s:p4Arguments = [] " Let a new changelist be created. - endif - let retVal = perforce#PFIF(2, a:outputType, 'change') - let s:p4Arguments = _p4Arguments - if s:errCode == 0 && s:indexMatching(s:p4Arguments, '^\d\+$') == -1 - \ && (s:StartBufSetup() || s:commandMode ==# s:CM_FILTER) - if len(s:p4Arguments) != 0 - if search('^Files:\s*$', 'w') && line('.') != line('$') - + - call s:PushP4Context() - try - call call('perforce#PFrangeIF', [line("."), line("$"), 1, 0]+ - \ s:p4Options+['++f', 'opened', '-c', 'default']+ - \ s:p4Arguments) - finally - call s:PopP4Context() - endtry - - if s:errCode == 0 - call genutils#SilentSubstitute('^', '.,$s//\t/e') - call genutils#SilentSubstitute('#\d\+ - \(\S\+\) .*$', - \ '.,$s//\t# \1/e') - endif - endif - endif - - call s:EndBufSetup() - setl nomodified - if len(s:p4Arguments) != 0 && &cmdheight > 1 - " The message about W and WQ must have gone by now. - redraw | call perforce#LastMessage() - endif - else - " Save the filelist in this changelist so that we can update their status - " later. - if search('Files:\s*$', 'w') - let b:p4OrgFilelist = getline(line('.')+1, line('$')) - endif - endif - return retVal -endfunction - -function! s:changeHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'change']+a:000) - endif - let retVal = s:changeHdlrImpl(a:outputType) - if s:StartBufSetup() - command! -buffer -nargs=* PChangeSubmit :call call('<SID>W', - \ [0]+b:p4Options+['submit']+split(<q-args>, '\s')) - - call s:EndBufSetup() - endif - return retVal -endfunction - -" Create a template for submit. -function! s:submitHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'submit']+a:000) - endif - - if index(s:p4CmdOptions, '-c') != -1 - " Non-interactive. - let retVal = perforce#PFIF(2, a:outputType, 'submit') - else - call s:PushP4Context() - try - " This is done just to get the :W and :WQ commands defined properly and - " open the window with a proper name. The actual job is done by the call - " to s:changeHdlrImpl() which is then run in filter mode to avoid the - " side-effects (such as :W and :WQ getting overwritten etc.) - call extend(s:p4Options, ['++y', '++T'], 0) " Don't confirm, and testmode. - call perforce#PFIF(2, 0, 'submit') - if s:errCode == 0 - call s:PeekP4Context() - let s:p4CmdOptions = [] " These must be specific to 'submit'. - let s:p4Command = 'change' - let s:commandMode = s:CM_FILTER | let s:filterRange = '.' - let retVal = s:changeHdlrImpl(a:outputType) - setlocal nomodified - if s:errCode != 0 - return - endif - endif - finally - call s:PopP4Context() - endtry - - if s:StartBufSetup() - command! -buffer -nargs=* PSubmitPostpone :call call('<SID>W', - \ [0]+b:p4Options+['change']+split(<q-args>, '\s')) - set ft=perforce " Just to get the cursor placement right. - call s:EndBufSetup() - endif - - if s:errCode - call s:EchoMessage("Error creating submission template.", 'Error') - endif - endif - return s:errCode -endfunction - -function! s:resolveHdlr(scriptOrigin, outputType, ...) - if !a:scriptOrigin - call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'resolve']+a:000) - endif - - if (s:indexMatching(s:p4CmdOptions, '^-a[fmsty]$') == -1) && - \ (index(s:p4CmdOptions, '-n') == -1) - return s:SyntaxError("Interactive resolve not implemented (yet).") - endif - let retVal = perforce#PFIF(2, a:outputType, 'resolve') - return retVal -endfunction - -function! s:filelogHdlr(scriptOrigin, outputType, ...) - let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'filelog']+a:000) - - if s:StartBufSetup() - " No meaning for delete. - silent! nunmap <buffer> D - silent! delcommand PItemDelete - command! -range -buffer -nargs=0 PFilelogDiff - \ :call s:FilelogDiff2(<line1>, <line2>) - vnoremap <silent> <buffer> D :PFilelogDiff<CR> - command! -buffer -nargs=0 PFilelogPrint :call perforce#PFIF(0, 0, 'print', - \ <SID>GetCurrentItem()) - nnoremap <silent> <buffer> p :PFilelogPrint<CR> - command! -buffer -nargs=0 PFilelogSync :call <SID>FilelogSyncToCurrentItem() - nnoremap <silent> <buffer> S :PFilelogSync<CR> - command! -buffer -nargs=0 PFilelogDescribe - \ :call <SID>FilelogDescribeChange() - nnoremap <silent> <buffer> C :PFilelogDescribe<CR> - - call s:EndBufSetup() - endif -endfunction - -function! s:clientsHdlr(scriptOrigin, outputType, ...) - let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'clients']+a:000) - - if s:StartBufSetup() - command! -buffer -nargs=0 PClientsTemplate - \ :call perforce#PFIF(0, 0, '++A', 'client', '-t', <SID>GetCurrentItem()) - nnoremap <silent> <buffer> P :PClientsTemplate<CR> - - call s:EndBufSetup() - endif - return retVal -endfunction - -function! s:changesHdlr(scriptOrigin, outputType, ...) - let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'changes']+a:000) - - if s:StartBufSetup() - command! -buffer -nargs=0 PItemDescribe - \ :call <SID>PChangesDescribeCurrentItem() - command! -buffer -nargs=0 PChangesSubmit - \ :call <SID>ChangesSubmitChangeList() - nnoremap <silent> <buffer> S :PChangesSubmit<CR> - command! -buffer -nargs=0 PChangesOpened - \ :if getline('.') =~# " \\*pending\\* '" | - \ call perforce#PFIF(1, 0, 'opened', '-c', <SID>GetCurrentItem()) | - \ endif - nnoremap <silent> <buffer> o :PChangesOpened<CR> - command! -buffer -nargs=0 PChangesDiff - \ :if getline('.') =~# " \\*pending\\* '" | - \ call perforce#PFIF(0, 0, 'diff', '++c', <SID>GetCurrentItem()) | - \ else | - \ call perforce#PFIF(0, 0, 'describe', (<SID>('DefaultDiffOptions') - \ =~ '^\s*$' ? '-dd' : <SID>('DefaultDiffOptions')), - \ <SID>GetCurrentItem()) | - \ endif - nnoremap <silent> <buffer> d :PChangesDiff<CR> - command! -buffer -nargs=0 PItemOpen - \ :if getline('.') =~# " \\*pending\\* '" | - \ call perforce#PFIF(0, 0, 'change', <SID>GetCurrentItem()) | - \ else | - \ call perforce#PFIF(0, 0, 'describe', '-dd', <SID>GetCurrentItem()) | - \ endif - - call s:EndBufSetup() - endif -endfunction - -function! s:labelsHdlr(scriptOrigin, outputType, ...) - let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'labels']+a:000) - - if s:StartBufSetup() - command! -buffer -nargs=0 PLabelsSyncClient - \ :call <SID>LabelsSyncClientToLabel() - nnoremap <silent> <buffer> S :PLabelsSyncClient<CR> - command! -buffer -nargs=0 PLabelsSyncLabel - \ :call <SID>LabelsSyncLabelToClient() - nnoremap <silent> <buffer> C :PLabelsSyncLabel<CR> - command! -buffer -nargs=0 PLabelsFiles :call perforce#PFIF(0, 0, '++n', 'files', - \ '//...@'. <SID>GetCurrentItem()) - nnoremap <silent> <buffer> I :PLabelsFiles<CR> - command! -buffer -nargs=0 PLabelsTemplate :call perforce#PFIF(0, 0, '++A', - \ 'label', '-t', <SID>GetCurrentItem()) - nnoremap <silent> <buffer> P :PLabelsTemplate<CR> - - call s:EndBufSetup() - endif - return retVal -endfunction - -function! s:helpHdlr(scriptOrigin, outputType, ...) - call genutils#SaveWindowSettings2("PerforceHelp", 1) - " If there is a help window already open, then we need to reuse it. - let helpWin = bufwinnr(s:helpWinName) - let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'help']+a:000) - - if s:StartBufSetup() - command! -buffer -nargs=0 PHelpSelect - \ :call perforce#PFIF(0, 0, 'help', expand("<cword>")) - nnoremap <silent> <buffer> <CR> :PHelpSelect<CR> - nnoremap <silent> <buffer> K :PHelpSelect<CR> - nnoremap <silent> <buffer> <2-LeftMouse> :PHelpSelect<CR> - call genutils#AddNotifyWindowClose(s:helpWinName, s:myScriptId . - \ "RestoreWindows") - if helpWin == -1 " Resize only when it was not already visible. - exec "resize " . 20 - endif - redraw | echo - \ "Press <CR>/K/<2-LeftMouse> to drilldown on perforce help keywords." - - call s:EndBufSetup() - endif - return retVal -endfunction - -" Built-in command handlers {{{ -function! s:VDiffHandler() - let nArgs = len(s:p4Arguments) - if nArgs > 2 - return s:SyntaxError("vdiff: Too many arguments.") - endif - - let firstFile = '' - let secondFile = '' - if nArgs == 2 - let firstFile = s:p4Arguments[0] - let secondFile = s:p4Arguments[1] - elseif nArgs == 1 - let secondFile = s:p4Arguments[0] - else - let secondFile = s:EscapeFileName(s:GetCurFileName()) - endif - if firstFile == '' - let firstFile = s:ConvertToDepotPath(secondFile) - endif - call s:VDiffImpl(firstFile, secondFile, 0) -endfunction - -function! s:VDiff2Handler() - if len(s:p4Arguments) > 2 - return s:SyntaxError("vdiff2: Too many arguments") - endif - - let s:p4Arguments = s:GetDiff2Args() - call s:VDiffImpl(s:p4Arguments[0], s:p4Arguments[1], 1) -endfunction - -function! s:VDiffImpl(firstFile, secondFile, preferDepotPaths) - let firstFile = a:firstFile - let secondFile = a:secondFile - - if a:preferDepotPaths || s:PathRefersToDepot(firstFile) - let firstFile = s:ConvertToDepotPath(firstFile) - let tempFile1 = s:MakeTempName(firstFile) - else - let tempFile1 = firstFile - endif - if a:preferDepotPaths || s:PathRefersToDepot(secondFile) - let secondFile = s:ConvertToDepotPath(secondFile) - let tempFile2 = s:MakeTempName(secondFile) - else - let tempFile2 = secondFile - endif - if firstFile =~# s:EMPTY_STR || secondFile =~# s:EMPTY_STR || - \ (tempFile1 ==# tempFile2) - return s:SyntaxError("diff requires two distinct files as arguments.") - endif - - let s:vdiffCounter = s:vdiffCounter + 1 - - if s:IsDepotPath(firstFile) - let s:p4Command = 'print' - let s:p4CmdOptions = ['-q'] - let s:p4WinName = tempFile1 - let s:p4Arguments = [firstFile] - call perforce#PFIF(2, 0, 'print') - if s:errCode != 0 - return - endif - else - let v:errmsg = '' - silent! exec 'split' firstFile - if v:errmsg != "" - return s:ShowVimError("Error opening file: ".firstFile."\n".v:errmsg, '') - endif - endif - diffthis - let w:p4VDiffWindow = s:vdiffCounter - wincmd K - - " CAUTION: If there is a buffer or window local value, then this will get - " overridden, but it is OK. - if exists('t:p4SplitCommand') - let _splitCommand = t:p4SplitCommand - endif - let t:p4SplitCommand = 'vsplit' - let _splitright = &splitright - set splitright - try - if s:IsDepotPath(secondFile) - let s:p4Command = 'print' - let s:p4CmdOptions = ['-q'] - let s:p4WinName = tempFile2 - let s:p4Arguments = [secondFile] - call perforce#PFIF(2, 0, 'print') - if s:errCode != 0 - return - endif - else - let v:errmsg = '' - silent! exec 'vsplit' secondFile - if v:errmsg != "" - return s:ShowVimError("Error opening file: ".secondFile."\n".v:errmsg, '') - endif - endif - finally - if exists('_splitCommand') - let t:p4SplitCommand = _splitCommand - else - unlet t:p4SplitCommand - endif - let &splitright = _splitright - endtry - diffthis - let w:p4VDiffWindow = s:vdiffCounter - wincmd _ -endfunction - -" Returns a fileName in the temp directory that is unique for the branch and -" revision specified in the fileName. -function! s:MakeTempName(filePath) - let depotPath = s:ConvertToDepotPath(a:filePath) - if depotPath =~# s:EMPTY_STR - return '' - endif - let tmpName = s:_('TempDir') . '/' - let branch = s:GetBranchName(depotPath) - if branch !~# s:EMPTY_STR - let tmpName = tmpName . branch . '-' - endif - let revSpec = s:GetRevisionSpecifier(depotPath) - if revSpec !~# s:EMPTY_STR - let tmpName = tmpName . substitute(strpart(revSpec, 1), '/', '_', 'g') . '-' - endif - return tmpName . fnamemodify(substitute(a:filePath, '\\*#\d\+$', '', ''), - \ ':t') -endfunction - -function! s:ExecHandler() - if len(s:p4Arguments) != 0 - echo join(s:p4Arguments, ' ') - let cmdHasBang = 0 - if s:p4Arguments[0] =~# '^!' - let cmdHasBang = 1 - " FIXME: Pipe itself needs to be escaped, and they could be chained. - let cmd = genutils#EscapeCommand(substitute(s:p4Arguments[0], '^!', '', - \ ''), s:p4Arguments[1:], s:p4Pipe) - else - let cmd = join(s:p4Arguments, ' ') - endif - let cmd = genutils#Escape(cmd, '#%!') - try - exec (cmdHasBang ? '!' : '').cmd - catch - let v:errmsg = substitute(v:exception, '^[^:]\+:', '', '') - call s:ShowVimError(v:errmsg, v:throwpoint) - endtry - endif -endfunction - -" Built-in command handlers }}} - -""" END: Command specific functions }}} - - -""" BEGIN: Helper functions {{{ - -" Open a file from an alternative codeline. -" If mode == 0, first file is opened and all other files are added to buffer -" list. -" If mode == 1, the files are not really opened, the list is just returned. -" If mode == 2, it behaves the same as mode == 0, except that the file is -" split opened. -" If there are no arguments passed, user is prompted to enter. He can then -" enter a codeline followed by a list of filenames. -" If only one argument is passed, it is assumed to be the codeline and the -" current filename is assumed (user is not prompted). -function! perforce#PFOpenAltFile(mode, ...) " {{{ - let argList = copy(a:000) - if a:0 < 2 - if a:0 == 0 - " Prompt for codeline string (codeline optionally followed by filenames). - let codelineStr = s:PromptFor(0, s:_('UseGUIDialogs'), - \ "Enter the alternative codeline string: ", '') - if codelineStr =~# s:EMPTY_STR - return "" - endif - let argList = split(codelineStr, s:SPACE_AS_SEP) - endif - if len(argList) == 1 - call add(argList, s:EscapeFileName(s:GetCurFileName())) - endif - endif - - let altFileNames = call('s:PFGetAltFiles', ['']+argList) - if a:mode == 0 || a:mode == 2 - let firstFile = 1 - for altFileName in altFileNames - if firstFile - execute ((a:mode == 0) ? ":edit " : ":split ") . altFileName - let firstFile = 0 - else - execute ":badd " . altFileName - endif - endfor - else - return join(altFileNames, ' ') - endif -endfunction " }}} - -" Interactively change the port/client/user. {{{ -function! perforce#SwitchPortClientUser() - let p4Port = s:PromptFor(0, s:_('UseGUIDialogs'), "Port: ", s:_('p4Port')) - let p4Client = s:PromptFor(0, s:_('UseGUIDialogs'), "Client: ", s:_('p4Client')) - let p4User = s:PromptFor(0, s:_('UseGUIDialogs'), "User: ", s:_('p4User')) - call perforce#PFSwitch(1, p4Port, p4Client, p4User) -endfunction - -" No args: Print presets and prompt user to select a preset. -" Number: Select that numbered preset. -" port [client] [user]: Set the specified settings. -function! perforce#PFSwitch(updateClientRoot, ...) - if a:0 == 0 || match(a:1, '^\d\+$') == 0 - let selPreset = '' - let presets = split(s:_('Presets'), ',') - if a:0 == 0 - if len(presets) == 0 - call s:EchoMessage("No presets to select from.", 'Error') - return - endif - - let selPreset = genutils#PromptForElement(presets, -1, - \ "Select the setting: ", -1, s:_('UseGUIDialogs'), 1) - else - let index = a:1 + 0 - if index >= len(presets) - call s:EchoMessage("Not that many presets.", 'Error') - return - endif - let selPreset = presets[index] - endif - if selPreset == '' - return - endif - let argList = split(selPreset, s:SPACE_AS_SEP) - else - if a:0 == 1 - let argList = split(a:1, ' ') - else - let argList = a:000 - endif - endif - call call('s:PSwitchHelper', [a:updateClientRoot]+argList) - - " Loop through all the buffers and invalidate the filestatuses. - let lastBufNr = bufnr('$') - let i = 1 - while i <= lastBufNr - if bufexists(i) && getbufvar(i, '&buftype') == '' - call s:ResetFileStatusForBuffer(i) - endif - let i = i + 1 - endwhile -endfunction - -function! s:PSwitchHelper(updateClientRoot, ...) - let p4Port = a:1 - let p4Client = s:_('p4Client') - let p4User = s:_('p4User') - if a:0 > 1 - let p4Client = a:2 - endif - if a:0 > 2 - let p4User = a:3 - endif - if ! s:SetPortClientUser(p4Port, p4Client, p4User) - return - endif - - if a:updateClientRoot - if s:p4Port !=# 'P4CONFIG' - call s:GetClientInfo() - else - let g:p4ClientRoot = '' " Since the client is chosen dynamically. - endif - endif -endfunction - -function! s:SetPortClientUser(port, client, user) - if s:p4Port ==# a:port && s:p4Client ==# a:client && s:p4User ==# a:user - return 0 - endif - - let s:p4Port = a:port - let s:p4Client = a:client - let s:p4User = a:user - let s:p4Password = '' - return 1 -endfunction - -function! perforce#PFSwitchComplete(ArgLead, CmdLine, CursorPos) - return substitute(s:_('Presets'), ',', "\n", 'g') -endfunction -" port/client/user }}} - -function! s:PHelpComplete(ArgLead, CmdLine, CursorPos) - if s:p4KnownCmdsCompStr == '' - let s:p4KnownCmdsCompStr = join(s:p4KnownCmds, "\n") - endif - return s:p4KnownCmdsCompStr. - \ "simple\ncommands\nenvironment\nfiletypes\njobview\nrevisions\n". - \ "usage\nviews\n" -endfunction - -" Handler for opened command. -function! s:OpenFile(scriptOrigin, outputType, fileName) " {{{ - if filereadable(a:fileName) - if a:outputType == 0 - let curWin = winnr() - let bufNr = genutils#FindBufferForName(a:fileName) - let winnr = bufwinnr(bufNr) - if winnr != -1 - exec winnr.'wincmd w' - else - wincmd p - endif - if curWin != winnr() && &previewwindow - wincmd p " Don't use preview window. - endif - " Avoid loosing temporary buffers accidentally. - if winnr() == curWin || getbufvar('%', '&bufhidden') != '' - split - endif - if winbufnr(winnr()) != bufNr - if bufNr != -1 - exec "buffer" bufNr | " Preserves cursor position. - else - exec "edit " . a:fileName - endif - endif - else - exec "pedit " . a:fileName - endif - else - call perforce#PFIF(0, a:outputType, 'print', a:fileName) - endif -endfunction " }}} - -function! s:DescribeGetCurrentItem() " {{{ - if getline(".") ==# "\t<SHOW DIFFS>" - let [changeHdrLine, col] = searchpos('^Change \zs\d\+ by ', 'bnW') - if changeHdrLine != 0 - let changeNo = matchstr(getline(changeHdrLine), '\d\+', col-1) - let _modifiable = &l:modifiable - try - setlocal modifiable - call genutils#SaveHardPosition('DescribeGetCurrentItem') - exec changeHdrLine.',.PF ++f describe' s:_('DefaultDiffOptions') changeNo - call genutils#RestoreHardPosition('DescribeGetCurrentItem') - call genutils#ResetHardPosition('DescribeGetCurrentItem') - finally - let &l:modifiable = _modifiable - endtry - call s:SetupDiff() - endif - return "" - endif - return s:GetCurrentDepotFile(line('.')) -endfunction " }}} - -function! s:getCommandItemHandler(outputType, command, args) " {{{ - let itemHandler = "" - if exists("s:{a:command}ItemHandler") - let itemHandler = s:{a:command}ItemHandler - elseif match(a:command, 'e\?s$') != -1 - let handlerCmd = substitute(a:command, 'e\?s$', '', '') - if exists('*s:{handlerCmd}Hdlr') - let itemHandler = 's:' . handlerCmd . 'Hdlr' - else - let itemHandler = 'perforce#PFIF' - endif - endif - if itemHandler ==# 'perforce#PFIF' - return "call perforce#PFIF(1, " . a:outputType . ", '" . handlerCmd . "', " . - \ a:args . ")" - elseif itemHandler !~# s:EMPTY_STR - return 'call ' . itemHandler . '(0, ' . a:outputType . ', ' . a:args . ')' - endif - return itemHandler -endfunction " }}} - -function! s:OpenCurrentItem(outputType) " {{{ - let curItem = s:GetOpenItem(a:outputType) - if curItem !~# s:EMPTY_STR - let commandHandler = s:getCommandItemHandler(a:outputType, b:p4Command, - \ "'" . curItem . "'") - if commandHandler !~# s:EMPTY_STR - exec commandHandler - endif - endif -endfunction " }}} - -function! s:GetCurrentItem() " {{{ - if exists("b:p4Command") && exists("s:{b:p4Command}Expr") - exec "return " s:{b:p4Command}Expr - endif - return "" -endfunction " }}} - -function! s:GetOpenItem(outputType) " {{{ - " For non-preview open. - if exists("b:p4Command") && a:outputType == 0 && - \ exists("s:{b:p4Command}OpenItemExpr") - exec "return " s:{b:p4Command}OpenItemExpr - endif - return s:GetCurrentItem() -endfunction " }}} - -function! s:DeleteCurrentItem() " {{{ - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - let answer = s:ConfirmMessage("Are you sure you want to delete " . - \ curItem . "?", "&Yes\n&No", 2, "Question") - if answer == 1 - let commandHandler = s:getCommandItemHandler(2, b:p4Command, - \ "'-d', '" . curItem . "'") - if commandHandler !~# s:EMPTY_STR - exec commandHandler - endif - if v:shell_error == "" - call perforce#PFRefreshActivePane() - endif - endif - endif -endfunction " }}} - -function! s:LaunchCurrentFile() " {{{ - if g:p4FileLauncher =~# s:EMPTY_STR - call s:ConfirmMessage("There was no launcher command configured to launch ". - \ "this item, use g:p4FileLauncher to configure." , "OK", 1, "Error") - return - endif - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - exec 'silent! !'.g:p4FileLauncher curItem - endif -endfunction " }}} - -function! s:FilelogDiff2(line1, line2) " {{{ - let line1 = a:line1 - let line2 = a:line2 - if line1 == line2 - if line2 < line("$") - let line2 = line2 + 1 - elseif line1 > 1 - let line1 = line1 - 1 - else - return - endif - endif - - let file1 = s:GetCurrentDepotFile(line1) - if file1 !~# s:EMPTY_STR - let file2 = s:GetCurrentDepotFile(line2) - if file2 !~# s:EMPTY_STR && file2 != file1 - " file2 will be older than file1. - exec "call perforce#PFIF(0, 0, \"" . (s:_('UseVimDiff2') ? 'vdiff2' : 'diff2') . - \ "\", file2, file1)" - endif - endif -endfunction " }}} - -function! s:FilelogSyncToCurrentItem() " {{{ - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - let answer = s:ConfirmMessage("Do you want to sync to: " . curItem . " ?", - \ "&Yes\n&No", 2, "Question") - if answer == 1 - call perforce#PFIF(1, 2, 'sync', curItem) - endif - endif -endfunction " }}} - -function! s:ChangesSubmitChangeList() " {{{ - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - let answer = s:ConfirmMessage("Do you want to submit change list: " . - \ curItem . " ?", "&Yes\n&No", 2, "Question") - if answer == 1 - call perforce#PFIF(0, 0, '++y', 'submit', '-c', curItem) - endif - endif -endfunction " }}} - -function! s:LabelsSyncClientToLabel() " {{{ - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - let answer = s:ConfirmMessage("Do you want to sync client to the label: " . - \ curItem . " ?", "&Yes\n&No", 2, "Question") - if answer == 1 - let retVal = call('perforce#PFIF', [1, 1, 'sync', - \ '//".s:_('Depot')."/...@'.curItem]) - return retVal - endif - endif -endfunction " }}} - -function! s:LabelsSyncLabelToClient() " {{{ - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - let answer = s:ConfirmMessage("Do you want to sync label: " . curItem . - \ " to client " . s:_('p4Client') . " ?", "&Yes\n&No", 2, "Question") - if answer == 1 - let retVal = perforce#PFIF(1, 1, 'labelsync', '-l', curItem) - return retVal - endif - endif -endfunction " }}} - -function! s:FilelogDescribeChange() " {{{ - let changeNo = matchstr(getline("."), ' change \zs\d\+\ze ') - if changeNo !~# s:EMPTY_STR - exec "call perforce#PFIF(0, 1, 'describe', changeNo)" - endif -endfunction " }}} - -function! s:SetupFileBrowse() " {{{ - " For now, assume that a new window is created and we are in the new window. - exec "setlocal includeexpr=P4IncludeExpr(v:fname)" - - " No meaning for delete. - silent! nunmap <buffer> D - silent! delcommand PItemDelete - command! -buffer -nargs=0 PFileDiff :call perforce#PFIF(0, 1, 'diff', - \ <SID>GetCurrentDepotFile(line("."))) - nnoremap <silent> <buffer> D :PFileDiff<CR> - command! -buffer -nargs=0 PFileProps :call perforce#PFIF(1, 0, 'fstat', '-C', - \ <SID>GetCurrentDepotFile(line("."))) - nnoremap <silent> <buffer> P :PFileProps<CR> - command! -buffer -nargs=0 PFileLog :call perforce#PFIF(1, 0, 'filelog', - \ <SID>GetCurrentDepotFile(line("."))) - command! -buffer -nargs=0 PFileEdit :call perforce#PFIF(1, 2, 'edit', - \ <SID>GetCurrentItem()) - nnoremap <silent> <buffer> I :PFileEdit<CR> - command! -buffer -bar -nargs=0 PFileRevert :call perforce#PFIF(1, 2, 'revert', - \ <SID>GetCurrentItem()) - nnoremap <silent> <buffer> R :PFileRevert \| PFRefreshActivePane<CR> - command! -buffer -nargs=0 PFilePrint - \ :if getline('.') !~# '(\%(u\|ux\)binary)$' | - \ call perforce#PFIF(0, 0, 'print', - \ substitute(<SID>GetCurrentDepotFile(line('.')), '#[^#]\+$', '', ''). - \ '#'. - \ ((getline(".") =~# '#\d\+ - delete change') ? - \ matchstr(getline('.'), '#\zs\d\+\ze - ') - 1 : - \ matchstr(getline('.'), '#\zs\d\+\ze - ')) - \ ) | - \ else | - \ echo 'PFilePrint: Binary file... ignored.' | - \ endif - nnoremap <silent> <buffer> p :PFilePrint<CR> - command! -buffer -nargs=0 PFileGet :call perforce#PFIF(1, 2, 'sync', - \ <SID>GetCurrentDepotFile(line("."))) - command! -buffer -nargs=0 PFileSync :call perforce#PFIF(1, 2, 'sync', - \ <SID>GetCurrentItem()) - nnoremap <silent> <buffer> S :PFileSync<CR> - command! -buffer -nargs=0 PFileChange :call perforce#PFIF(0, 0, 'change', - \ <SID>GetCurrentChangeNumber(line("."))) - nnoremap <silent> <buffer> C :PFileChange<CR> - command! -buffer -nargs=0 PFileLaunch :call <SID>LaunchCurrentFile() - nnoremap <silent> <buffer> A :PFileLaunch<CR> -endfunction " }}} - -function! s:SetupDiff() " {{{ - setlocal ft=diff -endfunction " }}} - -function! s:SetupSelectItem() " {{{ - nnoremap <buffer> <silent> D :PItemDelete<CR> - nnoremap <buffer> <silent> O :PItemOpen<CR> - nnoremap <buffer> <silent> <CR> :PItemDescribe<CR> - nnoremap <buffer> <silent> <2-LeftMouse> :PItemDescribe<CR> - command! -buffer -nargs=0 PItemDescribe :call <SID>OpenCurrentItem(1) - command! -buffer -nargs=0 PItemOpen :call <SID>OpenCurrentItem(0) - command! -buffer -nargs=0 PItemDelete :call <SID>DeleteCurrentItem() - cnoremap <buffer> <C-X><C-I> <C-R>=<SID>GetCurrentItem()<CR> -endfunction " }}} - -function! s:RestoreWindows(dummy) " {{{ - call genutils#RestoreWindowSettings2("PerforceHelp") -endfunction " }}} - -function! s:NavigateBack() " {{{ - call s:Navigate('u') - if line('$') == 1 && getline(1) == '' - call s:NavigateForward() - endif -endfunction " }}} - -function! s:NavigateForward() " {{{ - call s:Navigate("\<C-R>") -endfunction " }}} - -function! s:Navigate(key) " {{{ - let _modifiable = &l:modifiable - try - setlocal modifiable - " Use built-in markers as Vim takes care of remembering and restoring them - " during the undo/redo. - normal! mt - - silent! exec "normal" a:key - - if line("'t") > 0 && line("'t") <= line('$') - normal! `t - endif - finally - let &l:modifiable = _modifiable - endtry -endfunction " }}} - -function! s:GetCurrentChangeNumber(lineNo) " {{{ - let line = getline(a:lineNo) - let changeNo = matchstr(line, ' - \S\+ change \zs\S\+\ze (') - if changeNo ==# 'default' - let changeNo = '' - endif - return changeNo -endfunction " }}} - -function! s:PChangesDescribeCurrentItem() " {{{ - let currentChangeNo = s:GetCurrentItem() - if currentChangeNo !~# s:EMPTY_STR - call perforce#PFIF(0, 1, 'describe', '-s', currentChangeNo) - endif -endfunction " }}} - -" {{{ -function! perforce#PFSettings(...) - if s:_('SortSettings ') - if exists("s:sortedSettings") - let settings = s:sortedSettings - else - let settings = sort(s:settings) - let s:sortedSettings = settings - endif - else - let settings = s:settings - endif - if a:0 > 0 - let selectedSetting = a:1 - else - let selectedSetting = genutils#PromptForElement(settings, -1, - \ "Select the setting: ", -1, 0, 3) - endif - if selectedSetting !~# s:EMPTY_STR - let oldVal = s:_(selectedSetting) - if a:0 > 1 - let newVal = a:2 - echo 'Current value for' selectedSetting.': "'.oldVal.'" New value: "'. - \ newVal.'"' - else - let newVal = input('Current value for ' . selectedSetting . ' is: ' . - \ oldVal . "\nEnter new value: ", oldVal) - endif - if newVal != oldVal - let g:p4{selectedSetting} = newVal - call perforce#Initialize(1) - endif - endif -endfunction - -function! perforce#PFSettingsComplete(ArgLead, CmdLine, CursorPos) - if s:settingsCompStr == '' - let s:settingsCompStr = join(s:settings, "\n") - endif - return s:settingsCompStr -endfunction -" }}} - -function! s:MakeRevStr(ver) " {{{ - let verStr = '' - if a:ver =~# '^[#@&]' - let verStr = a:ver - elseif a:ver =~# '^[-+]\?\d\+\>\|^none\>\|^head\>\|^have\>' - let verStr = '#' . a:ver - elseif a:ver !~# s:EMPTY_STR - let verStr = '@' . a:ver - endif - return verStr -endfunction " }}} - -function! s:GetBranchName(fileName) " {{{ - if s:IsFileUnderDepot(a:fileName) - " TODO: Need to run where command at this phase. - elseif stridx(a:fileName, '//') == 0 - return matchstr(a:fileName, '^//[^/]\+/\zs[^/]\+\ze') - else - return '' - endif -endfunction " }}} - -function! s:GetDiff2Args() - let p4Arguments = s:p4Arguments - if len(p4Arguments) < 2 - if len(p4Arguments) == 0 - let file = s:EscapeFileName(s:GetCurFileName()) - else - let file = p4Arguments[0] - endif - let ver1 = s:PromptFor(0, s:_('UseGUIDialogs'), "Version1? ", '') - let ver2 = s:PromptFor(0, s:_('UseGUIDialogs'), "Version2? ", '') - let p4Arguments = [file.s:MakeRevStr(ver1), file.s:MakeRevStr(ver2)] - endif - return p4Arguments -endfunction - -function! perforce#ToggleCheckOutPrompt(interactive) - aug P4CheckOut - au! - if g:p4PromptToCheckout - let g:p4PromptToCheckout = 0 - else - let g:p4PromptToCheckout = 1 - au FileChangedRO * nested :call <SID>CheckOutFile() - endif - aug END - if a:interactive - echomsg "PromptToCheckout is now " . ((g:p4PromptToCheckout) ? "enabled." : - \ "disabled.") - endif -endfunction - -function! perforce#PFDiffOff(diffCounter) - " Cycle through all windows and turn off diff options for the specified diff - " run, or all, if none specified. - let curWinNr = winnr() - let eventignore = &eventignore - set eventignore=all - try - let i = 1 - while winbufnr(i) != -1 - try - exec i 'wincmd w' - if ! exists('w:p4VDiffWindow') - continue - endif - - if a:diffCounter == -1 || w:p4VDiffWindow == a:diffCounter - call genutils#CleanDiffOptions() - unlet w:p4VDiffWindow - endif - finally - let i = i + 1 - endtry - endwhile - finally - " Return to the original window. - exec curWinNr 'wincmd w' - let &eventignore = eventignore - endtry -endfunction -""" END: Helper functions }}} - - -""" BEGIN: Middleware functions {{{ - -" Filter contents through p4. -function! perforce#PW(fline, lline, scriptOrigin, ...) range - if a:scriptOrigin != 2 - call call('s:ParseOptions', [a:fline, a:lline, 0, '++f'] + a:000) - else - let s:commandMode = s:CM_FILTER - endif - setlocal modifiable - let retVal = perforce#PFIF(2, 5, s:p4Command) - return retVal -endfunction - -" Generate raw output into a new window. -function! perforce#PFRaw(...) - call call('s:ParseOptions', [1, line('$'), 0] + a:000) - - let retVal = s:PFImpl(1, 0) - return retVal -endfunction - -function! s:W(quitWhenDone, commandName, ...) - call call('s:ParseOptionsIF', [1, line('$'), 0, 5, a:commandName]+a:000) - if index(s:p4CmdOptions, '-i') == -1 - call insert(s:p4CmdOptions, '-i', 0) - endif - let retVal = perforce#PW(1, line('$'), 2) - if s:errCode == 0 - setl nomodified - if a:quitWhenDone - close - else - if s:p4Command ==# 'change' || s:p4Command ==# 'submit' - " Change number fixed, or files added/removed. - if s:FixChangeNo() || search('^Change \d\+ updated, ', 'w') - silent! undo - if search('^Files:\s*$', 'w') - let b:p4NewFilelist = getline(line('.')+1, line('$')) - if !exists('b:p4OrgFilelist') - let filelist = b:p4NewFilelist - else - " Find outersection. - let filelist = copy(b:p4NewFilelist) - call filter(filelist, 'index(b:p4OrgFilelist, v:val)==-1') - call extend(filelist, filter(copy(b:p4OrgFilelist), 'index(b:p4NewFilelist, v:val)==-1')) - endif - let files = map(filelist, 's:ConvertToLocalPath(v:val)') - call s:ResetFileStatusForFiles(files) - endif - silent! redo - endif - endif - endif - else - call s:FixChangeNo() - endif -endfunction - -function! s:FixChangeNo() - if search('^Change \d\+ created', 'w') || - \ search('^Change \d\+ renamed change \d\+ and submitted', 'w') - let newChangeNo = matchstr(getline('.'), '\d\+\ze\%(created\|and\)') - let _undolevels=&undolevels - try - let allLines = getline(1, line('$')) - silent! undo - " Make the below changes such a way that they can't be undo. This in a - " way, forces Vim to create an undo point, so that user can later - " undo and see these changes, with proper change number and status - " in place. This has the side effect of loosing the previous undo - " history, which can be considered desirable, as otherwise the user - " can undo this change and back to the new state. - set undolevels=-1 - if search("^Change:\t\%(new\|\d\+\)$") - silent! keepjumps call setline('.', "Change:\t" . newChangeNo) - " If no Date is present (happens for new changelists) - if !search("^Date:\t", 'w') - call append('.', ['', "Date:\t".strftime('%Y/%m/%d %H:%M:%S')]) - endif - endif - if search("^Status:\tnew$") - silent! keepjumps call setline('.', "Status:\tpending") - endif - setl nomodified - let &undolevels=_undolevels - silent! 0,$delete _ - call setline(1, allLines) - setl nomodified - call s:PFSetupForSpec() - finally - let &undolevels=_undolevels - endtry - let b:p4Command = 'change' - let b:p4CmdOptions = ['-i'] - return 1 - else - return 0 - endif -endfunction - -function! s:ParseOptionsIF(fline, lline, scriptOrigin, outputType, commandName, - \ ...) " range - " There are multiple possibilities here: - " - scriptOrigin, in which case the commandName contains the name of the - " command, but the varArgs also may contain it. - " - commandOrigin, in which case the commandName may actually be the - " name of the command, or it may be the first argument to p4 itself, in - " any case we will let p4 handle the error cases. - if index(s:allCommands, a:commandName) != -1 && a:scriptOrigin - call call('s:ParseOptions', [a:fline, a:lline, a:outputType] + a:000) - " Add a:commandName only if it doesn't already exist in the var args. - " Handles cases like "PF help submit" and "PF -c <client> change changeno#", - " where the commandName need not be at the starting and there could be - " more than one valid commandNames (help and submit). - if s:p4Command != a:commandName - call call('s:ParseOptions', - \ [a:fline, a:lline, a:outputType, a:commandName] + a:000) - endif - else - call call('s:ParseOptions', - \ [a:fline, a:lline, a:outputType, a:commandName] + a:000) - endif -endfunction - -" PFIF {{{ -" The commandName may not be the perforce command when it is not of script -" origin (called directly from a command), but it should be always command -" name, when it is script origin. -" scriptOrigin: An integer indicating the origin of the call. -" 0 - Originated directly from the user, so should redirect to the specific -" command handler (if exists), after some basic processing. -" 1 - Originated from the script, continue with the full processing (makes -" difference in some command parsing). -" 2 - Same as 1 but, avoid processing arguments (they are already processing -" by the caller). -function! perforce#PFIF(scriptOrigin, outputType, commandName, ...) - return call('perforce#PFrangeIF', [1, line('$'), a:scriptOrigin, a:outputType, - \ a:commandName]+a:000) -endfunction - -function! perforce#PFrangeIF(fline, lline, scriptOrigin, outputType, - \ commandName, ...) - if a:scriptOrigin != 2 - call call('s:ParseOptionsIF', [a:fline, a:lline, - \ a:scriptOrigin, a:outputType, a:commandName]+a:000) - endif - if ! a:scriptOrigin - " Save a copy of the arguments so that the refresh can invoke this exactly - " as it was before. - let s:userArgs = [a:fline, a:lline, a:scriptOrigin, a:outputType, a:commandName] - \ +a:000 - endif - - - let outputOptIdx = index(s:p4Options, '++o') - if outputOptIdx != -1 - " Get the argument followed by ++o. - let s:outputType = get(s:p4Options, outputIdx + 1) + 0 - endif - " If this command prefers a dialog output, then just take care of - " it right here. - if index(s:dlgOutputCmds, s:p4Command) != -1 - let s:outputType = 2 - endif - if ! a:scriptOrigin - if exists('*s:{s:p4Command}Hdlr') - return s:{s:p4Command}Hdlr(1, s:outputType, a:commandName) - endif - endif - - let modifyWindowName = 0 - let dontProcess = (index(s:p4Options, '++n') != -1) - let noDefaultArg = (index(s:p4Options, '++N') != -1) - " If there is a confirm message for this command, then first prompt user. - let dontConfirm = (index(s:p4Options, '++y') != -1) - if exists('s:confirmMsgs{s:p4Command}') && ! dontConfirm - let option = s:ConfirmMessage(s:confirmMsgs{s:p4Command}, "&Yes\n&No", 2, - \ "Question") - if option == 2 - let s:errCode = 2 - return '' - endif - endif - - if index(s:limitListCmds, s:p4Command) != -1 && - \ index(s:p4CmdOptions, '-m') == -1 && s:_('DefaultListSize') > -1 - call extend(s:p4CmdOptions, ['-m', s:_('DefaultListSize')], 0) - let modifyWindowName = 1 - endif - if index(s:diffCmds, s:p4Command) != -1 && - \ s:indexMatching(s:p4CmdOptions, '^-d.*$') == -1 - \ && s:_('DefaultDiffOptions') !~# s:EMPTY_STR - " FIXME: Avoid split(). - call extend(s:p4CmdOptions, split(s:_('DefaultDiffOptions'), '\s'), 0) - let modifyWindowName = 1 - endif - - " Process p4Arguments, unless explicitly not requested to do so, or the '-x' - " option to read arguments from a file is given. - let unprotectedSpecPat = genutils#CrUnProtectedCharsPattern('&#@') - if ! dontProcess && ! noDefaultArg && len(s:p4Arguments) == 0 && - \ index(s:p4Options, '-x') == -1 - if (index(s:askUserCmds, s:p4Command) != -1 && - \ index(s:p4CmdOptions, '-i') == -1) || - \ index(s:p4Options, '++A') != -1 - if index(s:genericPromptCmds, s:p4Command) != -1 - let prompt = 'Enter arguments for ' . s:p4Command . ': ' - else - let prompt = "Enter the " . s:p4Command . " name: " - endif - let additionalArg = s:PromptFor(0, s:_('UseGUIDialogs'), prompt, '') - if additionalArg =~# s:EMPTY_STR - if index(s:genericPromptCmds, s:p4Command) != -1 - call s:EchoMessage('Arguments required for '. s:p4Command, 'Error') - else - call s:EchoMessage(substitute(s:p4Command, "^.", '\U&', '') . - \ " name required.", 'Error') - endif - let s:errCode = 2 - return '' - endif - let s:p4Arguments = [additionalArg] - elseif ! dontProcess && - \ index(s:curFileNotDefCmds, s:p4Command) == -1 && - \ index(s:nofileArgsCmds, s:p4Command) == -1 - let s:p4Arguments = [s:EscapeFileName(s:GetCurFileName())] - let modifyWindowName = 1 - endif - elseif ! dontProcess && s:indexMatching(s:p4Arguments, unprotectedSpecPat) != -1 - let branchModifierSpecified = 0 - let unprotectedAmp = genutils#CrUnProtectedCharsPattern('&') - if s:indexMatching(s:p4Arguments, unprotectedAmp) != -1 - let branchModifierSpecified = 1 - " CAUTION: We make sure the view mappings are generated before - " s:PFGetAltFiles() gets invoked, otherwise the call results in a - " recursive |sub-replace-special| and corrupts the mappings. - call s:CondUpdateViewMappings() - endif - - " This is like running substitute(v:val, 'pat', '\=expr', 'g') on each - " element. - " Pattern is (the start of line or series of non-space chars) followed by - " an unprotected [#@&] with a revision/codeline specifier. - " Expression is a concatenation of each of: - " (<no filename specified>?<current file>:<specified file>) - " <revision specifier> - " (<offset specified>?<adjusted revision>:<specified revision>) - call map(s:p4Arguments, "substitute(v:val, '". - \ '\(^\|\%(\S\)\+\)\('.unprotectedSpecPat.'\)\%(\2\)\@!\([-+]\?\d\+\|\S\+\)'."', ". - \ "'\\=s:ExpandRevision(submatch(1), submatch(2), submatch(3))', 'g')") - if s:errCode != 0 - return '' - endif - - if branchModifierSpecified - call map(s:p4Arguments, - \ '(v:val =~ unprotectedAmp ? s:ApplyBranchSpecs(v:val, unprotectedAmp) : v:val)') - endif - " Unescape them, as user is required to escape them to avoid the above - " processing. - call map(s:p4Arguments, "genutils#UnEscape(v:val, '&@')") - - let modifyWindowName = 1 - endif - - let testMode = 0 - if index(s:p4Options, '++T') != -1 - let testMode = 1 " Dry run, opens the window. - elseif index(s:p4Options, '++D') != -1 - let testMode = 2 " Debug. Opens the window and displays the command. - endif - - let oldOptLen = len(s:p4Options) - " Remove all the built-in options. - call filter(s:p4Options, "v:val !~ '".'++\S\+\%(\s\+[^-+]\+\|\s\+\)\?'."'") - if len(s:p4Options) != oldOptLen - let modifyWindowName = 1 - endif - if index(s:diffCmds, s:p4Command) != -1 - " Remove the dummy option, if exists (see |perforce-default-diff-format|). - call filter(s:p4CmdOptions, 'v:val != "-d"') - let modifyWindowName = 1 - endif - - if s:p4Command ==# 'help' - " Use simple window name for all the help commands. - let s:p4WinName = s:helpWinName - elseif modifyWindowName - let s:p4WinName = s:MakeWindowName() - endif - - " If the command is a built-in command, then don't pass it to external p4. - if exists('s:builtinCmdHandler{s:p4Command}') - let s:errCode = 0 - return {s:builtinCmdHandler{s:p4Command}}() - endif - - let specMode = 0 - if index(s:specCmds, s:p4Command) != -1 - if index(s:p4CmdOptions, '-d') == -1 - \ && index(s:p4CmdOptions, '-o') == -1 - \ && index(s:noOutputCmds, s:p4Command) == -1 - call add(s:p4CmdOptions, '-o') - endif - - " Go into specification mode only if the user intends to edit the output. - if ((s:p4Command ==# 'submit' && index(s:p4CmdOptions, '-c') == -1) || - \ (index(s:specOnlyCmds, s:p4Command) == -1 && - \ index(s:p4CmdOptions, '-d') == -1)) && - \ s:outputType == 0 - let specMode = 1 - endif - endif - - let navigateCmd = 0 - if index(s:navigateCmds, s:p4Command) != -1 - let navigateCmd = 1 - endif - - let retryCount = 0 - let retVal = '' - " FIXME: When is "not clearing" (value 2) useful at all? - let clearBuffer = (testMode != 2 ? ! navigateCmd : 2) - " CAUTION: This is like a do..while loop, but not exactly the same, be - " careful using continue, the counter will not get incremented. - while 1 - let retVal = s:PFImpl(clearBuffer, testMode) - - " Everything else in this loop is for password support. - if s:errCode == 0 - break - else - if retVal =~# s:EMPTY_STR - let retVal = getline(1) - endif - " FIXME: Works only with English as the language. - if retVal =~# 'Perforce password (P4PASSWD) invalid or unset.' - let p4Password = inputsecret("Password required for user " . - \ s:_('p4User') . ": ", s:p4Password) - if p4Password ==# s:p4Password - break - endif - let s:p4Password = p4Password - else - break - endif - endif - let retryCount = retryCount + 1 - if retryCount > 2 - break - endif - endwhile - - if s:errCode == 0 && index(s:autoreadCmds, s:p4Command) != -1 - call s:ResetFileStatusForFiles(s:p4Arguments) - endif - - if s:errCode != 0 - return retVal - endif - - call s:SetupWindow(specMode) - - return retVal -endfunction - -function! s:SetupWindow(specMode) - if s:StartBufSetup() - " If this command has a handler for the individual items, then enable the - " item selection commands. - if s:getCommandItemHandler(0, s:p4Command, '') !~# s:EMPTY_STR - call s:SetupSelectItem() - endif - - if index(s:ftNotPerforceCmds, s:p4Command) == -1 - setlocal ft=perforce - endif - - if index(s:filelistCmds, s:p4Command) != -1 - call s:SetupFileBrowse() - endif - - if s:NewWindowCreated() - if a:specMode - " It is not possible to have an s:p4Command which is in s:allCommands - " and still not be the actual intended command. - command! -buffer -nargs=* W :call call('<SID>W', - \ [0]+b:p4Options+[b:p4Command]+b:p4CmdOptions+split(<q-args>, - \ '\s')) - command! -buffer -nargs=* WQ :call call('<SID>W', - \ [1]+b:p4Options+[b:p4Command]+b:p4CmdOptions+split(<q-args>, - \ '\s')) - call s:EchoMessage("When done, save " . s:p4Command . - \ " spec by using :W or :WQ command. Undo on errors.", 'None') - call s:PFSetupForSpec() - else " Define q to quit the read-only perforce windows (David Fishburn) - nnoremap <buffer> q <C-W>q - endif - endif - - if index(s:navigateCmds, s:p4Command) != -1 - nnoremap <silent> <buffer> <C-O> :call <SID>NavigateBack()<CR> - nnoremap <silent> <buffer> <BS> :call <SID>NavigateBack()<CR> - nnoremap <silent> <buffer> <Tab> :call <SID>NavigateForward()<CR> - endif - - call s:EndBufSetup() - endif -endfunction - -function! s:ExpandRevision(fName, revType, revSpec) - return (a:fName==''?s:EscapeFileName(s:GetCurFileName()):a:fName). - \ a:revType. - \ (a:revSpec=~'^[-+]'?s:AdjustRevision(a:fName, a:revSpec):a:revSpec) -endfunction - -function! s:ApplyBranchSpecs(arg, unprotectedAmp) - " The first arg will be filename, followed by multiple specifiers. - let toks = split(a:arg, a:unprotectedAmp) - " FIXME: Handle "&" in the filename. - " FIXME: Handle other revision specifiers occuring in any order - " (e.g., <file>&branch#3). - " Ex: c:/dev/docs/Triage/Tools/Machine\ Configurations\ &\ Codeline\ Requirements.xls - if len(toks) == 0 || toks[0] == '' - return a:arg - endif - let fname = remove(toks, 0) - " Reduce filename according to the branch tokens. - for altBranch in toks - let fname = s:PFGetAltFiles("&", altBranch, fname)[0] - endfor - return fname -endfunction - -function! perforce#PFComplete(ArgLead, CmdLine, CursorPos) - if s:p4KnownCmdsCompStr == '' - let s:p4KnownCmdsCompStr = join(s:p4KnownCmds, "\n") - endif - if a:CmdLine =~ '^\s*P[FW] ' - let argStr = strpart(a:CmdLine, matchend(a:CmdLine, '^\s*PF ')) - let s:p4Command = '' - if argStr !~# s:EMPTY_STR - if exists('g:p4EnableUserFileExpand') - let _p4EnableUserFileExpand = g:p4EnableUserFileExpand - endif - try - " WORKAROUND for :redir broken, when called from here. - let g:p4EnableUserFileExpand = 0 - exec 'call s:ParseOptionsIF(-1, -1, 0, 0, ' . - \ genutils#CreateArgString(argStr, s:SPACE_AS_SEP).')' - finally - if exists('_p4EnableUserFileExpand') - let g:p4EnableUserFileExpand = _p4EnableUserFileExpand - else - unlet g:p4EnableUserFileExpand - endif - endtry - endif - if s:p4Command ==# '' || s:p4Command ==# a:ArgLead - return s:p4KnownCmdsCompStr."\n".join(s:builtinCmds, "\n") - endif - else - let userCmd = substitute(a:CmdLine, '^\s*P\(.\)\(\w*\).*', '\l\1\2', '') - if strlen(userCmd) < 3 - if !has_key(s:shortCmdMap, userCmd) - throw "Perforce internal error: no map found for short command: ". - \ userCmd - endif - let userCmd = s:shortCmdMap[userCmd] - endif - let s:p4Command = userCmd - endif - if s:p4Command ==# 'help' - return s:PHelpComplete(a:ArgLead, a:CmdLine, a:CursorPos) - endif - if index(s:nofileArgsCmds, s:p4Command) != -1 - return '' - endif - - " FIXME: Can't set command-line from user function. - "let argLead = genutils#UserFileExpand(a:ArgLead) - "if argLead !=# a:ArgLead - " let cmdLine = strpart(a:CmdLine, 0, a:CursorPos-strlen(a:ArgLead)) . - " \ argLead . strpart(a:CmdLine, a:CursorPos) - " exec "normal! \<C-\>e'".cmdLine."'\<CR>" - " call setcmdpos(a:CursorPos+(strlen(argLead) - strlen(a:ArgLead))) - " return '' - "endif - if a:ArgLead =~ '^//'.s:_('Depot').'/' - " Get directory matches. - let dirMatches = s:GetOutput('dirs', a:ArgLead, "\n", '/&') - " Get file matches. - let fileMatches = s:GetOutput('files', a:ArgLead, '#\d\+[^'."\n".']\+', '') - if dirMatches !~ s:EMPTY_STR || fileMatches !~ s:EMPTY_STR - return dirMatches.fileMatches - else - return '' - endif - endif - return genutils#UserFileComplete(a:ArgLead, a:CmdLine, a:CursorPos, 1, '') -endfunction - -function! s:GetOutput(p4Cmd, arg, pat, repl) - let matches = perforce#PFIF(0, 4, a:p4Cmd, a:arg.'*') - if s:errCode == 0 - if matches =~ 'no such file(s)' - let matches = '' - else - let matches = substitute(substitute(matches, a:pat, a:repl, 'g'), - \ "\n\n", "\n", 'g') - endif - endif - return matches -endfunction -" PFIF }}} - -""" START: Adopted from Tom's perforce plugin. {{{ - -"--------------------------------------------------------------------------- -" Produce string for ruler output -function! perforce#RulerStatus() - if exists('b:p4RulerStr') && b:p4RulerStr !~# s:EMPTY_STR - return b:p4RulerStr - endif - if !exists('b:p4FStatDone') || !b:p4FStatDone - return '' - endif - - "let b:p4RulerStr = '[p4 ' - let b:p4RulerStr = '[' - if exists('b:p4RulerErr') && b:p4RulerErr !~# s:EMPTY_STR - let b:p4RulerStr = b:p4RulerStr . b:p4RulerErr - elseif !exists('b:p4HaveRev') - let b:p4RulerStr = '' - elseif b:p4Action =~# s:EMPTY_STR - if b:p4OtherOpen =~# s:EMPTY_STR - let b:p4RulerStr = b:p4RulerStr . 'unopened' - else - let b:p4RulerStr = b:p4RulerStr . b:p4OtherOpen . ':' . b:p4OtherAction - endif - else - if b:p4Change ==# 'default' || b:p4Change =~# s:EMPTY_STR - let b:p4RulerStr = b:p4RulerStr . b:p4Action - else - let b:p4RulerStr = b:p4RulerStr . b:p4Action . ':' . b:p4Change - endif - endif - if exists('b:p4HaveRev') && b:p4HaveRev !~# s:EMPTY_STR - let b:p4RulerStr = b:p4RulerStr . ' #' . b:p4HaveRev . '/' . b:p4HeadRev - endif - - if b:p4RulerStr !~# s:EMPTY_STR - let b:p4RulerStr = b:p4RulerStr . ']' - endif - return b:p4RulerStr -endfunction - -function! s:GetClientInfo() - let infoStr = '' - call s:PushP4Context() - try - let infoStr = perforce#PFIF(0, 4, 'info') - if s:errCode != 0 - return s:ConfirmMessage((v:errmsg != '') ? v:errmsg : infoStr, 'OK', 1, - \ 'Error') - endif - finally - call s:PopP4Context(0) - endtry - let g:p4ClientRoot = genutils#CleanupFileName(s:StrExtract(infoStr, - \ '\CClient root: [^'."\n".']\+', 13)) - let s:p4Client = s:StrExtract(infoStr, '\CClient name: [^'."\n".']\+', 13) - let s:p4User = s:StrExtract(infoStr, '\CUser name: [^'."\n".']\+', 11) -endfunction - -" Get/refresh filestatus for the specified buffer with optimizations. -function! perforce#GetFileStatus(buf, refresh) - if ! type(a:buf) " If number. - let bufNr = (a:buf == 0) ? bufnr('%') : a:buf - else - let bufNr = bufnr(a:buf) - endif - - " If it is not a normal buffer, then ignore it. - if getbufvar(bufNr, '&buftype') != '' || bufname(bufNr) == '' - return "" - endif - if bufNr == -1 || (!a:refresh && s:_('OptimizeActiveStatus') && - \ getbufvar(bufNr, "p4FStatDone")) - return "" - endif - - " This is an optimization by restricting status to the files under the - " client root only. - if !s:IsFileUnderDepot(expand('#'.bufNr.':p')) - return "" - endif - - return s:GetFileStatusImpl(bufNr) -endfunction - -function! s:ResetFileStatusForFiles(files) - for file in a:files - let bufNr = genutils#FindBufferForName(file) - if bufNr != -1 - " FIXME: Check for other tabs also. - if bufwinnr(bufNr) != -1 " If currently visible. - call perforce#GetFileStatus(bufNr, 1) - else - call s:ResetFileStatusForBuffer(bufNr) - endif - endif - endfor -endfunction - -function! s:ResetFileStatusForBuffer(bufNr) - " Avoid proliferating this buffer variable. - if getbufvar(a:bufNr, 'p4FStatDone') != 0 - call setbufvar(a:bufNr, 'p4FStatDone', 0) - endif -endfunction - -"--------------------------------------------------------------------------- -" Obtain file status information -function! s:GetFileStatusImpl(bufNr) - if bufname(a:bufNr) == "" - return '' - endif - let fileName = fnamemodify(bufname(a:bufNr), ':p') - let bufNr = a:bufNr - " If the filename matches with one of the ignore patterns, then don't do - " status. - if s:_('ASIgnoreDefPattern') !~# s:EMPTY_STR && - \ match(fileName, s:_('ASIgnoreDefPattern')) != -1 - return '' - endif - if s:_('ASIgnoreUsrPattern') !~# s:EMPTY_STR && - \ match(fileName, s:_('ASIgnoreUsrPattern')) != -1 - return '' - endif - - call setbufvar(bufNr, 'p4RulerStr', '') " Let this be reconstructed. - - " This could very well be a recursive call, so we should save the current - " state. - call s:PushP4Context() - try - let fileStatusStr = perforce#PFIF(1, 4, 'fstat', fileName) - call setbufvar(bufNr, 'p4FStatDone', '1') - - if s:errCode != 0 - call setbufvar(bufNr, 'p4RulerErr', "<ERROR>") - return '' - endif - finally - call s:PopP4Context(0) - endtry - - if match(fileStatusStr, ' - file(s) not in client view\.') >= 0 - call setbufvar(bufNr, 'p4RulerErr', "<Not In View>") - " Required for optimizing out in future runs. - call setbufvar(bufNr, 'p4HeadRev', '') - return '' - elseif match(fileStatusStr, ' - no such file(s).') >= 0 - call setbufvar(bufNr, 'p4RulerErr', "<Not In Depot>") - " Required for optimizing out in future runs. - call setbufvar(bufNr, 'p4HeadRev', '') - return '' - else - call setbufvar(bufNr, 'p4RulerErr', '') - endif - - call setbufvar(bufNr, 'p4HeadRev', - \ s:StrExtract(fileStatusStr, '\CheadRev [0-9]\+', 8)) - "call setbufvar(bufNr, 'p4DepotFile', - " \ s:StrExtract(fileStatusStr, '\CdepotFile [^'."\n".']\+', 10)) - "call setbufvar(bufNr, 'p4ClientFile', - " \ s:StrExtract(fileStatusStr, '\CclientFile [^'."\n".']\+', 11)) - call setbufvar(bufNr, 'p4HaveRev', - \ s:StrExtract(fileStatusStr, '\ChaveRev [0-9]\+', 8)) - let headAction = s:StrExtract(fileStatusStr, '\CheadAction [^[:space:]]\+', - \ 11) - if headAction ==# 'delete' - call setbufvar(bufNr, 'p4Action', '<Deleted>') - call setbufvar(bufNr, 'p4Change', '') - else - call setbufvar(bufNr, 'p4Action', - \ s:StrExtract(fileStatusStr, '\Caction [^[:space:]]\+', 7)) - call setbufvar(bufNr, 'p4OtherOpen', - \ s:StrExtract(fileStatusStr, '\CotherOpen0 [^[:space:]@]\+', 11)) - call setbufvar(bufNr, 'p4OtherAction', - \ s:StrExtract(fileStatusStr, '\CotherAction0 [^[:space:]@]\+', 13)) - call setbufvar(bufNr, 'p4Change', - \ s:StrExtract(fileStatusStr, '\Cchange [^[:space:]]\+', 7)) - endif - - return fileStatusStr -endfunction - -function! s:StrExtract(str, pat, pos) - let part = matchstr(a:str, a:pat) - let part = strpart(part, a:pos) - return part -endfunction - -function! s:AdjustRevision(file, adjustment) - let s:errCode = 0 - let revNum = a:adjustment - if revNum =~# '[-+]\d\+' - let revNum = substitute(revNum, '^+', '', '') - if getbufvar(a:file, 'p4HeadRev') =~# s:EMPTY_STR - " If fstat is not done yet, do it now. - call perforce#GetFileStatus(a:file, 1) - if getbufvar(a:file, 'p4HeadRev') =~# s:EMPTY_STR - call s:EchoMessage("Current revision is not available. " . - \ "To be able to use negative revisions, see help on " . - \ "'perforce-active-status'.", 'Error') - let s:errCode = 1 - return -1 - endif - endif - let revNum = getbufvar(a:file, 'p4HaveRev') + revNum - if revNum < 1 - call s:EchoMessage("Not that many revisions available. Try again " . - \ "after running PFRefreshFileStatus command.", 'Error') - let s:errCode = 1 - return -1 - endif - endif - return revNum -endfunction - -"--------------------------------------------------------------------------- -" One of a set of functions that returns fields from the p4 fstat command -function! s:IsCurrent() - let revdiff = b:p4HeadRev - b:p4HaveRev - if revdiff == 0 - return 0 - else - return -1 - endif -endfunction - -function! s:CheckOutFile() - if ! g:p4PromptToCheckout || ! s:IsFileUnderDepot(expand('%:p')) - return - endif - " If we know that the file is deleted from the depot, don't prompt. - if exists('b:p4Action') && b:p4Action == '<Deleted>' - return - endif - - if filereadable(expand("%")) && ! filewritable(expand("%")) - let option = s:ConfirmMessage("Readonly file, do you want to checkout " . - \ "from perforce?", "&Yes\n&No\n&Cancel", s:_('CheckOutDefault'), - \ "Question") - if option == 1 - call perforce#PFIF(1, 2, 'edit') - if ! s:errCode - edit - call perforce#GetFileStatus(expand('<abuf>') + 0, 1) - endif - elseif option == 3 - call s:CancelEdit(0) - endif - endif -endfunction - -function! s:CancelEdit(stage) - aug P4CancelEdit - au! - if a:stage == 0 - au CursorMovedI <buffer> nested :call <SID>CancelEdit(1) - au CursorMoved <buffer> nested :call <SID>CancelEdit(1) - elseif a:stage == 1 - stopinsert - silent undo - setl readonly - endif - aug END -endfunction - -function! perforce#FileChangedShell() - let bufNr = expand("<abuf>") + 0 - if s:_('EnableActiveStatus') - call s:ResetFileStatusForBuffer(bufNr) - endif - let autoread = -1 - if index(s:autoreadCmds, s:currentCommand) != -1 - let autoread = s:_('Autoread') - if autoread - call setbufvar(bufNr, '&readonly', 0) - endif - endif - return autoread -endfunction -""" END: Adapted from Tom's perforce plugin. }}} - -""" END: Middleware functions }}} - - -""" BEGIN: Infrastructure {{{ - -" Assumes that the arguments are already parsed and are ready to be used in -" the script variables. -" Low level interface with the p4 command. -" clearBuffer: If the buffer contents should be cleared before -" adding the new output (See s:GotoWindow). -" testMode (number): -" 0 - Run normally. -" 1 - testing, ignore. -" 2 - debugging, display the command-line instead of the actual output.. -" Returns the output if available. If there is any error, the error code will -" be available in s:errCode variable. -function! s:PFImpl(clearBuffer, testMode) " {{{ - try " [-2f] - - let s:errCode = 0 - let p4Options = s:GetP4Options() - let fullCmd = s:CreateFullCmd(s:MakeP4ArgList(p4Options, 0)) - " Save the name of the current file. - let p4OrgFileName = s:GetCurFileName() - - let s:currentCommand = '' - " Make sure all the already existing changes are detected. We don't have - " s:currentCommand set here, so the user will get an appropriate prompt. - try - checktime - catch - " FIXME: Ignore error for now. - endtry - - " If the output has to be shown in a window, position cursor appropriately, - " creating a new window if required. - let v:errmsg = "" - " Ignore outputType in this case. - if s:commandMode != s:CM_PIPE && s:commandMode != s:CM_FILTER - if s:outputType == 0 || s:outputType == 1 - " Only when "clear with undo" is selected, we optimize out the call. - if s:GotoWindow(s:outputType, - \ (!s:refreshWindowsAlways && (a:clearBuffer == 1)) ? - \ 2 : a:clearBuffer, p4OrgFileName, 0) != 0 - return s:errCode - endif - endif - endif - - let output = '' - if s:errCode == 0 - if ! a:testMode - let s:currentCommand = s:p4Command - if s:_('EnableFileChangedShell') - call genutils#DefFCShellInstall() - endif - - try - if s:commandMode ==# s:CM_RUN - " Only when "clear with undo" is selected, we optimize out the call. - if s:refreshWindowsAlways || - \ ((!s:refreshWindowsAlways && (a:clearBuffer == 1)) && - \ (line('$') == 1 && getline(1) =~ '^\s*$')) - " If we are placing the output in a new window, then we should - " avoid system() for performance reasons, imagine doing a - " 'print' on a huge file. - " These two outputType's correspond to placing the output in a - " window. - if s:outputType != 0 && s:outputType != 1 - let output = s:System(fullCmd) - else - exec '.call s:Filter(fullCmd, 1)' - let output = '' - endif - endif - elseif s:commandMode ==# s:CM_FILTER - exec s:filterRange . 'call s:Filter(fullCmd, 1)' - elseif s:commandMode ==# s:CM_PIPE - exec s:filterRange . 'call s:Filter(fullCmd, 2)' - endif - " Detect any new changes to the loaded buffers. - " CAUTION: This actually results in a reentrant call back to this - " function, but our Push/Pop mechanism for the context should take - " care of it. - try - checktime - catch - " FIXME: Ignore error for now. - endtry - finally - if s:_('EnableFileChangedShell') - call genutils#DefFCShellUninstall() - endif - let s:currentCommand = '' - endtry - elseif a:testMode != 1 - let output = fullCmd - endif - - let v:errmsg = "" - " If we have non-null output, then handling it is still pending. - if output !~# s:EMPTY_STR - let echoGrp = 'NONE' " The default - let maxLinesInDlg = s:_('MaxLinesInDialog') - if s:outputType == 2 && maxLinesInDlg != -1 - " Count NLs. - let nNLs = 0 - let nlIdx = 0 - while 1 - let nlIdx = stridx(output, "\n", nlIdx+1) - if nlIdx != -1 - let nNLs += 1 - if nNLs > maxLinesInDlg - break - endif - else - break - endif - endwhile - if nNLs > maxLinesInDlg - " NOTE: Keep in sync with that at the start of the function. - if s:GotoWindow(s:outputType, - \ (!s:refreshWindowsAlways && (a:clearBuffer == 1)) ? - \ 2 : a:clearBuffer, p4OrgFileName, 0) == 0 - let s:outputType = 0 - else - let s:outputType = 3 - let echoGrp = 'WarningMsg' - endif - endif - endif - " If the output has to be shown in a dialog, bring up a dialog with the - " output, otherwise show it in the current window. - if s:outputType == 0 || s:outputType == 1 - silent! put! =output - 1 - elseif s:outputType == 2 - call s:ConfirmMessage(output, "OK", 1, "Info") - elseif s:outputType == 3 - call s:EchoMessage(output, echoGrp) - elseif s:outputType == 4 - " Do nothing we will just return it. - endif - endif - endif - return output - - finally " [+2s] - call s:InitWindow(p4Options) - endtry -endfunction " }}} - -function! s:NewWindowCreated() - if (s:outputType == 0 || s:outputType == 1) && s:errCode == 0 && - \ (s:commandMode ==# s:CM_RUN) - return 1 - else - return 0 - endif -endfunction - -function! s:setBufSetting(opt, set) - let optArg = matchstr(b:p4Options, '\%(\S\)\@<!-'.a:opt.'\s\+\S\+') - if optArg !~# s:EMPTY_STR - let b:p4Options = substitute(b:p4Options, '\V'.optArg, '', '') - let b:{a:set} = matchstr(optArg, '-'.a:opt.'\s\+\zs.*') - endif -endfunction - -" These p4Options are frozen according to the current s:p4Options. -function! s:InitWindow(p4Options) - if s:NewWindowCreated() - let b:p4Command = s:p4Command - let b:p4Options = a:p4Options - let b:p4CmdOptions = s:p4CmdOptions - let b:p4Arguments = s:p4Arguments - let b:p4UserArgs = s:userArgs - " Separate -p port -c client -u user options and set them individually. - " Leave the rest in the b:p4Options variable. - call s:setBufSetting('c', 'p4Client') - call s:setBufSetting('p', 'p4Port') - call s:setBufSetting('u', 'p4User') - " Remove any ^M's at the end (for windows), without corrupting the search - " register or its history. - call genutils#SilentSubstitute("\<CR>$", '%s///e') - setlocal nomodifiable - setlocal nomodified - - if s:outputType == 1 - wincmd p - endif - endif -endfunction - -" External command execution {{{ - -function! s:System(fullCmd) - return s:ExecCmd(a:fullCmd, 0) -endfunction - -function! s:Filter(fullCmd, mode) range - " For command-line, we need to protect '%', '#' and '!' chars, even if they - " are in quotes, to avoid getting expanded by Vim before invoking external - " cmd. - let fullCmd = genutils#Escape(a:fullCmd, '%#!') - exec a:firstline.",".a:lastline. - \ "call s:ExecCmd(fullCmd, a:mode)" -endfunction - -function! s:ExecCmd(fullCmd, mode) range - let v:errmsg = '' - let output = '' - try - " Assume the shellredir is set correctly to capture the error messages. - if a:mode == 0 - let output = system(a:fullCmd) - elseif a:mode == 1 - silent! exec a:firstline.",".a:lastline."!".a:fullCmd - else - silent! exec a:firstline.",".a:lastline."write !".a:fullCmd - endif - - call s:CheckShellError(output, s:outputType) - return output - catch /^Vim\%((\a\+)\)\=:E/ " 48[2-5] - let v:errmsg = substitute(v:exception, '^[^:]\+:', '', '') - call s:CheckShellError(output, s:outputType) - catch /^Vim:Interrupt$/ - let s:errCode = 1 - let v:errmsg = 'Interrupted' - catch " Ignore. - endtry -endfunction - -function! s:EvalExpr(expr, def) - let result = a:def - if a:expr !~# s:EMPTY_STR - exec "let result = " . a:expr - endif - return result -endfunction - -function! s:GetP4Options() - let addOptions = [] - - " If there are duplicates, perfore takes the first option, so let - " s:p4Options or b:p4Options come before g:p4DefaultOptions. - " LIMITATATION: We choose either s:p4Options or b:p4Options only. But this - " shouldn't be a big issue as this feature is meant for executing more - " commands on the p4 result windows only. - if len(s:p4Options) != 0 - call extend(addOptions, s:p4Options) - elseif exists('b:p4Options') && len(b:p4Options) != 0 - call extend(addOptions, b:p4Options) - endif - - " FIXME: avoid split here. - call extend(addOptions, split(s:_('DefaultOptions'), ' ')) - - let p4Client = s:p4Client - let p4User = s:p4User - let p4Port = s:p4Port - try - if s:p4Port !=# 'P4CONFIG' - if s:_('CurPresetExpr') !~# s:EMPTY_STR - let preset = s:EvalExpr(s:_('CurPresetExpr'), '') - if preset ~= s:EMPTY_STR - call perforce#PFSwitch(0, preset) - endif - endif - - if s:_('p4Client') !~# s:EMPTY_STR && index(addOptions, '-c') == -1 - call add(add(addOptions, '-c'), s:_('p4Client')) - endif - if s:_('p4User') !~# s:EMPTY_STR && index(addOptions, '-u') == -1 - call add(add(addOptions, '-u'), s:_('p4User')) - endif - if s:_('p4Port') !~# s:EMPTY_STR && index(addOptions, '-p') == -1 - call add(add(addOptions, '-p'), s:_('p4Port')) - endif - " Don't pass password with '-P' option, it will be too open (ps will show - " it up). - let $P4PASSWD = s:p4Password - else - endif - finally - let s:p4Client = p4Client - let s:p4User = p4User - let s:p4Port = p4Port - endtry - - return addOptions -endfunction - -function! s:CreateFullCmd(argList) - let fullCmd = genutils#EscapeCommand(s:p4CommandPrefix.s:_('CmdPath'), a:argList, - \ s:p4Pipe) - let g:p4FullCmd = fullCmd - return fullCmd -endfunction - -" Generates a command string as the user typed, using the script variables. -function! s:MakeP4ArgList(p4Options, useBufLocal) - if a:useBufLocal && exists('b:p4Command') - let p4Command = b:p4Command - else - let p4Command = s:p4Command - endif - if a:useBufLocal && exists('b:p4CmdOptions') - let p4CmdOptions = b:p4CmdOptions - else - let p4CmdOptions = s:p4CmdOptions - endif - if a:useBufLocal && exists('b:p4Arguments') - let p4Arguments = b:p4Arguments - else - let p4Arguments = s:p4Arguments - endif - let cmdList = a:p4Options+[p4Command]+p4CmdOptions+p4Arguments - " Remove the protection from the characters that we treat specially (Note: # - " and % are treated specially by Vim command-line itself, and the - " back-slashes are removed even before we see them.) - call map(cmdList, "genutils#UnEscape(v:val, '&')") - return cmdList -endfunction - -" In case of outputType == 4, it assumes the caller wants to see the output as -" it is, so no error message is given. The caller is expected to check for -" error code, though. -function! s:CheckShellError(output, outputType) - if (v:shell_error != 0 || v:errmsg != '') && a:outputType != 4 - let output = "There was an error executing external p4 command.\n" - if v:errmsg != '' - let output = output . "\n" . "errmsg = " . v:errmsg - endif - " When commandMode ==# s:CM_RUN, the error message may already be there in - " the current window. - if a:output !~# s:EMPTY_STR - let output = output . "\n" . a:output - elseif a:output =~# s:EMPTY_STR && - \ (s:commandMode ==# s:CM_RUN && line('$') == 1 && col('$') == 1) - let output = output . "\n\n" . - \ "Check if your 'shellredir' option captures error messages." - endif - call s:ConfirmMessage(output, "OK", 1, "Error") - endif - let s:errCode = v:shell_error - return v:shell_error -endfunction - -" External command execution }}} - -" Push/Pop/Peek context {{{ -function! s:PushP4Context() - call add(s:p4Contexts, s:GetP4ContextVars()) -endfunction - -function! s:PeekP4Context() - return s:PopP4ContextImpl(1, 1) -endfunction - -function! s:PopP4Context(...) - " By default carry forward error. - return s:PopP4ContextImpl(0, (a:0 ? a:1 : 1)) -endfunction - -function! s:NumP4Contexts() - return len(s:p4Contexts) -endfunction - -function! s:PopP4ContextImpl(peek, carryFwdErr) - let nContexts = len(s:p4Contexts) - if nContexts <= 0 - echoerr "PopP4Context: Contexts stack is empty" - return - endif - let context = s:p4Contexts[-1] - if !a:peek - call remove(s:p4Contexts, nContexts-1) - endif - - call s:SetP4ContextVars(context, a:carryFwdErr) - return context -endfunction - -" Serialize p4 context variables. -function! s:GetP4ContextVars() - return [s:p4Options , s:p4Command , s:p4CmdOptions , s:p4Arguments , - \ s:p4Pipe , s:p4WinName , s:commandMode , s:filterRange , - \ s:outputType , s:errCode, s:userArgs] -endfunction - -" De-serialize p4 context variables. -function! s:SetP4ContextVars(context, ...) - let carryFwdErr = 0 - if a:0 && a:1 - let carryFwdErr = s:errCode - endif - - let [s:p4Options, s:p4Command, s:p4CmdOptions, s:p4Arguments, s:p4Pipe, - \ s:p4WinName, s:commandMode, s:filterRange, s:outputType, s:errCode, - \ s:userArgs] = a:context - let s:errCode = s:errCode + carryFwdErr -endfunction -" Push/Pop/Peek context }}} - -""" BEGIN: Argument parsing {{{ -function! s:ResetP4ContextVars() - " Syntax is: - " PF <p4Options> <p4Command> <p4CmdOptions> <p4Arguments> | <p4Pipe> - " Ex: PF -c hari integrate -b branch -s <fromFile> <toFile> - let s:p4Options = [] - let s:p4Command = "" - let s:p4CmdOptions = [] - let s:p4Arguments = [] - let s:p4Pipe = [] - let s:p4WinName = "" - " commandMode: - " run - Execute p4 using system() or its equivalent. - " filter - Execute p4 as a filter for the current window contents. Use - " commandPrefix to restrict the filter range. - " display - Don't execute p4. The output is already passed in. - let s:commandMode = "run" - let s:filterRange = "" - let s:outputType = 0 - let s:errCode = 0 - - " Special variable to keep track of full user arguments. - let s:userArgs = [] -endfunction -call s:ResetP4ContextVars() " Let them get initialized the first time. - -" Parses the arguments into 4 parts, "options to p4", "p4 command", -" "options to p4 command", "actual arguments". Also generates the window name. -" outputType (string): -" 0 - Execute p4 and place the output in a new window. -" 1 - Same as above, but use preview window. -" 2 - Execute p4 and show the output in a dialog for confirmation. -" 3 - Execute p4 and echo the output. -" 4 - Execute p4 and return the output. -" 5 - Execute p4 no output expected. Essentially same as 4 when the current -" commandMode doesn't produce any output, just for clarification. -function! s:ParseOptions(fline, lline, outputType, ...) " range - call s:ResetP4ContextVars() - let s:outputType = a:outputType - if a:0 == 0 - return - endif - - let s:filterRange = a:fline . ',' . a:lline - let i = 1 - let prevArg = "" - let curArg = "" - let s:pendingPipeArg = '' - while i <= a:0 - try " Just for the sake of loop variables. [-2f] - - if s:pendingPipeArg !~# s:EMPTY_STR - let curArg = s:pendingPipeArg - let s:pendingPipeArg = '' - elseif len(s:p4Pipe) == 0 - let curArg = a:000[i-1] - " The user can't specify a null string on the command-line, this is an - " argument originating from the script, so just ignore it (just for - " the sake of convenience, see PChangesDiff for a possibility). - if curArg == '' - continue - endif - let pipeIndex = match(curArg, '\\\@<!\%(\\\\\)*\zs|') - if pipeIndex != -1 - let pipePart = strpart(curArg, pipeIndex) - let p4Part = strpart(curArg, 0, pipeIndex) - if p4Part !~# s:EMPTY_STR - let curArg = p4Part - let s:pendingPipeArg = pipePart - else - let curArg = pipePart - endif - endif - else - let curArg = a:000[i-1] - endif - - if curArg ==# '<pfitem>' - let curItem = s:GetCurrentItem() - if curItem !~# s:EMPTY_STR - let curArg = curItem - endif - endif - - " As we use custom completion mode, the filename meta-sequences in the - " arguments will not be expanded by Vim automatically, so we need to - " expand them manually here. On the other hand, this provides us control - " on what to expand, so we can avoid expanding perforce file revision - " numbers as buffernames (escaping is no longer required by the user on - " the commandline). - let fileRev = '' - let fileRevIndex = match(curArg, '#\(-\?\d\+\|none\|head\|have\)$') - if fileRevIndex != -1 - let fileRev = strpart(curArg, fileRevIndex) - let curArg = strpart(curArg, 0, fileRevIndex) - endif - if curArg != '' && (!exists('g:p4EnableUserFileExpand') || - \ g:p4EnableUserFileExpand) - let curArg = genutils#UserFileExpand(curArg) - endif - if fileRev != '' - let curArg = curArg.fileRev - endif - - if curArg =~# '^|' || len(s:p4Pipe) != 0 - call add(s:p4Pipe, curArg) - continue - endif - - if ! s:IsAnOption(curArg) " If not an option. - if s:p4Command =~# s:EMPTY_STR && - \ index(s:allCommands, curArg) != -1 - " If the previous one was an option to p4 that takes in an argument. - if prevArg =~# '^-[cCdHLpPux]$' || prevArg =~# '^++o$' " See :PH usage. - call add(s:p4Options, curArg) - if prevArg ==# '++o' && (curArg == '0' || curArg == 1) - let s:outputType = curArg - endif - else - let s:p4Command = curArg - endif - else " Argument is not a perforce command. - if s:p4Command =~# s:EMPTY_STR - call add(s:p4Options, curArg) - else - let optArg = 0 - " Look for options that have an argument, so we can collect this - " into p4CmdOptions instead of p4Arguments. - if len(s:p4Arguments) == 0 && s:IsAnOption(prevArg) - " We could as well just check for the option here, but combining - " this with the command name will increase the accuracy of finding - " the starting point for p4Arguments. - if (prevArg[0] ==# '-' && has_key(s:p4OptCmdMap, prevArg[1]) && - \ index(s:p4OptCmdMap[prevArg[1]], s:p4Command) != -1) || - \ (prevArg =~# '^++' && has_key(s:biOptCmdMap, prevArg[2]) && - \ index(s:biOptCmdMap[prevArg[2]], s:p4Command) != -1) - let optArg = 1 - endif - endif - - if optArg - call add(s:p4CmdOptions, curArg) - else - call add(s:p4Arguments, curArg) - endif - endif - endif - else - if len(s:p4Arguments) == 0 - if s:p4Command =~# s:EMPTY_STR - if curArg =~# '^++[pfdr]$' - if curArg ==# '++p' - let s:commandMode = s:CM_PIPE - elseif curArg ==# '++f' - let s:commandMode = s:CM_FILTER - elseif curArg ==# '++r' - let s:commandMode = s:CM_RUN - endif - continue - endif - call add(s:p4Options, curArg) - else - call add(s:p4CmdOptions, curArg) - endif - else - call add(s:p4Arguments, curArg) - endif - endif - " The "-x -" option requires it to act like a filter. - if s:p4Command =~# s:EMPTY_STR && prevArg ==# '-x' && curArg ==# '-' - let s:commandMode = s:CM_FILTER - endif - - finally " [+2s] - if s:pendingPipeArg =~# s:EMPTY_STR - let i = i + 1 - endif - let prevArg = curArg - endtry - endwhile - - if index(s:p4Options, '-d') == -1 - let curDir = s:EvalExpr(s:_('CurDirExpr'), '') - if curDir !=# '' - call add(add(s:p4Options, '-d'), s:EscapeFileName(curDir)) - endif - endif - let s:p4WinName = s:MakeWindowName() -endfunction - -function! s:IsAnOption(arg) - if a:arg =~# '^-.$' || a:arg =~# '^-d\%([cnsubw]\|\d\+\)*$' || - \ a:arg =~# '^-a[fmsty]$' || a:arg =~# '^-s[ader]$' || - \ a:arg =~# '^-qu$' || a:arg =~# '^+' - return 1 - else - return 0 - endif -endfunction - -function! s:CleanSpaces(str) - " Though not complete, it is enough to just say, - " "spaces that are not preceded by \'s". - return substitute(substitute(a:str, '^ \+\|\%(\\\@<! \)\+$', '', 'g'), - \ '\%(\\\@<! \)\+', ' ', 'g') -endfunction - -function! s:_(set) - let set = a:set - if set =~# '^\u' - let set = 'p4'.set - endif - if exists('b:'.set) - return b:{set} - elseif exists('w:'.set) - return w:{set} - elseif exists('t:'.set) - return t:{set} - elseif exists('s:'.set) - return s:{set} - elseif exists('g:'.set) - return g:{set} - else - echoerr 'No setting found for: ' set - endif -endfunction - -function! s:indexMatching(list, pat) - let i = 0 - for item in a:list - if item =~ a:pat - return i - endif - let i += 1 - endfor - return -1 -endfunction -""" END: Argument parsing }}} - -""" BEGIN: Messages and dialogs {{{ -function! s:SyntaxError(msg) - let s:errCode = 1 - call s:ConfirmMessage("Syntax Error:\n".a:msg, "OK", 1, "Error") - return s:errCode -endfunction - -function! s:ShowVimError(errmsg, stack) - call s:ConfirmMessage("There was an error executing a Vim command.\n\t" . - \ a:errmsg.(a:stack != '' ? "\nCurrent stack: ".a:stack : ''), "OK", 1, - \ "Error") - echohl ErrorMsg | echomsg a:errmsg | echohl None - if a:stack != '' - echomsg "Current stack:" a:stack - endif - redraw " Cls, such that it is only available in the message list. - let s:errCode = 1 - return s:errCode -endfunction - -function! s:EchoMessage(msg, type) - let s:lastMsg = a:msg - let s:lastMsgGrp = a:type - redraw | exec 'echohl' a:type | echo a:msg | echohl NONE -endfunction - -function! s:ConfirmMessage(msg, opts, def, type) - let s:lastMsg = a:msg - let s:lastMsgGrp = 'None' - if a:type ==# 'Error' - let s:lastMsgGrp = 'Error' - endif - return confirm(a:msg, a:opts, a:def, a:type) -endfunction - -function! s:PromptFor(loop, useDialogs, msg, default) - let result = "" - while result =~# s:EMPTY_STR - if a:useDialogs - let result = inputdialog(a:msg, a:default) - else - let result = input(a:msg, a:default) - endif - if ! a:loop - break - endif - endwhile - return result -endfunction - -function! perforce#LastMessage() - call s:EchoMessage(s:lastMsg, s:lastMsgGrp) -endfunction -""" END: Messages and dialogs }}} - -""" BEGIN: Filename handling {{{ -" Escape all the special characters (as the user would if he typed the name -" himself). -function! s:EscapeFileName(fName) - " If there is a -d option existing, then it is better to use the full path - " name. - if index(s:p4Options, '-d') != -1 - let fName = fnamemodify(a:fName, ':p') - else - let fName = a:fName - endif - return genutils#Escape(fName, ' &|') -endfunction - -function! s:GetCurFileName() - " When the current window itself is a perforce window, then carry over the - " existing value. - return (exists('b:p4OrgFileName') && - \ b:p4OrgFileName !~# s:EMPTY_STR) ? - \ b:p4OrgFileName : expand('%:p') -endfunction - -function! s:GuessFileTypeForCurrentWindow() - let fileExt = s:GuessFileType(b:p4OrgFileName) - if fileExt =~# s:EMPTY_STR - let fileExt = s:GuessFileType(expand("%")) - endif - return fileExt -endfunction - -function! s:GuessFileType(name) - let fileExt = fnamemodify(a:name, ":e") - return matchstr(fileExt, '\w\+') -endfunction - -function! s:IsDepotPath(path) - if match(a:path, '^//'.s:_('Depot').'/') == 0 - " \ || match(a:path, '^//'. s:_('p4Client') . '/') == 0 - return 1 - else - return 0 - endif -endfunction - -function! s:PathRefersToDepot(path) - if s:IsDepotPath(a:path) || s:GetRevisionSpecifier(a:path) !~# s:EMPTY_STR - return 1 - else - return 0 - endif -endfunction - -function! s:GetRevisionSpecifier(fileName) - return matchstr(a:fileName, - \ '^\(\%(\S\|\\\@<!\%(\\\\\)*\\ \)\+\)[\\]*\zs[#@].*$') -endfunction - -" Removes the //<depot> or //<client> prefix from fileName. -function! s:StripRemotePath(fileName) - "return substitute(a:fileName, '//\%('.s:_('Depot').'\|'.s:_('p4Client').'\)', '', '') - return substitute(a:fileName, '//\%('.s:_('Depot').'\)', '', '') -endfunction - -" Client view translation {{{ -" Convert perforce file wildcards ("*", "..." and "%[1-9]") to a Vim string -" regex (see |pattern.txt|). Returns patterns that work when "very nomagic" -" is set. -let s:p4Wild = {} -function! s:TranlsateP4Wild(p4Wild, rhsView) - let strRegex = '' - if a:rhsView - if a:p4Wild[0] ==# '%' - let pos = s:p4WildMap[a:p4Wild[1]] - else - let pos = s:p4WildCount - endif - let strRegex = '\'.pos - else - if a:p4Wild ==# '*' - let strRegex = '\(\[^/]\*\)' - elseif a:p4Wild ==# '...' - let strRegex = '\(\.\*\)' - elseif a:p4Wild[0] ==# '%' - let strRegex = '\(\[^/]\*\)' - let s:p4WildMap[a:p4Wild[1]] = s:p4WildCount - endif - endif - let s:p4WildCount = s:p4WildCount + 1 - return strRegex -endfunction - -" Convert perforce file regex (containing "*", "..." and "%[1-9]") to a Vim -" string regex. No error checks for now, for simplicity. -function! s:TranslateP4FileRegex(p4Regex, rhsView) - let s:p4WildCount = 1 - " Note: We don't expect backslashes in the views, so no special handling. - return substitute(a:p4Regex, - \ '\(\*\|\%(\.\)\@<!\.\.\.\%(\.\)\@!\|%\([1-9]\)\)', - \ '\=s:TranlsateP4Wild(submatch(1), a:rhsView)', 'g') -endfunction - -function! s:CondUpdateViewMappings() - if s:_('UseClientViewMap') && - \ (!has_key(s:toDepotMapping, s:_("p4Client")) || - \ (len(s:toDepotMapping[s:_('p4Client')]) < 0)) - call perforce#UpdateViewMappings() - endif -endfunction - -function! perforce#UpdateViewMappings() - if s:_('p4Client') =~# s:EMPTY_STR - return - endif - let view = '' - call s:PushP4Context() - try - let view = substitute(perforce#PFIF(1, 4, '-c', s:_('p4Client'), 'client'), - \ "\\_.*\nView:\\ze\n", '', 'g') - if s:errCode != 0 - return - endif - finally - call s:PopP4Context(0) - endtry - let fromDepotMapping = [] - let toDepotMapping = [] - for nextMap in reverse(split(view, "\n")) - " We need to inverse the order of mapping such that the mappings that come - " later in the view take more priority. - " Also, don't care about exclusionary mappings for simplicity (this could - " be considered a feature too). - exec substitute(nextMap, - \ '\s*-\?//'.s:_('Depot').'/\([^ ]\+\)\s*//'.s:_("p4Client").'/\(.\+\)', - \ 'call add(fromDepotMapping, [s:TranslateP4FileRegex('. - \ "'".'\1'."'".', 0), s:TranslateP4FileRegex('."'".'\2'."'". - \ ', 1)])', '') - exec substitute(nextMap, - \ '\s*-\?//'.s:_('Depot').'/\([^ ]\+\)\s*//'.s:_("p4Client").'/\(.\+\)', - \ 'call add(toDepotMapping, [s:TranslateP4FileRegex('. - \ "'".'\2'."'".', 0), s:TranslateP4FileRegex('."'".'\1'."'". - \ ', 1)])', '') - endfor - let s:fromDepotMapping[s:_('p4Client')] = fromDepotMapping - let s:toDepotMapping[s:_('p4Client')] = toDepotMapping -endfunction - -function! P4IncludeExpr(path) - return s:ConvertToLocalPath(a:path) -endfunction - -function! s:ConvertToLocalPath(path) - let fileName = substitute(a:path, '^\s\+\|\s*#[^#]\+$', '', 'g') - if s:IsDepotPath(fileName) - if s:_('UseClientViewMap') - call s:CondUpdateViewMappings() - for nextMap in s:fromDepotMapping[s:_('p4Client')] - let [lhs, rhs] = nextMap - if fileName =~# '\V'.lhs - let fileName = substitute(fileName, '\V'.lhs, rhs, '') - break - endif - endfor - endif - if s:IsDepotPath(fileName) - let fileName = s:_('ClientRoot') . s:StripRemotePath(fileName) - endif - endif - return fileName -endfunction - -function! s:ConvertToDepotPath(path) - " If already a depot path, just return it without any changes. - if s:IsDepotPath(a:path) - let fileName = a:path - else - let fileName = genutils#CleanupFileName(a:path) - if s:IsFileUnderDepot(fileName) - if s:_('UseClientViewMap') - call s:CondUpdateViewMappings() - for nextMap in s:toDepotMapping[s:_('p4Client')] - let [lhs, rhs] = nextMap - if fileName =~# '\V'.lhs - let fileName = substitute(fileName, '\V'.lhs, rhs, '') - break - endif - endfor - endif - if ! s:IsDepotPath(fileName) - let fileName = substitute(fileName, '^'.s:_('ClientRoot'), - \ '//'.s:_('Depot'), '') - endif - endif - endif - return fileName -endfunction -" Client view translation }}} - -" Requires at least 2 arguments. -" Returns a List of alternative filenames. -function! s:PFGetAltFiles(protectedChars, codeline, ...) - if a:0 == 0 - return [] - endif - - let altCodeLine = a:codeline - - let i = 1 - let altFiles = [] - while i <= a:0 - let fileName = a:000[i-1] - let fileName = genutils#CleanupFileName2(fileName, a:protectedChars) - - if altCodeLine ==# 'local' && s:IsDepotPath(fileName) - let altFile = s:ConvertToLocalPath(fileName) - elseif ! s:IsDepotPath(fileName) - let fileName = s:ConvertToDepotPath(fileName) - - if altCodeLine ==# s:_('Depot') - " We do nothing, it is already converted to depot path. - let altFile = fileName - else - " FIXME: Assumes that the current branch name has single path component. - let altFile = substitute(fileName, '//'.s:_('Depot').'/[^/]\+', - \ '//'.s:_('Depot').'/' . altCodeLine, "") - let altFile = s:ConvertToLocalPath(altFile) - endif - endif - call add(altFiles, altFile) - let i = i + 1 - endwhile - return altFiles -endfunction - -function! s:IsFileUnderDepot(fileName) - let fileName = genutils#CleanupFileName(a:fileName) - if fileName =~? '^\V'.s:_('ClientRoot') - return 1 - else - return 0 - endif -endfunction - -" This better take the line as argument, but I need the context of current -" buffer contents anyway... -" I don't need to handle other revision specifiers here, as I won't expect to -" see them here (perforce converts them to the appropriate revision number). -function! s:GetCurrentDepotFile(lineNo) - " Local submissions. - let fileName = "" - let line = getline(a:lineNo) - if match(line, '//'.s:_('Depot').'/.*\(#\d\+\)\?') != -1 - " \ || match(line, '^//'. s:_('p4Client') . '/.*\(#\d\+\)\?') != -1 - let fileName = matchstr(line, '//[^/]\+/[^#]*\(#\d\+\)\?') - elseif match(line, '\.\.\. #\d\+ .*') != -1 - " Branches, integrations etc. - let fileVer = matchstr(line, '\d\+') - call genutils#SaveHardPosition('Perforce') - exec a:lineNo - if search('^//'.s:_('Depot').'/', 'bW') == 0 - let fileName = "" - else - let fileName = substitute(s:GetCurrentDepotFile(line(".")), '#\d\+$', '', - \ '') - let fileName = fileName . "#" . fileVer - endif - call genutils#RestoreHardPosition('Perforce') - call genutils#ResetHardPosition('Perforce') - endif - return fileName -endfunction -""" END: Filename handling }}} - -""" BEGIN: Buffer management, etc. {{{ -" Must be followed by a call to s:EndBufSetup() -function! s:StartBufSetup() - " If the command created a new window, then only do setup. - if !s:errCode - if s:NewWindowCreated() - if s:outputType == 1 - wincmd p - endif - - return 1 - endif - endif - return 0 -endfunction - -function! s:EndBufSetup() - if s:NewWindowCreated() - if s:outputType == 1 - wincmd p - endif - endif -endfunction - -" Goto/Open window for the current command. -" clearBuffer (number): -" 0 - clear with undo. -" 1 - clear with no undo. -" 2 - don't clear -function! s:GotoWindow(outputType, clearBuffer, p4OrgFileName, cmdCompleted) - let bufNr = genutils#FindBufferForName(s:p4WinName) - " NOTE: Precautionary measure to avoid accidentally matching an existing - " buffer and thus overwriting the contents. - if bufNr != -1 && getbufvar(bufNr, '&buftype') == '' - return s:BufConflictError(a:cmdCompleted) - endif - - " If there is a window for this buffer already, then we will just move - " cursor into it. - let curBufnr = bufnr('%') - let maxBufNr = bufnr('$') - let bufWinnr = bufwinnr(bufNr) - let nWindows = genutils#NumberOfWindows() - let _eventignore = &eventignore - try - "set eventignore=BufRead,BufReadPre,BufEnter,BufNewFile - set eventignore=all - if a:outputType == 1 " Preview - let alreadyOpen = 0 - try - wincmd P - " No exception, meaning preview window is already open. - if winnr() == bufWinnr - " The buffer is already visible in the preview window. We don't have - " to do anything in this case. - let alreadyOpen = 1 - endif - catch /^Vim\%((\a\+)\)\=:E441/ - " Ignore. - endtry - if !alreadyOpen - call s:EditP4WinName(1, nWindows) - wincmd P - endif - elseif bufWinnr != -1 - call genutils#MoveCursorToWindow(bufWinnr) - else - exec s:_('SplitCommand') - call s:EditP4WinName(0, nWindows) - endif - if s:errCode == 0 - " FIXME: If the name didn't originally match with a buffer, we expect - " the s:EditP4WinName() to create a new buffer, but there is a bug in - " Vim, that treats "..." in filenames as ".." resulting in multiple - " names matching the same buffer ( "p4 diff ../.../*.java" and - " "p4 submit ../.../*.java" e.g.). Though I worked around this - " particular bug by avoiding "..." in filenames, this is a good check - " in any case. - if bufNr == -1 && bufnr('%') <= maxBufNr - return s:BufConflictError(a:cmdCompleted) - endif - " For navigation. - normal! mt - endif - catch /^Vim\%((\a\+)\)\=:E788/ " Happens during FileChangedRO. - return 788 " E788 - catch - return s:ShowVimError("Exception while opening new window.\n" . v:exception, - \ v:throwpoint) - finally - let &eventignore = _eventignore - endtry - " We now have a new window created, but may be with errors. - if s:errCode == 0 - setlocal noreadonly - setlocal modifiable - if s:commandMode ==# s:CM_RUN - if a:clearBuffer == 1 - call genutils#OptClearBuffer() - elseif a:clearBuffer == 0 - silent! 0,$delete _ - endif - endif - - let b:p4OrgFileName = a:p4OrgFileName - call s:PFSetupBuf(expand('%')) - else - " Window is created but with an error. We might actually miss the cases - " where a preview operation when the preview window is already open - " fails, and so no additional windows are created, but detecting such - " cases could be error prone, so it is better to leave the buffer in - " this case, rather than making a mistake. - if genutils#NumberOfWindows() > nWindows - if winbufnr(winnr()) == curBufnr " Error creating buffer itself. - close - elseif bufname('%') == s:p4WinName - " This should even close the window. - silent! exec "bwipeout " . bufnr('%') - endif - endif - endif - return 0 -endfunction - -function! s:BufConflictError(cmdCompleted) - return s:ShowVimError('This perforce command resulted in matching an '. - \ 'existing buffer. To prevent any demage this could cause '. - \ 'the command will be aborted at this point.'. - \ (a:cmdCompleted ? ("\nHowever the command completed ". - \ (s:errCode ? 'un' : ''). 'successfully.') : ''), '') -endfunction - -function! s:EditP4WinName(preview, nWindows) - let fatal = 0 - let bug = 0 - let exception = '' - let pWindowWasOpen = (genutils#GetPreviewWinnr() != -1) - " Some patterns can cause problems. - let _wildignore = &wildignore - try - set wildignore= - exec (a:preview?'p':'').'edit' s:p4WinName - catch /^Vim\%((\a\+)\)\=:E303/ - " This is a non-fatal error. - let bug = 1 | let exception = v:exception - let stack = v:throwpoint - catch /^Vim\%((\a\+)\)\=:\%(E77\|E480\)/ - let bug = 1 | let exception = v:exception | let fatal = 1 - let stack = v:throwpoint - catch - let exception = v:exception | let fatal = 1 - let stack = v:throwpoint - finally - let &wildignore = _wildignore - endtry - if fatal - call s:ShowVimError(exception, '') - endif - if bug - echohl ERROR - echomsg "Please report this error message:" - echomsg "\t".exception - echomsg - echomsg "with the following information:" - echomsg "\ts:p4WinName:" s:p4WinName - echomsg "\tCurrent stack:" stack - echohl NONE - endif - " For non preview operation, or for preview window operation when the preview - " window is not already visible, we expect the number of windows to go up. - if !a:preview || (a:preview && !pWindowWasOpen) - if a:nWindows >= genutils#NumberOfWindows() - let s:errCode = 1 - endif - endif -endfunction - -function! s:MakeWindowName(...) - " Let only the options that are explicitly specified appear in the window - " name. - if a:0 > 0 - let cmdStr = a:1 - else - let cmdStr = 'p4 '.join(s:MakeP4ArgList(s:p4Options, 0), ' ') - endif - let winName = cmdStr - "let winName = genutils#DeEscape(winName) - " HACK: Work-around for some weird handling of buffer names that have "..." - " (the perforce wildcard) at the end of the filename or in the middle - " followed by a space. The autocommand is not getting triggered to clean - " the buffer. If we append another character to this, I observed that the - " autocommand gets triggered. Using "/" instead of "'" would probably be - " more appropriate, but this is causing unexpected FileChangedShell - " autocommands on certain filenames (try "PF submit ../..." e.g.). There - " is also another issue with "..." (anywhere) getting treated as ".." - " resulting in two names matching the same buffer( - " "p4 diff ../.../*.java" and "p4 submit ../.../*.java" e.g.). This - " could also change the name of the buffer during the :cd operations - " (though applies only to spec buffers). - "let winName = substitute(winName, '\.\.\%( \|$\)\@=', '&/', 'g') - "let winName = substitute(winName, '\.\.\%( \|$\)\@=', "&'", 'g') - let winName = substitute(winName, '\.\.\.', '..,', 'g') - " The intention is to do the substitute only on systems like windoze that - " don't allow all characters in the filename, but I can't generalize it - " enough, so as a workaround I a just assuming any system supporting - " 'shellslash' option to be a windoze like system. In addition, cygwin - " vim thinks that it is on Unix and tries to allow all characters, but - " since the underlying OS doesn't support it, we need the same treatment - " here also. - if exists('+shellslash') || has('win32unix') - " Some characters are not allowed in a filename on windows so substitute - " them with something else. - let winName = substitute(winName, s:specialChars, - \ '\="[" . s:specialCharsMap[submatch(1)] . "]"', 'g') - "let winName = substitute(winName, s:specialChars, '\\\1', 'g') - endif - " Finally escape some characters again. - let winName = genutils#Escape(winName, " #%\t") - if ! exists('+shellslash') " Assuming UNIX environment. - let winName = substitute(winName, '\\\@<!\(\%(\\\\\)*\\[^ ]\)', '\\\1', 'g') - let winName = escape(winName, "'~$`{\"") - endif - return winName -endfunction - -function! s:PFSetupBuf(bufName) - call genutils#SetupScratchBuffer() - let &l:bufhidden=s:_('BufHidden') -endfunction - -function! s:PFSetupForSpec() - setlocal modifiable - setlocal buftype= - exec 'aug Perforce'.bufnr('%') - au! - au BufWriteCmd <buffer> nested :W - aug END -endfunction - -function! perforce#WipeoutP4Buffers(...) - let testMode = 1 - if a:0 > 0 && a:1 ==# '++y' - let testMode = 0 - endif - let i = 1 - let lastBuf = bufnr('$') - let cleanedBufs = '' - while i <= lastBuf - if bufexists(i) && expand('#'.i) =~# '\<p4 ' && bufwinnr(i) == -1 - if testMode - let cleanedBufs = cleanedBufs . ', ' . expand('#'.i) - else - silent! exec 'bwipeout' i - let cleanedBufs = cleanedBufs + 1 - endif - endif - let i = i + 1 - endwhile - if testMode - echo "Buffers that will be wipedout (Use ++y to perform action):" . - \ cleanedBufs - else - echo "Total Perforce buffers wipedout (start with 'p4 '): " . cleanedBufs - endif -endfunction - -function! perforce#PFRefreshActivePane() - if exists("b:p4UserArgs") - call genutils#SaveSoftPosition('Perforce') - - try - silent! undo - call call('perforce#PFrangeIF', b:p4UserArgs) - catch - call s:ShowVimError(v:exception, v:throwpoint) - endtry - - call genutils#RestoreSoftPosition('Perforce') - call genutils#ResetSoftPosition('Perforce') - endif -endfunction -""" END: Buffer management, etc. }}} - -""" BEGIN: Testing {{{ -" Ex: PFTestCmdParse -c client -u user integrate -b branch -s source target1 target2 -command! -nargs=* -range=% -complete=file PFTestCmdParse - \ :call <SID>TestParseOptions(<f-args>) -function! s:TestParseOptions(commandName, ...) range - call call('s:ParseOptionsIF', [a:firstline, a:lastline, 0, 0, a:commandName]+ - \ a:000) - call s:DebugP4Status() -endfunction - -function! s:DebugP4Status() - echo "p4Options :" . join(s:p4Options, ' ') . ":" - echo "p4Command :" . s:p4Command . ":" - echo "p4CmdOptions :" . join(s:p4CmdOptions, ' ') . ":" - echo "p4Arguments :" . join(s:p4Arguments, ' ') . ":" - echo "p4Pipe :" . join(s:p4Pipe, ' ') . ":" - echo "p4WinName :" . s:p4WinName . ":" - echo "outputType :" . s:outputType . ":" - echo "errCode :" . s:errCode . ":" - echo "commandMode :" . s:commandMode . ":" - echo "filterRange :" . s:filterRange . ":" - echo "Cmd :" . s:CreateFullCmd(s:MakeP4ArgList([''], 0)) . ":" -endfunction - -"function! s:TestPushPopContexts() -" let s:p4Options = ["options1"] -" let s:p4Command = "command1" -" let s:p4CmdOptions = ["cmdOptions1"] -" let s:p4Arguments = ["arguments1"] -" let s:p4WinName = "winname1" -" call s:PushP4Context() -" -" let s:p4Options = ["options2"] -" let s:p4Command = "command2" -" let s:p4CmdOptions = ["cmdOptions2"] -" let s:p4Arguments = ["arguments2"] -" let s:p4WinName = "winname2" -" call s:PushP4Context() -" -" call s:ResetP4ContextVars() -" echo "After reset: " . s:CreateFullCmd(s:MakeP4ArgList([''], 0)) -" call s:PopP4Context() -" echo "After pop1: " . s:CreateFullCmd(s:MakeP4ArgList([''], 0)) -" call s:PopP4Context() -" echo "After pop2: " . s:CreateFullCmd(s:MakeP4ArgList([''], 0)) -"endfunction - -""" END: Testing }}} - -""" BEGIN: Experimental API {{{ - -function! perforce#PFGet(var) - return {a:var} -endfunction - -function! perforce#PFSet(var, val) - let {a:var} = a:val -endfunction - -function! perforce#PFCall(func, ...) - let result = call(a:func, a:000) - return result -endfunction - -function! perforce#PFEval(expr) - exec "let result = ".a:expr - return result -endfunction - -""" END: Experimental API }}} - -function! perforce#Initialize(initMenu) " {{{ - -" User Options {{{ - -if g:p4ClientRoot != '' - let g:p4ClientRoot = genutils#CleanupFileName(g:p4ClientRoot) -endif -if type(g:p4DefaultListSize) == 0 - let g:p4DefaultListSize = string(g:p4DefaultListSize) -endif -if g:p4FileLauncher == '' && genutils#OnMS() - let g:p4FileLauncher = "start rundll32 SHELL32.DLL,ShellExec_RunDLL" -endif -if g:p4DefaultPreset != -1 && - \ g:p4DefaultPreset.'' !~# s:EMPTY_STR - call perforce#PFSwitch(1, g:p4DefaultPreset) -endif - - -" Assume the user already has the preferred rulerformat set (which is anyway -" going to be done through the .vimrc file which should have been sourced by -" now). -if g:p4EnableRuler - " Take care of rerunning this code, as the reinitialization can happen any - " time. - if !exists("s:orgRulerFormat") - let s:orgRulerFormat = &rulerformat - else - let &rulerformat = s:orgRulerFormat - endif - - if &rulerformat != "" - if match(&rulerformat, '^%\d\+') == 0 - let orgWidth = substitute(&rulerformat, '^%\(\d\+\)(.*$', - \ '\1', '') - let orgRuler = substitute(&rulerformat, '^%\d\+(\(.*\)%)$', '\1', '') - else - let orgWidth = strlen(&rulerformat) " Approximate. - let orgRuler = &rulerformat - endif - else - let orgWidth = 20 - let orgRuler = '%l,%c%V%=%5(%p%%%)' - endif - let &rulerformat = '%' . (orgWidth + g:p4RulerWidth) . '(%{' . - \ 'perforce#RulerStatus()}%=' . orgRuler . '%)' -else - if exists("s:orgRulerFormat") - let &rulerformat = s:orgRulerFormat - else - set rulerformat& - endif -endif - -aug P4Active - au! - if g:p4EnableActiveStatus - au BufRead * call perforce#GetFileStatus(expand('<abuf>') + 0, 0) - endif -aug END - -" User Options }}} - -if a:initMenu -runtime! perforce/perforcemenu.vim -let v:errmsg = '' -endif - -let g:p4PromptToCheckout = ! g:p4PromptToCheckout -call perforce#ToggleCheckOutPrompt(0) - -endfunction " s:Initialize }}} - -""" END: Infrastructure }}} - -" Do some initializations. -if g:p4DefaultPreset != -1 && - \ g:p4DefaultPreset.'' !~# s:EMPTY_STR - call perforce#PFSwitch(0, g:p4DefaultPreset) -endif - -aug P4ClientRoot - au! - if g:p4ClientRoot =~# s:EMPTY_STR || s:p4Client =~# s:EMPTY_STR || - \ s:p4User =~# s:EMPTY_STR - if s:_('EnableActiveStatus') - " If Vim is still starting up (construct suggested by Eric Arnold). - if bufnr("$") == 1 && !bufloaded(1) - au VimEnter * call <SID>GetClientInfo() | au! P4ClientRoot - else - call s:GetClientInfo() - endif - else - let g:p4ClientRoot = fnamemodify(".", ":p") - endif - endif -aug END - -call perforce#Initialize(0) - -" WORKAROUND for :redir broken, when called from completion function... just -" make sure this is initialized early. -call genutils#MakeArgumentString() - -" Restore cpo. -let &cpo = s:save_cpo -unlet s:save_cpo - -" vim6:fdm=marker et sw=2 diff --git a/.vim/autoload/perforceutils.vim b/.vim/autoload/perforceutils.vim deleted file mode 100755 index 2009413..0000000 --- a/.vim/autoload/perforceutils.vim +++ /dev/null @@ -1,260 +0,0 @@ -" perforceutils.vim: Please see perforce/perforceutils.vim - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - -" Determine the script id. -function! s:MyScriptId() - map <SID>xx <SID>xx - let s:sid = maparg("<SID>xx") - unmap <SID>xx - return substitute(s:sid, "xx$", "", "") -endfunction -let s:myScriptId = s:MyScriptId() -delfunction s:MyScriptId " This is not needed anymore. - -" CAUTION: Don't assume the existence of plugin/perforce.vim (or any other -" plugins) at the time this file is sourced. - -" DiffLink {{{ - -" Open the source line for the current line from the diff. -function! perforceutils#DiffOpenSrc(preview) " {{{ - let s:EMPTY_STR = perforce#PFEval('s:EMPTY_STR') - if perforce#PFEval('s:GetCurrentItem()') !~# s:EMPTY_STR - PItemOpen - endif - call genutils#SaveHardPosition('DiffOpenSrc') - " Move to the end of next line (if possible), so that the search will work - " correctly when the cursor is ON the header (should find the current line). - normal $ - let filePat = '\zs[^#]\+\%(#\d\+\)\=\ze\%( ([^)]\+)\)\=' - let diffHdr = '^diff \%(-\S\+\s\+\)*' - " Search backwards to find the header for this diff (could contain two - " depot files or one depot file with or without a local file). - if search('^==== '.filePat.'\%( - '.filePat.'\)\= ====', 'bW') - let firstFile = matchstr(getline('.'), '^==== \zs'.filePat. - \ '\%( - \| ====\)') - let secondFile = matchstr(getline('.'), ' - '.filePat.' ====', - \ strlen(firstFile)+5) - let foundHeader = 1 - - " GNU diff header. - elseif search('^--- '.filePat.'.*\n\_^+++ '.filePat, 'bW') - let firstFile = matchstr(getline(line('.')-1), '^--- \zs.\{-}\ze\t') - let secondFile = matchstr(getline('.'), '^+++ \zs.\{-}\ze\t') - let foundHeader = 1 - - " Another GNU diff header, for default output (typically for -r option). - elseif search(diffHdr.filePat.' '.filePat, 'bW') - exec substitute(substitute(getline('.'), - \ diffHdr.'\('.filePat.'\) \('.filePat.'\)', - \ ":::let firstFile = '\\1' | let secondFile = '\\2'", ''), - \ '^.*:::', '', '') - let foundHeader = 1 - else - let foundHeader = 0 - endif - if foundHeader - call genutils#RestoreHardPosition('DiffOpenSrc') - if firstFile =~# s:EMPTY_STR - return - elseif secondFile =~# s:EMPTY_STR - " When there is only one file, then it is treated as the secondFile. - let secondFile = firstFile - let firstFile = '' - endif - - " Search for the start of the diff segment. We could be in default, - " context or unified mode. Determine context, stLine and offset. - if search('^\d\+\%(,\d\+\)\=[adc]\d\+\%(,\d\+\)\=$', 'bW') " default. - let segStLine = line('.') - let segHeader = getline('.') - call genutils#RestoreHardPosition('DiffOpenSrc') - let context = 'depot' - let regPre = '^' - if getline('.') =~# '^>' - let context = 'local' - let regPre = '[cad]' - if search('^---$', 'bW') && line('.') > segStLine - let segStLine = line('.') - endif - endif - let stLine = matchstr(segHeader, regPre.'\zs\d\+\ze') - call genutils#RestoreHardPosition('DiffOpenSrc') - let offset = line('.') - segStLine - 1 - elseif search('\([*-]\)\1\1 \d\+,\d\+ \1\{4}', 'bW') " context. - if getline('.') =~# '^-' - let context = 'local' - else - let context = 'depot' - endif - let stLine = matchstr(getline('.'), '^[*-]\{3} \zs\d\+\ze,') - let segStLine = line('.') - call genutils#RestoreHardPosition('DiffOpenSrc') - let offset = line('.') - segStLine - 1 - elseif search('^@@ -\=\d\+,\d\+ +\=\d\+,\d\+ @@$', 'bW') " unified - let segStLine = line('.') - let segHeader = getline('.') - call genutils#RestoreHardPosition('DiffOpenSrc') - let context = 'local' - let sign = '+' - if getline('.') =~# '^-' - let context = 'depot' - let sign = '-' - endif - let stLine = matchstr(segHeader, ' '.sign.'\zs\d\+\ze,\d\+') - let _ma = &l:modifiable - try - setl modifiable - " Count the number of lines that come from the other side (those lines - " that start with an opposite sign). - let _ss = @/ | let @/ = '^'.substitute('-+', sign, '', '') | - \ let offOffset = matchstr(genutils#GetVimCmdOutput( segStLine.',.s//&/'), - \ '\d\+\ze substitutions\? on \d\+ lines\?') + 0 | let @/ = _ss - if offOffset > 0 - silent! undo - call genutils#RestoreHardPosition('DiffOpenSrc') - endif - let offset = line('.') - segStLine - 1 - offOffset - finally - let &l:modifiable = _ma - endtry - else " Not inside a diff context, just use 1. - let context = 'local' - let stLine = 1 - let offset = 0 - endif - - try - if context ==# 'depot' && firstFile =~# s:EMPTY_STR - " Assume previous revision as the "before" file if none specified. - if perforce#PFCall('s:IsDepotPath', secondFile) && secondFile =~# '#\d\+' - let depotRev = s:GetFileRevision(secondFile) - if depotRev == '' - return - endif - let firstFile = substitute(secondFile, '#\d\+', '', '').'#'.(depotRev-1) - else - return - endif - endif - if context ==# 'local' - let file = secondFile - else - let file = firstFile - endif - " If the path refers to a depot file, check if the local file is currently - " open in Vim and if so has the same version number as the depot file. - if context ==# 'local' && perforce#PFCall('s:IsDepotPath', file) - let localFile = perforce#PFCall('s:ConvertToLocalPath', file) - let bufNr = bufnr(localFile) + 0 - if bufNr != -1 - let haveRev = getbufvar(bufNr, 'p4HaveRev') - let depotRev = s:GetFileRevision(file) - if haveRev == depotRev - let file = localFile - endif - " else " We could also try to run 'fstat' command and open up the file. - endif - endif - if perforce#PFCall('s:IsDepotPath', file) - let refresh = perforce#PFGet('s:refreshWindowsAlways') - try - call perforce#PFSet('s:refreshWindowsAlways', 0) - call perforce#PFIF(1, a:preview, 'print', file) - finally - call perforce#PFSet('s:refreshWindowsAlways', refresh) - endtry - let offset = offset + 1 " For print header. - else - call perforce#PFCall('s:OpenFile', 1, a:preview, genutils#CleanupFileName(file)) - endif - if perforce#PFEval('s:errCode') == 0 - if a:preview - wincmd P - endif - mark ' - exec (stLine + offset) - if a:preview - " Also works as a work-around for the buffer not getting scrolled. - normal! z. - wincmd p - endif - endif - catch - call perforce#PFCall('s:EchoMessage', v:exception, 'Error') - endtry - endif -endfunction " }}} - -function! perforceutils#SetupDiffLink() - command! -buffer -nargs=0 PDiffLink :PFDiffLink - command! -buffer -nargs=0 PDiffPLink :PFDiffPLink - nnoremap <buffer> <silent> O :PDiffLink<CR> - nnoremap <buffer> <silent> <CR> :PDiffPLink<CR> -endfunction - -function! s:GetFileRevision(depotPath) - let rev = matchstr(a:depotPath, '#\zs\d\+$') - return (rev !~# s:EMPTY_STR) ? rev + 0 : '' -endfunction - -" DiffLink }}} - -" ShowConflicts {{{ -function! perforceutils#ShowConflicts() - let _splitright = &splitright - set splitright - try - let curFile = expand('%:p') - "exec 'split' curFile.'.Original' - exec 'edit' curFile.'.Original' - silent! exec 'read' curFile - silent! 1delete _ - call genutils#SilentSubstitute('^==== THEIRS \_.\{-}\%(^<<<<$\)\@=', '%s///e') - call genutils#SilentDelete('\%(^>>>> ORIGINAL \|^==== THEIRS\|^==== YOURS \|^<<<<$\)') - call genutils#SetupScratchBuffer() - setlocal nomodifiable - diffthis - - exec 'vsplit' curFile.'.Theirs' - silent! exec 'read' curFile - 1delete _ - call genutils#SilentSubstitute('^>>>> ORIGINAL \_.\{-}\%(^==== THEIRS \)\@=', '%s///e') - call genutils#SilentSubstitute('^==== YOURS \_.\{-}\%(^<<<<$\)\@=', '%s///e') - call genutils#SilentDelete('\%(^>>>> ORIGINAL \|^==== THEIRS\|^==== YOURS \|^<<<<$\)') - call genutils#SetupScratchBuffer() - setlocal nomodifiable - diffthis - - exec 'vsplit' curFile.'.Yours' - silent! exec 'read' curFile - 1delete _ - call genutils#SilentSubstitute('^>>>> ORIGINAL \_.\{-}\%(^==== YOURS \)\@=', '%s///e') - call genutils#SilentDelete('\%(^>>>> ORIGINAL \|^==== THEIRS\|^==== YOURS \|^<<<<$\)') - call genutils#SetupScratchBuffer() - setlocal buftype= - setlocal nomodified - exec "au Perforce BufWriteCmd <buffer> :call <SID>SaveYours('".curFile."')" - diffthis - finally - let &splitright = _splitright - endtry -endfunction - -function! s:SaveYours(orgFile) - if confirm('Do you want to accept the changes in "'.expand("%:p:t").'"?', - \ "&Yes\n&No", 2, "Question") == 1 - exec 'w!' a:orgFile - endif -endfunction -" ShowConflicts }}} - -" Restore cpo. -let &cpo = s:save_cpo -unlet s:save_cpo - -" vim6:fdm=marker et sw=2 diff --git a/.vim/doc/perforce.txt b/.vim/doc/perforce.txt deleted file mode 100755 index 32d6985..0000000 --- a/.vim/doc/perforce.txt +++ /dev/null @@ -1,2441 +0,0 @@ -*perforce.txt* A feature Rich Perforce SCM Integration for Vim. - Requires Vim 6.0 - Last Change: 01-Sep-2006 @ 16:54 - Since Version: 1.4 - Revision: 1.3.0 - Plugin Version: 4.1 - Author: Hari Krishna Dara (hari_vim at yahoo dot com) - - *perforce-introduction* - *perforce-plugin* -This is a fairly complete integration with the perforce version control system -for the most commonly used operations, including many administrative commands. -It includes a great menu that is modelled very close to the p4win (the perforce -GUI client) and is quite extensive. - -============================================================================== -OVERVIEW *perforce-overview* - -|perforce-installation| How to install the plugin. - -|perforce-filetype| Perforce filetype plugin and setting it up for p4. - -|perforce-settings| An explanation of how to configure the plugin, for - both the perforce related parameters and the plugin - customizations, such as enabling menu. - -|perforce-ruler| Setting up the ruler to show an active status of the - file. - -|perforce-syntax| Perforce syntax plugin. - -|perforce-help| Browse the p4 help conveniently from within vim. - -|perforce-reinitialize| Describes how to reinitialize the plugin to load the - latest settings from the environment without - restarting vim. - -|perforce-commands| A description of various commands that can be - issued on Vim command-line. - -|perforce-revisions| Specifying perforce revisions conveniently. - -|perforce-interactive-commands| - How to execute interactive perforce commands. - -|perforce-forms| How to edit the perforce forms (specifications) from - within vim. - -|perforce-submit| Special handling of submit command. - -|perforce-list-commands| Commands that can be used in a list of items window. - -|perforce-extensions| Some useful extensions in the form of new options - and commands. - -|perforce-misc-commands| Some additional useful commands. - -|perforce-special-commands| Some useful commands and mappings. - -|perforce-utils| Additional utilties (perforce/perforceutils.vim). - -|perforce-API| New API provided by the plugin (experimental). - -|perforce-tips| Some useful tips. - -|perforce-limitations| Current limitations of the plugin. - -|perforce-troubleshooting| Some notes how to trouble shoot problems. - -|perforce-changes| A change list for current version from previous - versions. - -|perforce-known-issues| A list of known bugs. - -|perforce-wishlist| Wishlist items that may be worth doing for a future - version. - -|perforce-bugreporting| Reporting bugs. - -|perforce-acknowledgements| Acknowledgements. - -============================================================================== - - *perforce-installation* - -To install, place the perforce.vim script in one of the runtime plugin -directories along with the genutils.vim scripts that it depends on. This -typically is .vim/plugin or vimfiles/plugin directory under your home directory. -To get the latest versions of these plugins, goto the following webplages: - perforce.vim: http://www.vim.org/script.php?script_id=240 - genutils.vim: http://www.vim.org/script.php?script_id=197 - -The distribution contains the following files: - - plugin/perforce.vim - - Thin interface to the plugin (autoload/perforce.vim). - - autoload/perforce.vim - - The perforce plugin itself loaded on demand. - - ftplugin/perforce.vim - - The perforce filetype plugin file. See below on how to configure the - perforce filetype. - - syntax/perforce.vim. - - Syntax definition file for perforce forms. - - doc/perforce.txt. - - The online help file (this file). - - perforce/perforcemenu.vim. - - Additional module to install and configure a menu for the plugin. - See |perforce-menu|. - - perforce/perforcebugrep.vim. - - An utility script that can be used to generate useful information - while sending bugreports about the plugin. See - |perforce-bugreporting|. - - perforce/perforceutils.vim. - - Thin interface to autoload/perforceutils.vim - - autoload/perforceutils.vim - - Additional misc. utilities loaded on demand. - -If you obtained the plugin as a zip archive, - - Just extract it in your runtime directory. - - Start a new instance or go to an existing instance of vim. - - Execute: -> - :helpt <your runtime directory>/doc -< - This should generate the help tags for the perforce plugin help. - - Setup perforce filetype as described in |perforce-filetype| section. - - Make sure p4 command is in your path or set |p4CmdPath| property. - - Set the |p4ClientRoot| property and additionally any other - |perforce-settings| that you like. - - Optionally set 'cmdheight' property to at least 2 to avoid seeing the more - prompt for most of the messages the plugin gives. - - The plugin requires that you have Vim 7.0 version installed. - - If you want to enable the perforceutils.vim plugin, add the following line - to your vimrc: -> - runtime perforce/perforceutils.vim -< - - If you want to enable the menu, add the following line to your vimrc, at - the end of perforce configuration lines: -> - runtime perforce/perforcemenu.vim -< - - The core of the plugin is autoloaded by Vim the first time a perforce - command needs to be executed. This improves the startup time of Vim - considerably in some situations. If you want the plugin to be loaded - immediately, you can force an autoload by adding the following command to - your vimrc: -> - PFIntialize -< - -Note: It is important to make sure your 'shellredir' properly set such that, vim -captures both the standard output and standard error messages from the external -perforce command. If this is not correctly set, the plugin will not be able to -show the error messages generated by p4 command to you. - -Also note that on Windows, if you use a UNIX like shell for your 'shell' -setting, the plugin will not work correctly unless the 'shellslash' option is -set. - - *loaded_perforce* -Later, if you need to temporarily disable the plugin without needing to remove -the files, you can set the loaded_perforce variable in your vimrc. You can also -set the no_perforce_maps to disable just the mappings defined in this plugin or -no_plugin_maps to disable mappings in all the plugins (provided they all honor -this setting), in your vimrc. -============================================================================== - - *perforce-filetype* - *perforce-ftplugin* -The package comes with a perforce ftplugin (|filetype-plugin|) which sets a -few text mode options suitable for editing the forms and a syntax plugin to -colorize the spec files. The ftplugin also positions the cursor at the -appropriate line based on the type of spec you are editing. When you open -perforce forms from within vim using |perforce-interactive-commands|, you -don't have to do anything special for this to work, but if you want the same -to work while editing forms using p4 command directly, then you need to add -the following lines in your scripts.vim: -> - if getline(1) =~ '^# A Perforce ' - setfiletype perforce - endif -< -If you do not have this file already, then you need to create it under -vimfiles or .vim directory (or anywhere in your 'rtp'). For details see help -on |new-filetype-scripts|. Note that you also need to enable filetype plugins -for this to work, see |filetype-plugin| for more information. - -============================================================================== - - *perforce-settings* - *perforce-customizing* -The plugin allows a lot of customization by reading some global variables. You -can define a set of global variables in your startup script (.vimrc/_vimrc) and -they are automatically read by the plugin during the Vim startup and are used -for customizing the behavior. - -Note that all the setting names are case sensitive and the boolean settings can -be set to the value 0 to disable and any non-zero number (for the matter of -fact, any string will also do) to enable. All the settings can be changed at -runtime without restarting vim; see |perforce-reinitialize|. - -The settings can also be changed at runtime, see |perforce-reinitialize|. - -Here is a list of all the options: - |p4CmdPath|, |p4DefaultPreset|, |p4DefaultOptions|, |p4ClientRoot|, - |p4EnableRuler|, |p4RulerWidth|, |p4EnableActiveStatus|, - |p4ASIgnoreDefPattern|, |p4ASIgnoreUsrPattern|, |p4OptimizeActiveStatus|, - |p4UseGUIDialogs|, |p4PromptToCheckout|, |p4DefaultListSize|, - |p4DefaultDiffOptions|, |p4EnableMenu|, |p4UseExpandedMenu|, - |p4EnablePopupMenu|, |p4UseExpandedPopupMenu|, |p4Presets|, - |p4MaxLinesInDialog|, |p4CheckOutDefault|, |p4SortSettings|, |p4TempDir|, - |p4SplitCommand|, |p4UseVimDiff2|, |p4EnableFileChangedShell|, - |p4HideOnBufHidden|, |p4Depot|, |p4Autoread|, |p4FileLauncher|, - |p4CurPresetExpr|, |p4CurDirExpr|, |p4UseClientViewMap| - - *perforce-command-path* - *p4CmdPath* -The plugin executes the external p4 command for all its operations. By default -the command is found in the PATH, but if it doesn't exist in the path you can -still specify the location by using the p4CmdPath variable. -> - :let g:p4CmdPath = '<path_to_p4_command>' -< - Example: > - :let g:p4CmdPath = '~/bin/perforce/bin/p4' -< - *perforce-presets* - *p4Presets* -This is a useful setting when you work with multiple perforce installations at -the same time. This allows you to predefine a set of configurations that you -can switch between without needing to restart vim or manually enter the -details while using the |PFSwitch| command. Set this variable in your vimrc -with a comma separated list of settings. Each setting should be of -the form (separated with one or more spaces): -> - <port> <client> <user> -< -You can include as many of these specifications as you want, just separate them -with commas. -> - :let g:p4Presets = 'port1 client1 user1,port2 client2 user2' -< -Once set, you can use the |PFSwitch| command in one of three ways to choose the -setting. - - 1. If you know the index of the setting to which you want to - switch to (starting with 0), just pass that as an argument to the - command as -> - " Switch to the third setting. - :PFSwitch 2 -< - 2. If you don't know the index, just invoke the command without any - arguments. You will be prompted to enter the index after displaying - a list of available settings. - - 3. If you have expanded menu enabled (see |p4UseExpandedMenu| or - |p4UseExpandedPopupMenu|), then you can choose the desired setting - to switch to using the "Settings" sub-menu under "Perforce" group. - - *perforce-P4CONFIG* - *P4CONFIG* -As a special case, you can have one of the specifications as "P4CONFIG", -allowing you to switch to the P4CONFIG feature of external p4 command -interactively, see |perforce-dynamic-client|. -> - :let g:p4Presets = 'p1 c1 u1,P4CONFIG,p2 c2 u2' -< -Setting port field to "P4CONFIG" also has the same effect. This results in -plugin not passing the options for port, client and user explicitly such that p4 -can determine them based on the P4CONFIG file. However you can still override -them by explicitly specifying the corresponding option to PF command. - - *p4DefaultPreset* -If you don't have the P4CLIENT, P4USER and P4PORT environment variables set, you -can use this setting to initialize the plugin with corresponding values. The -format for the value is exactly same as a single entry in |p4Presets| setting. -In fact, you can also set this to an index in the |p4Presets|. -> - :let g:p4DefaultPreset = '<your_perforce_port> <your_perforce_client_name> <your_perforce_user_name>' -< - Example: > - :let g:p4DefaultPreset = 'localhost:1666 hari_client hari' - :let g:p4DefaultPreset = 2 " Start with the second setting in p4Presets. -< -Note that the plugin automatically chooses some defaults for the above based on -your environment, if you don't explicitly set them in your startup script. - - *perforce-default-options* - *perforce-common-options* - *p4DefaultOptions* -If you need to pass in additional arguments every time the external p4 command -is run, you can use the following setting. The arguments are passed to p4 -literally. For the set of options that you can specify here, see perforce help -for "usage" (use ":PH usage" command, see |perforce-help|) -> - :let g:p4DefaultOptions = '<default_options_to_p4>' -< - Example: > - :let g:p4DefaultOptions = '-H hkrishna' -< - *perforce-buffer-local-options* -In addition you can also use the buffer local variables "b:p4Options", -"b:p4Client", "b:p4User", "b:p4Port" and "b:clientRoot" to override the global -options (see ":PH usage" for option list) at a buffer level. The plugin -automatically sets these options whenever you create a new perforce result -window such that any future commands originating from the same window -automatically inherit them. This is especially useful when you temporarily -switch to a different client/user by providing one at command-line, and later do -more operations on the results (provided the given client/user is valid on the -current m/c). > - - :PF -c hari_tmp opened - :PFileDiff -> -The PFileDiff will automatically use the "hari_tmp" client as b:p4Client is set -to that value. You can also use b:p4Options to set any option that is accepted -in the global options section of PF command (see |perforce-global-options|), -however for the client view mapping to work correctly, you need to have -b:p4Client and b:clientRoot set. > - - :let b:p4Options = '-H my_host' -< -All commands executed when this buffer is active will automatically inherit -these global options. - -NOTE: Currently the b:clientRoot variable needs to be set manually. - - *perforce-client-root* - *p4ClientRoot* -The client root is required for certain commands (it is same as what you -specify in the Root: property in the client settings), so if not specified and -if the |p4EnableActiveStatus| setting is enabled, the plugin will run the "p4 -info" command to read the client root setting from the perforce server. But -this will introduce a short delay in autoload time (especially if you are -talking to a perforce server that is installed out side your network). To avoid -this, use the following setting to specify the client root. -> - :let g:p4ClientRoot = '<client_root_directory>' -< - Example: > - :let g:p4ClientRoot = 'c:/dev' -< -If |p4EnableActiveStatus| is disabled, the current directory is used as the -default. - - *perforce-gui-dialogs* - *p4UseGUIDialogs* -By default the plugin uses console dialogs for some of the prompts. This is -convenient as you can then use the input-history and expression register -|quote=|. But if you like, you can enable this setting to force using GUI -dialogs for all the prompts. -> - :let g:p4UseGUIDialogs = 1 -< - - *perforce-automatic-checkout* - *p4PromptToCheckout* -The plugin by default prompts you to checkout, when you start editing a -readonly file under the client root. You can disable this behavior by using the -following setting: -> - :let g:p4PromptToCheckout = 0 -< -Note that you can still manually checkout (or edit) the file even when this -option is disabled by using "PE" or "PF edit" command. - -When the checkout prompt is given, you have the option saying Yes, No or Cancel. -When accidental changes to the buffer bring up the checkout prompt, you can -select Cancel to revert the state of the buffer as much as possible (you may -still have to press <Esc> sometimes). One advantage of selecting Cancel in these -cases is that the next time you start making a genuine change, you will get the -checkout prompt as expected (otherwise, you will only get this prompt once). - - *perforce-list-size* - *perforce-default-list-size* - *p4DefaultListSize* -When you execute "changes", "jobs" and "filelog" perforce commands, the number -of entries is limited to 100 to avoid generating a large volume of data. But you -can change the value to whatever you like: -> - :let g:p4DefaultListSize = 1000 -< -To disabling it completely (show the entire list) set it to a negative number: -> - :let g:p4DefaultListSize = -1 -< - - *perforce-default-diff-options* - *p4DefaultDiffOptions* -You can set the default diff options to be passed to all the "diff" and "diff2" -operations (both direct and indirect execution of these commands), by using the -following setting: -> - :let g:p4DefaultDiffOptions = '-dwbu5' -< -For the options that you can set here, see the help for "diff" or "diff2" by -running the "PH diff" or "PH diff2" command. - -Note, this setting can't be used to specify options to the external diff -program. - - *perforce-menu* - *p4EnableMenu* -The distribution comes with an additional module called perforcemenu.vim to -install a Perforce sub-menu on the main or PopUp menu. By default the menu is -not added as many people (including myself) don't use menus (I have the entire -menu bar disabled). Use the following setting to enable the Perforce sub-menu: -> - :let g:p4EnableMenu = 1 -< -The above setting will create a very basic menu with the most needed commands. -This makes it easy to use shortcut keys if you have the |winaltkeys| correctly -configured. To enable a more full featured menu, see |p4UseExpandedMenu|. - - *perforce-expanded-menu* - *p4UseExpandedMenu* -By default the |p4EnableMenu| option creates a full-featured menu that is -modelled closely after the p4Win utility, which comes with perforce. But you can -disable this and have only a basic menu with the most commonly used set of -commands (this was the default for older versions of the plugin). Use the -following setting in your startup script: -> - :let g:p4UseExpandedMenu = 0 -< -If you want a basic menu on the main menu (for the ease of using the shortcut -keys), then you can consider having the full-featured version on the popup -menu, see |p4EnablePopupMenu| and |p4UseExpandedPopupMenu| settings. - - *perforce-popup-menu* - *p4EnablePopupMenu* -This is similar to |p4EnableMenu| except that enabling this option, adds a -Perforce sub-menu on the PopUp menu instead of the main menu. -> - :let g:p4EnablePopupMenu = 1 -< - *perforce-expanded-popup-menu* - *p4UseExpandedPopupMenu* -This is similar to |p4UseExpandedMenu| except that enabling this option, adds a -more full-featured Perforce sub-menu on the PopUp menu. -> - :let g:p4UseExpandedPopupMenu = 1 -< - *loaded_perforcemenu* -Note: If you never use the menu features of the plugin, consider setting -"loaded_perforcemenu" to a non-zero value, to avoid getting this module sourced. - - *perforce-max-lines-in-dialog* - *p4MaxLinesInDialog* -Commands that use a dialog box to show the result (such as |PEdit|) assume -that the messages generated by the perforce command are only a few lines. But -depending on the arguments (e.g., "PEdit ..." and there are many files under -the current directory ...), there can be too many lines to display in a dialog -so the display mode is automatically switched to a new window instead of the -dialog. Though the default limit is 1, which helps to draw your attention for -the conditions that you normally expect a one line result (e.g., you checkout a -file and someone else already checked out the file), you can change it by -setting the following line: -> - :let g:p4MaxLinesInDialog = <number of lines> -< - Example: -> - :let g:p4MaxLinesInDialog = 5 -< - *p4CheckOutDefault* -When you start modifying a read-only file, the plugin prompts you to checkout -the file from perforce. Set this option to 1 to make the default option to -"Yes" and 2 for "No". The default is 2 to avoid accidentally checking out a -file. > - - :let g:p4CheckOutDefault = <option number> -< - Example: -> - :let g:p4CheckOutDefault = 1 -< - *p4SortSettings* -The |PFSettings| command by default sorts the setting so that they are in -alphabetical order. But this will alter the position of the settings as new -settings get added, so if you want them to always appear in the same familiar -order, then set this to 0 to disable sorting. > - - :let p4SortSettings = 0 -< - *p4TempDir* -This setting points to the directory which should be used by the plugin for -creating any temporary files. This setting is used for vdiff and vdiff2 -commands, but currently these commands don't really create any files on the -filesystem, as the directory is used to merely generate the filenames for -temporary files (the filename is still such that it is valid on the filesystem, -so that you can write the contents to it for any reason, but you will have to -reset the 'buftype' option first). But this may change in future when new -features/commands get added which require the temporary files to be on -filesystem. > - - :let p4TempDir = "c:/temp/vim-p4" -< - *p4SplitCommand* -When the plugin creates new windows as a result of issuing perforce commands, it -by default uses |:split| command, which creates a horizontally split window above -or below the current window depending on your 'splitbelow' setting. But if you -would like to change the way the windows are created, you can set this setting -to any split command that is valid (such as |:vsplit| or "topleft split"). For -all possible commands see |:vertical|. > - - :let p4SplitCommand = "vsplit" -< - *p4UseVimDiff2* -If this option is set, the plugin uses vdiff2 instead of diff2 in the filelog -window. See |perforce-vim-diff|. > - - :let p4UseVimDiff2 = 1 -< - *p4EnableFileChangedShell* -The plugin normally listens to the |FileChangedShell| events and refreshes the -ruler automatically (See |perforce-ruler|), keeping the status up to date. But -because of the way this event works, the plugin has to emulate the |timestamp| -warning messages that would be generated by Vim by default, when there is no -listener for this event. If you don't like this feature for any reason, you can -disable it by setting this option to 0. > - - :let p4EnableFileChangedShell = 0 -< -Note that the plugin no longer refreshes the ruler whenever vim detects that the -file has been modified externally requiring a reload of the buffer (and this -anyway happens only if the buffer is currently visible in a window, or if the -'hidden' option is set). To manually refresh the ruler see -|perforce-refresh-file-status|. - - *p4BufHidden* -This setting is useful if you do not normally set the 'hidden' option. The -plugin normally sets the 'bufhidden' option for the perforce plugins to the -value "wipe" such that they are automatically wiped out when they are unloaded. -This keeps your buffer list clean and also conserves the vim resources as you -can potentially end up creating a lot of buffers, one for each perforce command -that you execute from with in Vim. But this would prevent you from switching -back and forth between the perforce result buffers and other regular buffers. -If you often find yourself working with perforce windows for a long time, you -should consider setting this option to the value "hide" instead, avoiding unload -of the buffers when they are hidden. When you set this value, an interesting and -useful side effect is that you can use <C-O> and <Tab> to navigate the preview -window, which can be very useful while viewing the description of list items, -see |perforce-list-commands|. > - - :let g:p4BufHidden = 'hide' - -Note: You have three other alternatives to essentially get the same -functionality at different levels, avoiding the unload of the buffers: - - Set the 'hidden' global option to avoid unloading all buffers. This - essentially avoids unloading every buffer that is loaded/created in - Vim, not just perforce windows. - - Manually set 'bufhidden' local option to "hide" for any particular - perforce window that you are interested in keeping around. Once set, - this prevents the buffer from getting wipedout, until explicitly - requested to do so. > - - :setlocal bufhidden=hide -< - - Use the |:hide| command instead of quitting the buffer by other means, - such as the |:quit| command everytime. This again prevents the buffer - from getting unloaded even after it is hidden, but conveniently so - only when you use :hide command. If the buffer is later shown back - in another window and then hidden without having one of the other - settings appropriately set, then it will get unloaded and will get - wipedout. - -See |PFWipeoutBufs| command for a way to cleanup all the hidden perforce buffers -that get accumulated, when you use one of the above techniques. - -Note: There are other values that the 'bufhidden' can take, and so does the -g:p4BufHidden option, but they are not useful. They leave the perforce result -buffers lying around, without any useful side effect. - - *p4Depot* -The plugin at any time can operate only on one preset depot, which by default is -"depot". If your perforce server has multiple depots or if your depot name is -not "depot", then you can use this setting: -> - :let g:p4Depot = 'proj' -> -to switch to a different depot than "depot". You can also do this at any time by -using the |PFSettings| command interactively. - - *p4Autoread* -By default, the plugin automatically reloads the file that get externally -modified as a side effect of some perforce commands (such as get and edit), if -the buffer inside vim is not yet modified. But you can disable this feature by -using this setting: > - - :let g:p4Autoread = -1 -> -A value of -1 means, use the 'autoread' vim setting and a value of 0 means don't -autoread and a value of 1 means autoread (the default). - - *perforce-ruler* -The below are some additional settings that are related to configuring the -perforce ruler. - - *p4EnableRuler* -You can enable this setting to see additional information in the Vim ruler about -the current file's status. If the status for the current file doesn't exist yet, -nothing is shown. To make the status automatically available when you open a -file, you can enable the active status option, see |p4EnableActiveStatus|. You -can also manually obtain the status by executing the |PFRefreshFileStatus| -command any time. See |p4RulerWidth| on how to adjust the width of the ruler. By -default this setting is enabled, to disable it use, > - - :let g:p4EnableRuler = 0 -< -The plugin modifies the 'rulerformat' for this to work, so if you are also -modifying this, make sure you do it before the plugin gets loaded (doing it in -the vim startup file will ensure this.) - -Note that enabling this option alone is not sufficient, you should also have the -|p4EnableActiveStatus| setting enabled or use the |PFRefreshFileStatus| command. -Also see |p4OptimizeActiveStatus| setting. - - *perforce-ruler-width* - *p4RulerWidth* -By default the plugin uses an additional 25 columns to show the perforce file -status. You might want to increase this value if you have long client names in -your perforce setup: -> - :let g:p4RulerWidth = 50 -< - *perforce-active-status* - *p4EnableActiveStatus* -Enabling this option along with |p4EnableRuler| will provide you a quick look -at the current file's status in the perforce depot, as soon as it is opened. -By default this setting is enabled, but you can disable it if it introduces -significant delay for every file you open (as it involves running an external -command which in turn has to talk to a server). > - - :let g:p4EnableActiveStatus = 0 -< -If the response is slow and you would still like to have this feature, you can -disable this option and and use the |PFRefreshFileStatus| command, for whichever -file and whenever you want to see/update the ruler. - -Besides using the status for showing the ruler, if available, it is also used to -make better decisions during some perforce operations. - -Note, you need to still have the |p4EnableRuler| setting enabled to actually see -the status in the ruler. Also the default |p4OptimizeActiveStatus| setting -optimises it such that the "fstat" is done only the first time the file is -opened. - - *perforce-active-status-ignore-patterns* - *p4ASIgnoreDefPattern* - *p4ASIgnoreUsrPattern* -These are regular expression patterns matching the filenames for which the -active status should be ignored. If the current filename matches the default -ignore pattern or the user defined ignore pattern, then it is assumed that the -file doesn't exist in the depot and no fstat is done on it. By default the -user pattern is empty and the default pattern is set to all files under tmp -and temp sub-directories and any file with log, dif, diff, out, buf and bak as -extension (case insensitive), which is expressed by the following pattern: > - - '\c\%(\<t\%(e\)\?mp\/.*\|^.*\.tmp$\|^.*\.log$\|^.*\.diff\?$\|^.*\.out$\|' . - \ '^.*\.buf$\|^.*\.bak$\)\C' -< -To add additional patterns, the "p4ASIgnoreUsrPattern" should be used. The -"p4ASIgnoreDefPattern" can however be set to an empty value such that the -default pattern is completely ignored. Setting the default pattern to empty -string without defining the user pattern will completely disabled this feature, -resulting in a 'p4 fstat' call to every file that is opened (the file still -needs to be under the client root). - - *perforce-optimize-filestatus* - *p4OptimizeActiveStatus* -Enabling this option along with |p4EnableActiveStatus| and |p4EnableRuler| will -allow the plugin to determine a brief status of the file in perforce and show it -as part of the ruler, without loosing much of the responsiveness. When you -enable this option, the plugin determines the status only the first time you -open the file and any other time there is a possibility for change in the status -(after executing the |PEdit|, |PRevert| etc.) and when you manually ask the -plugin to update the status using the |PFRefreshFileStatus| command. By default, -this option is enabled, to disable it use, > - - :let g:p4OptimizeActiveStatus = 0 -< -When this option is set, the current file status shown in the ruler may not be -the most up to date status, so when it is important (see -|perforce-negative-revisions|) make sure you update it manually. - - *perforce-file-launcher* - *p4FileLauncher* -This setting is used to choose the launcher application for executing the -|PFileLaunch| command in a filelist window. For non-windows platforms, this -needs to be explicitly set before you can use the |PFileLaunch| command, but on -windows, this by default is set to the following command: > - - start rundll32 url.dll,FileProtocolHandler -< -This works almost the same as double clicking the file under explorer, so proper -file associations are assumed. You can however change the command to whatever -you like. - - *perforce-dynamic-client* -For those users who have a need to dynamically switch between different perforce -clients, the plugin provides ability to set expressions that can be used to -provide call back hooks and determine the appropriate client. This is especially -useful when you have multiple clients mapped on to the same root and there is a -way to deduce the client based on the usage patterns and or current file. - - *p4CurPresetExpr* - *p4CurDirExpr* -These by default are set to an empty string, but can be assigned any Vim -expression that is valid on the RHS of a variable assignment. The expression is -evaluated and the result is used as the corresponding setting. - -The "p4CurPresetExpr" setting is used only when using |P4CONFIG| setting. The -"p4CurDirExpr" at any time can also be used to determine the working directory -of the p4 operation, which in turn could impact which |P4CONFIG| file is picked -up. - -For the more demanding users, these expressions provide the call-back hooks -required to determine the client based on your environment. - -Note that when you specify an expression which returns a different current -directory than the current Vim working directory (as returned by |getcwd()|), -the plugin doesn't attempt to modify any relative filenames that you specify on -the command-line to be relative to the new directory, so you need to make sure -you specify a valid filename in this case (or specify full paths all the time). -This could get tricky especially if you can't predict which directory your -expression would return. If your logic to find the current directory is really -that complex, then you could use the experimental API (see |perforce-API| that -the plugin provides to manipulate the filename arguments yourself from with in -the "p4CurDirExpr" before returning the directory name. However, while adding -new filenames to arguments (such as the default filename for certain commands) -the plugin automatically uses full filenames, when you specify a "-d" option on -the command-line or through the return value of "p4CurDirExpr". - -It is recommended to return an empty string from "p4CurDirExpr", when the -directory is same as Vim's current working directory. - -See also |perforce-switch-client|. - -See |perforce-tips| for an interesting and useful idea for using "p4CurDirExpr" -setting. - - *p4UseClientViewMap* -This is an experimental feature, so defaults to 0. - -Use this setting to make the plugin look into your client View: mappings while -translating depot paths to local paths and vice versa. The plugin translates the -paths without needing to run "p4 where" command, by extracting the View: data -from the client specification and building an internal representations for that. -This is done the first time the translation is required and it is cached to -avoid executing the "p4 client" command everytime. When the views in your client -specification change, you need to manually update this mapping by running the -|PFUpdateViews| command. - -Make sure you don't have any syntactic errors in your views (such as unmatched -wildcards), as the plugin is not as forgiving as perforce itself in handling -them (this is done for simplicity). -============================================================================== - - *perforce-syntax* -The perforce plugin comes with a Vim syntax plugin for perforce filetype, and -works even when the |perforce-filetype| plugin is not setup. Most of the -output windows generated for perforce commands are set to the "perforce" -filetype and results in automatically sourcing this syntax file. Like any syntax -plugin, you can do further customizations and overrides from your vimrc or from -an "after" plugin (as the case may be). To customize syntax colors, here is a -complete list of all the syntax groups that the plugin defines (replace the tag -on the right hand side with your own preferred highlight group such as Comment, -Special etc.): -> - hi link perforceSpecKey <your_preferred_highlighting_group> - hi link perforceComment <your_preferred_highlighting_group> - hi link perforceDate <your_preferred_highlighting_group> - hi link perforceCommands <your_preferred_highlighting_group> - hi link perforceHelpKeys <your_preferred_highlighting_group> - hi link perforceClientRoot <your_preferred_highlighting_group> - hi link perforceKeyName <your_preferred_highlighting_group> - hi link perforceDepotFile <your_preferred_highlighting_group> - hi link perforceLocalFile <your_preferred_highlighting_group> - hi link perforceVerSep <your_preferred_highlighting_group> - hi link perforceVersion <your_preferred_highlighting_group> - hi link perforceSubmitType <your_preferred_highlighting_group> - hi link perforceDefaultSubmitType <your_preferred_highlighting_group> - hi link perforceViewExclude <your_preferred_highlighting_group> - hi link perforceDepotView <your_preferred_highlighting_group> - hi link perforceClientView <your_preferred_highlighting_group> -< -============================================================================== - - *perforce-help* -The plugin comes with a help browser to browse the perforce help from within -vim window and move back and forth between different help pages. To start the -help just type |PH| or "PF help" command or alternatively choose the appropriate -menu entry. The plugin opens a new window that is positioned the way the vim -built-in help does. Once you close the help window, all the other window sizes -are restored, again the way the vim built-in help does. - -Once you are in the help window, you can see that the perforce help keywords -are highlighted with a different color. To get additional perforce help on the -keyword, you can just move on to the keyword and press |Enter| or |K|. You can -also press double-click with your left mouse button. - -The |PH|, |PHelp| or "PF help" command takes a set of arguments that are passed -to the perforce help command, which makes it easier to get to the help page if -you know the keywords. The |PH| and |PHelp| commands also support command -completion for help topics. - -You can use <BS> and <Tab> to navigate the help history. This makes it easy -to view the perforce help and makes it feel like a hyper-text browser. Use "q" -or any other vim command to quit the help window. -============================================================================== - - *perforce-commands* - *:PF* - *perforce-global-options* - *perforce-command-options* - *perforce-command* - *perforce-arguments* -The plugin defines a set of new commands to interact with perforce. The most -basic command is the "PF" command that is equivalent to the "p4" command on -the shell. This command takes arguments that are processed and passed to the -external p4 command and the output is collected back. Depending on the type of -command and various user settings, the output is either displayed in a new -window, a preview window or in a dialog box. - -The command syntax resembles that of p4 command. There are five different types -of arguments that can be passed to PF command: -> - :[range]PF [<p4 global options>] <p4 command> - [<p4 command options>] [<arguments>] -< -All the argument sections are optional except for the command name itself. It -provides the flexibility to issue complex commands (essentially anything that is -possible at the shell prompt) such as the below: -> - :PF -c client -u user integrate -b branch -s source target1 target2 -< -where, the "-c client -u user" are global options, "integrate" is the p4 -command, "-b branch -s source" are the command options and the "target1 -target2" are the arguments to the corresponding perforce command. - -Note: See |perforce-common-options| for informaton on providing global options -transparently. - -All commands executed through "PF" go through a common internal function that -does argument validations/modifications/customizations etc. in addition to any -command specific operations. This results in a very consistent argument handling -throughout all the perforce commands. - - Example: > - " Run p4 diff on the current file and display the diff in a new window. - :PF diff - - " Show all the opened files under the src directory (assuming you we are - " currnetly above this directory) in a new window. - :PF opened src/... - - " Open the client specification for editing. - :PF client -< -Most commands take variable number of arguments. Some commands that require a -filename default to current file or ask you for an argument, if you didn't pass -any. - -You can additionally pipe the output of p4 through external commands (filters) -before the plugin sees the output. Anything after an unprotected bar ("|") is -considered as the external filters and so is specially treated by the plugin, -and the processing on such arguments is reduced to a minimum, which means that -you need to take care of the shell specific issues (such as enclosing the -arguments in quotes etc.) yourself. If you need to specify the bar symbol as -part of the perforce arguments (not really as the shell pipe symbol), then you -need to protect it with a back-slash, as discussed in the -|perforce-special-chars| section. - - Example (useful for older versions of p4 client that didn't support -u - argument): > - PChanges -s pending | grep hari -< -If you find yourself using a combination frequently, you can create a new -command for it to make it easier to type. For the above combination, the -following can be placed in .vimrc: -> - command! MyPChanges PChanges -m -1 -s pending | grep hari -< -Note, If you want to by-pass additional command specific processing, then you -can use the |PFRaw| command instead of the "PF" command. - -The :PF command also supports custom command completion, to complete partial -perforce command names as well as filenames. Most filename expansions -automatically happen (like, %, <cfile> etc.), and # followed by a revision -specifier is treated specially when occurred at the end of the argument, and is -prevented from getting expanding as a Vim buffer name. - - *perforce-special-chars* -Some of the characters in the arguments are treated specially by the plugin, -unless they are protected by prefixing them with a back-slash. The characters -that are treated specially are: - - character special meaning ~ - <space> argument separator. - & codeline modifier. See - |perforce-alternative-codeline-modifier| - | pipe symbol. - \ protects other special characters, unless protected by - itself. - - *perforce-command-mode-specifier* - *perforce-filter* *perforce-pipe* -You can also specify the run mode of the perforce command as one of the "run" -(default), "filter" or "pipe" by specifying one of the '++r', '++f' or '++p' -option respectively to the PF command in the <p4 global options> section as -described in the |perforce-commands| section. These options are just used as -directives to the command-processor and are not passed to the external p4 -command. The "filter" and "pipe" modes are most useful with the "-x -" -perforce global option (see ":PH usage" for details) and "display" mode is used -mainly for internal purposes. - - option details ~ - ++p Write (pipe) the lines specified by the given [range] to the p4 - command on standard input. This works like the |:write_c| command. - This only pipes contents to p4, and doesn't read the output back, so - the contents are not effected. - ++f Filter the lines specified by the given [range] through the p4 - command. This works like the |filter| command. You can create a new - buffer or modify buffer containing the output of another perforce - command, and pass the contents as arguments to a perforce command - and get back the results. In fact the '++c' option of diff does - exactly this. It first obtains the list of opened files in the given - change list and passes them as arguments to the diff command. See - |perforce-extensions|. The |PW| command is just an alias for this - feature so that you can skip the bang for convenience (you can't - specify -x option with this command, however). - -The default [range] for the ":PF" command is the whole buffer (1,$). There is no -direct equivalent of Vim's |:read!| syntax here, but it can easily be done using -the "filter" mode on an empty line created at the location where you want to -read the output of p4 command. - - *:PEdit* *:PRevert* *:PAdd* - *:PDiff* *:PDiff2* *:PPrint* - *:PGet* *:PSync* - *:POpened* *:PHelp* - *:PDelete* *:PLock* - *:PSubmit* *:PUnlock* - *:PClient* *:PClients* *:PUser* - *:PUsers* *:PBranch* - *:PBranches* *:PLabel* - *:PLabels* *:PJob* *:PJobs* - *:PJobspec* *:PResolve* - *:PChange* *:PChanges* - *:PDepot* *:PDepots* *:PHave* - *:PDescribe* *:PFiles* *:PFstat* - *:PGroup* *:PGroups* - *:PLabelsync* *:PIntegrate* - *:PPasswd* - -While the perforce commands can be executed using the "PF xxx" syntax, some -of them have an equivalent PXxx command. So the following two: > - - :PF opened -c 123456 -< - and > - - :POpened -c 123456 -< -are identical. However, if you intend to pass some global arguments to p4, -then you are forced to use the first syntax. E.g., if you want to change the -user specification of another user, instead of changing the P4USER env. -variable, or using the |PFSwitch| command, you can use the following approach: -> - :PF -u other_user user -< - *perforce-describe* -The describe command by default adds the "-s" option to avoid generating the -diff, unless a diff option is explicitly specified (implying that you would like -to see the diff too). - -Note that the commands that normally prompt a confirmation message (such as -revert) accept a "++y" argument to avoid the prompt. -> - :PF ++y revert -c 12345 -< - *:PE* *:PR* *:PA* *:PD* *:PD2* *:PP* - *:PG* *:PO* *:PH* -Some of the more frequently used commands have a shortcut to make it faster to -type. Following table gives the mapping: - - Short-cut Command ~ - PA add - PD diff - PD2 diff2 - PE edit - PG get/sync - PH help |perforce-help| - PO opened - PP print - PR revert - -You can also define your own shortcuts easily, e.g., > - - :command! -nargs=* PB :PF branch <args> -< -Place this command in your .vimrc so that it gets executed every time you -start Vim. - - *:PFRaw* -PFRaw command is like |PF| command except that it bypasses all the processing -that the |PF| command does. You should be able to pass most of the perforce -arguments as they are to this command. The raw output from the p4 command is -collected and placed in a new window - -Note that you can't use PFRaw to execute any p4 command that requires user -interaction (such as "PFRaw client") unless you can pass in a "-o" options to -it. In fact the |PF| command and the corresponding specialized commands (such -as PClient) pass the "-o" argument internally to generate forms. - - *perforce-initialize* - *perforce-reinitialize* - *:PFInitialize* -Changing some settings may have impact on other plugin or Vim settings, so to -propagate these changes, you should execute the :PFInitialize command. -When you want to change a setting while within Vim, you can directly set the -value of the corresponding global variable, but you should also call the -:PFInitialize command. It is recommended to use the |:PFsettings| command, which -not only makes it easier to find and enter values for these settings, it will -also execute :PFInitialize for you. - - Examples: - You can remove the Perforce sub-menu from the main menu by using - the following commands: > - - :let g:p4EnableMenu = 0 - :PFInitialize -< - You can re-enable the menu, may be the full-featured one by setting: > - - :let g:p4EnableMenu = 1 - :let g:p4UseExpandedMenu = 1 - :PFInitialize -< - *:PFSettings* -To make the above process easier, the PFSettings command prompts you with a -list of settings to select from (without the common p4 prefix) and let you -modify them. You can optionally pass in the setting name and value on the -command line too. If passing the setting name, you can use Vim's completion -mechanism to complete partially typed in name. -> - :PFSettings [setting name] [new value] -< -The command reinitializes the plugin after making the modifications. A typical -dialog to turn on perforce menu for a gvim window could look like this: -> - :PFSettings - 0 User 1 Client 2 Password - 3 Port 4 Presets 5 ClientRoot - ... - 9 EnableMenu ... - ... - . - . - Select the setting: 9<Enter> - Current value for EnableMenu is: 0 - Enter new value: 1<Enter> -< -You should see the menu turned on at the end of this process. You can quit the -dialog at any time by just pressing <Enter> without typing anything. - -If you know the name of the setting (or use command-completion), you can specify -the setting and its new value directly on the command-line, to avoid the -dialogs. E.g., to change the default diff options: > - - :PFSettings DefaultDiffOptions -dwbu - Current value for DefaultDiffOptions: "-du" New value: "-dwbu" -< -Note, there is also an abbreviation defined for this command as "PFS". - - *perforce-switch-client* - *:PFSwitchPortClientUser* - *:PFSwitch* -If you are connecting to multiple perforce installations, the PFSwitch command -can be used to quickly switch between them. For an explanation of how to -store these configurations to avoid typing, or use the Settings menu, see -|p4Presets|. - -When you want to switch to a different perforce server, or just switch to a -different client or user, without leaving Vim or needing to change any -environment variables, use the PFSwitch command in one of the following ways: - - 1. Prompt for the setting to choose from. Enter the index in the list of - settings. > - - :PFSwitch -< - 2. If you know the index, pass it as an argument. > - - :PFSwitch <index into p4Presets starting with 0> -< - 3. To switch to an arbitrary setting, pass in the arguments as below: > - - :PFSwitch <port> [<client>] [<user>] -< - As a special case, you can pass in P4CONFIG as the only argument to - switch to using the P4CONFIG feature of the external p4 command (see - also |perforce-dynamic-client| and |perforce-P4CONFIG|. You can use Vim - command completion mechanism to complete from the |p4Presets|. - 4. You can also use PFSwitchPortClientUser which prompts you for the - individual values. > - - :PFSwitchPortClientUser -< -See also |p4Presets|. - -Note, this command resets the cached file statuses of all the buffers such that -their statuses are determined again based on the new client. - - *:PFWipeoutBufs* -This command can be used periodically to cleanup all the hidden perforce buffers -that are not already wipedout because they are not yet unloaded (see -|p4HideOnBufHidden| for ways to do this). By default, this command only prints -the list of buffers that will be wipedout, so to actually wipeout the buffers, -run the command with "++y" option. > - - :PFWipeoutBufs ++y -< - *perforce-update-views* - *:PFUpdateViews* -Use this command to update the internal structures corresponding to the client -view mapping. When run, it discards the local cache and reconstructs it by -running "p4 client" command. -============================================================================== - - *perforce-revisions* -For convenience most commands (such as sync and print) take in a revision (as -specified by "help revisions") as the last argument and apply it to the -current file. You need to however protect the '#'s with a backslash such that -it is not substituted by vim with the current alternative-file |#|. - Examples: > - - :PP \#1 - To see the revision 1 of the current file. - :PP @2002/01/01 - To see the current file as of a date. - :PP @65000 - To see the current file as of change 65000. -< - *perforce-negative-revisions* -In addition, you can also pass in a negative or positive number as a revision -to specify an offset from the have revision. If you have the -|perforce-active-status| feature enabled, the have revision value is available -automatically, otherwise the plugin executes the file status such that it can -generate the new revision after the offset. > - - :PP \#-2 " To see the (#head - 2)'th revision. - :PD2 \#-1 \#-0 " Diff between the have and the previous revisions. - :PD2 #\#have #\#head " Diff between the have and the head revisions for - " the alternate file.. -< -Note: Observe the "-0" given as the revision number to mean the head revision. - -Note: PD2 (which is a shortcut for "PDiff2" or "PF diff2") also supports an -interactive mode in which you can just type in PD2 by its own with no -arguments, and the plugin will prompt you to specify the two revisions. You -can specify any revision specifier that is normally supported on the -command-line, in addition numbers are always treated as revisions so you don't -have to prefix them with a \#. > - - :PD2 - Version 1? 10 - Version 2? 2002/12/15 -< -Note: To be able to specify revision offsets, you need to have all the resultant -files already open in the current vim session. - - *perforce-alternative-codeline-modifier* -Another convenient feature supported by plugin is to allow specifying an -alternative codeline in addition to the revision specifiers by using the '&' -modifier. Suppose you want to diff between the revision 2 of the currently -opened file with the head revision of the same file but from another codeline -called 'other', then the following syntax makes it easy > - - :PD2 \#head&other \#2 " Same as 'PD2 \#1 \#2' if 'other' is the parent - " codeline and if they are in sync. -< -You can pass multiple such modifiers too, though the main use is with the -depot-modifier as described below. - - *perforce-depot-modifier* -The '&depot' modifier is treated specially. Instead of treating 'depot' (or the -name of the current depot) as an alternative codeline, the filename is converted -to its corresponding depot name. This is useful if the local file is not part of -your client spec or is deleted from the depot. See also -|perforce-edit-alternative-file| > - :PF filelog a-deleted-file&other&depot -< - - *perforce-local-modifier* -The '&local' modifier is treated specially. Instead of treating 'local' as an -alternative codeline, the filename is converted to its corresponding local name. - -============================================================================== - - *perforce-forms* - *perforce-specifications* - *perforce-interactive-commands* -Most of the perforce forms can be edited right from with in vim. The perforce -command line normally invokes the external editor to edit the forms and when -you save and quit the editor, the form is read back and the corresponding -settings are updated. E.g., the following steps describe how you modify client -specification using the p4 command: -> - $ p4 client - - # A Perforce Client Specification. - # - # Client: <so and so>. - . - . - :wq - - Client <so and so> saved. -< - The aim of the plugin is to be able to do most of such actions without -needing to leave Vim. So when you execute a command that requires editing a -form, the plugin automatically generates the form in a new window for you to -edit. You can then modify it as you would normally in the external editor -invoked by the p4 command, and to finally save it, use the normal |:write| or -the special "W" (|perforce-W|) command. The plugin then tries to send the -changes back to the server and generates the result also on the same window. The -entire process would appear the same as above, except for - - 1. you would use "PF client" or |PClient| in Vim, instead of the - "p4 client" in the shell. - 2. Edit the specification as you would otherwise. - 3. The specification will be automatically written back to perforce when - you save it like any other file (using :w or :W). - -Note that you can also use :wq to save and quit the window at the same time, but -because of a known issue in Vim as of the release version of 6.1, your changes -could be lost if the specification has an error. There is a patch available for -this that fixes the problem, so apply the patch or use the safer :WQ command. - -What is the advantage? - - - You don't have to leave your Vim window or look for a command prompt. - - If you change your mind, it is easy to quit/leave or even postpone - (especially for submits, where you can convert it to a new - change list) the spec window. - - On errors you can just undo (by pressing 'u') and retry, as many - times as you need to. - - You have the option of opening the specification while viewing its - corresponding list. E.g., you can execute "PF changes -s pending" - and press "O" command on any change to open its change specification - and easily modify it. - - You can also view multiple specifications at the same time. You can - for example easily move files from one change list into another. - - You have additional commands defined local to the spec window, that - are specific to the type of spec being edited. - - Based on your working habits, you have other advantages that are - inherent in using the same Vim session for multiple things. - - It is much easier to use the Vim editing techniques to filter the - filelist or edit the description instead of using the GUI in p4Win. - - To me, it is also more fun to do it this way :) - -Unlike in earlier versions of the plugin, the specification buffers are now -regular buffers, so they get marked as 'modified' when you start editing them. -This prevents you from accidentally quitting the buffers, without writing them -back to perforce. Also, Vim creates 'swapfile's for these buffers, so in case -your session crashes, you can retrieve your changes (such as the description or -your filelist) from the swapfile (see |crash-recover|). The swapfile will -usually be created in the current directory or in a fixed directory specified by -'directory' setting. When working with perforce specifications, the swapfiles -could also be created in the temp directory, as the buffer names are often -invalid on the file system (in which case the swap filename may not be that -obvious). - - *perforce-W* - *perforce-WQ* -The W command accepts arguments that are in turn passed to the corresponding -p4 command, so you can pass additional arguments such as "-r" while using -submit form. - -There is also a WQ command which is same as the W command except that it also -close the form window when there are no errors. - -The equivalent menu entries are "Save Current Spec" and "Save and Quit Current -Spec". - - *perforce-changelist* -The change command accepts a set of perforce filename patterns that are -passed directly to "opened" to filter the files that should be included in the -changelist. Without specifying the patterns, the command would work exactly the -way the native "p4" command works, which means the changelist will start with -all the opened files that are in the "default" changelist. - -============================================================================== - - *perforce-submit* -The submit command is handled slightly differently than other interactive -commands, as the "PF submit" or |PSubmit| internally runs the "PF change" -command to generate a submission template. There are a few additional features -implemented which are discussed below. - -PSubmit command accepts additional arguments which are passed in as they are -to "opened" command to generate the list of files to submit, so it is possible -to create the template with a set of files to submit such as, "PSubmit % #" to -submit the current and alternate files only (which is more flexible than the -native command). Of course you can always run with out arguments to generate a -full list of files and then remove the ones that you don't want. You can also -pass in the -c changelist# to submit the given changelist non-interactively (or -submit it from "changes" list). You can convert a submission template into a -changelist by simply using the PSubmitPostpone instead of the W or WQ command. -Similarly, when you are in the change specification, you can use the -PChangeSubmit to submit the current change instead of first saving it using W or -WQ command and then submitting the change list using the "PSubmit -c -changelist#". - -On partial errors during the submissions (such as those that require a resolve -before submission), perforce sometimes automatically creates a changelist for -the files in the submission template, in which case the changelist number is no -longer "new" and the status is no longer "pending", so the plugin automatically -detects this scenario and adjusts the template for these values. All you have to -do in such cases is to 'undo' as you normally would, and fix the error before -trying to submit again. - -Note, arguments such as '-r' are remembered when the PSubmit is first invoked -and are used during the :W or :WQ command. - -============================================================================== - - *perforce-list-commands* - *perforce-list-view* - *perforce-item-list* -When executing a perforce command that generates a list of {something} such as -changes, you have special commands defined that are local to the buffer and -are specific to the list you are viewing. This allows you to visually perform -some operations on the individual item without needing to type a separate -command on the item. - -There are commands defined for both the commandline as well as key mappings -and menu items for these operations. Note however that the same mapping can -behave differently on different list views, depending on what is the list that -you are viewing. E.g., pressing D normally means delete the specific item, but -on a filelog window when you select two history entries (select all the lines -between the two versions, inclusive) and press D, you get a diff between the two -versions. - -There are some generic list commands that work in most of the list views with -somewhat consistent behavior: - -Note that for commands that generate a list of files (such as opened), there -is a different set of commands defined, see |perforce-filelist|. - - *perforce-common-list-commands* -These commands are available in all the listing windows. - - *:PItemDescribe* *:PItemOpen* - *:PItemDelete* - Command Key Meaning ~ - PItemDescribe <Enter> Describe the current item. This shows a - summary of the current item in a - |preview-window|. - PItemOpen O Open the current item for editing. - PItemDelete D Delete the current item. You will have be - prompted to confirm the deletion. - - *perforce-client-list* -You can use all the commands described in |perforce-common-list-commands|, as -well as the below: - - *:PClientsTemplate* - Command Key Meaning ~ - PClientsTemplate P Using the current client as a template, - start creating a new client spec. You will - prompted for the name of the new client. - - *perforce-labels-list* -You can use all the commands described in |perforce-common-list-commands|, as -well as the below: - - *:PLabelsSyncClient* - *:PLabelsSyncLabel* *:PLabelsFiles* - *:PLabelsTemplate* - Command Key Meaning ~ - PLabelsSyncClient S Sync the client to the current label. - PLabelsSyncLabel C Sync the the label to the current client. - PLabelsFiles I List the files associated with this label. - PLabelsTemplate T Using the current label as a template, start - editing a new label spec. You will be - prompted to enter the name of the new label. - - *perforce-changes-list* -You can use all the commands described in |perforce-common-list-commands| as -well as the below: - - *:PChangesSubmit* *:PChangesOpened* - *:PChangesDiff* - Command Key Meaning ~ - PChangesSubmit S Submit the current change list. You will - be prompted to confirm. - PChangesOpened o List files associated with this - changelist. - PChangesDiff d Show diff for the current pending or - submitted changelist. - - *perforce-filelog-list* -You can only use the describe command described in -|perforce-common-list-commands| however there are other convenience commands -defined for this view: - - *:PFilelogDiff* *:PFilelogDSync* - *:PFilelogDescribe* *:PFilelogPrint* - Command Key Meaning ~ - PFilelogDiff D Show diff between two selected versions - (works only in the visual mode). - PFilelogDSync S Sync to the current version. - PFilelogDescribe C Describe the changelist for the current - change. - PFilelogPrint p Run print on the current version. - -You can generate the diff between two version while viewing the history. For -this, you need to select all the lines between the two version, inclusive, and -press the 'D' key. You can also use the PFilelogDiff with a range of lines as -a prefix, without needing to select the lines. - - Example: - You can mark the first version as 'a' using the 'ma' command and mart - the second line as 'b' using the 'mb' command and execute: > - - :'a,'bPFilelogDiff -< - - *perforce-filelist* -When you execute the commands |POpened|, |PHave|, |PFiles| and |PDescribe| that -generate a list of files, you can use the file list window to do further -operations on the files. - - *:PFileDiff* *:PFileProps* *:PFileEdit* - *:PFileRevert* *:PFilePrint* *:PFileSync* - *:PFileChange* *:PFileLaunch* *:PFileLog* - Command Key Meaning ~ - PFileDiff D Run "p4 diff" on the current file. - PFileProps P Print the properties (fstat) of the - current file. - PFileEdit I Edit (checkout) the current file. - PFileRevert R Revert the current file. - PFilePrint P Print the current file in the preview - window. This is mostly same as - PItemDescribe, but handles the deleted and - binary files correctly. - PFileGet Sync the current file to the revision - specified in the filelist. - PFileSync S Sync the current file to the head - revision. - PFileChange C Open change list for the current file. - PFileLaunch A Launch the current file. On windows, it - works almost the same way as double clicking - the file in explorer. On non-windows - platforms, you need to explicitly configure - a launcher command by using the - |p4FileLauncher| setting. You need to have - (correct revision of) the file already on - the filesystem, if not first do a sync as - described above. - PFileLog Run "filelog" on current file. - -In addition, the plugin sets up 'includeexpr' such that you can use |gf| and -|<cfile>| on the depot files. Since |gf| would result in the current buffer -getting hidden, the current perforce buffer showing the filelist could get -wipedout (unless this is prevented using the techniques described in -|p4BufHidden|). If you have any mappings using |<cfile>| they should work well. - -Note: There is no quick help available to see which commands are available and -what the mappings are for any given perforce result buffer. However, the output -of nmap command is pretty useful and sufficient for this purpose. Type the -following command as it is to see the perforce commands with their mappings -(among others) > - :nmap <buffer> -< -============================================================================== - - *perforce-extensions* -There are some useful extensions provided over the perforce commands to make -your job easier. - -|perforce-pending-change-diff| Restricting diff to an open changelist. -|perforce-vim-diff| Diffing using vim's built-in diff feature. -|perforce-external-diff| Diffing using external diff tool. - - *perforce-pending-change-diff* -This provides an useful "++c" option to the PDiff command to specify a change -number that is open on this client. The plugin internally queries the open files -under this change list and restricts the diff to only these files. > - - PF diff ++c 1111 //depot/branch/src/... -< -The above restricts changes to only the changelist '1111' and under the src -directory. - - *perforce-builtin-commands* - *perforce-vim-diff* -The plugin provides two built-in commands vdiff and vdiff2 to view diff using -the Vim's built-in diff features instead of using the perforce diff and diff2 -commands respectively. If you need to customize the view, then read help on -|diff-options|. These commands do not accept any options and will ignore them if -any are provided. Make sure you don't have any windows that have diff mode set -before running these commands as otherwise they will participate in the diff -too. - - *perforce-vdiff* - *:PVDiff* - *perforce-vdiff2* - *:PVDiff2* -These commands are an alternative to the perforce diff and diff2 commands that -use the Vim's built-in |vdiff| feature to generate the diff. Both command work -exactly same as both accept upto two arbitrary local or depot files as -arguments, but while "vdiff" command works with the files as they are specified -(local or depot paths), the "vdiff2" command tries to convert them to depot -paths as much as possible. There is also difference in how they choose default -arguments when the number of arguments is less than 2. The "vdiff" commands are -also a lot more flexible than the "diff" commands in that you can mix any two -filenames as arguments, including those from different codelines, local and -depot files and even those that are not even related. - -With only one file (or the current file when no arguments) specified as -argument, the "vdiff" command like the "diff" command, diffs the file against -that of depot, where as the "vdiff2" command, like the "diff2" command prompts -you to enter the two depot version that you would like to diff for the specified -file. -> - :PF vdiff " Diff the current file against depot. - :PVDiff % &altBranch " Diff the current file against the same from a - " different branch. - :PVDiff2 \#1 \#2 " Diff the revisions 1 and 2 for the current file. -< - *PFDiffOff* -These commands always open new windows split vertically side-by-side to start -diff settings (diff settings are local to windows), so that your existing -windows are not disturbed. When you are done viewing the diff, you can just -close the diff windows and be done. But in case you need to reset the diff -settings, there is a command called "PFDiffOff" provided for convenience. The -command is very flexible in the sense that, it can identify the diff windows -that belong to one diff operation and when run from one of them, can turn off -the diff settings on all the related windows. This is useful to incrementally -add/remove diff windows using PVDiff and PVDiff2 commands. If run outside of any -perforce diff windows, it turns off diff for all perforce windows. - - *perforce-default-diff-format* -Pass the dummy option "-d" (with no diff flags) to perforce commands that -produce diff output to force the format to be in the default diff format. This -is useful in case the |p4DefaultDiffOptions| is used and you temporarily want -the diff output to be of default type. This option is not really recognized by -the p4 command, and so will be removed from the command string before seen by -the p4 command (and so is merely used to avoid adding the default diff options). -> - :PF describe -d 100 -< - *perforce-external-diff* - *perforce-GNU-diff* -The "diff" command now supports running external GNU diff to generate the diff -output. To use this feature, make sure you have GNU diff installed in the path -and pass one or more of the valid GNU diff command options using the following -syntax: -> - +<short or long option>[=<optional argument>] -< -E.g., to generate diff output for the current file in unified format with the -whole file in context (like the diff output in p4Win), you could use the -following comand: -> - :PDiff +U=99999 -< -Just make sure that the number is large enough to include the whole file. -Another example is: -> - :PDiff +strip-trailing-cr +context=10 +W=120 +w -< - *perforce-execute-direct* - *:PExec* -This is a built-in command that executes arbitrary vim commands after -processing the command-line the same way as it would if you executed any regular -perforce command. This is useful to execute external perforce commands (though -not limited to them) directly, when you find that you can't do some task using -the features provided by the plugin alone. You typically want to execute -perforce commands using Vim's |:!| feature, e.g.: > - - :!p4 sync % -< -But if you want to take advantage of the various command-line shortcuts provided -by the plugin, then you would just pass the command as it is to :PExec: > - - :PExec !p4 sync %&altbranch#3 -< -The above would sync the current file in a parallel branch called -"altbranch" to the version 3. Using the command also has the other inherent -advantages such as, you don't have to protect the filenanme special character -such as "#". The plugin also performs the same escaping mechanism on the -external command that it does on the regular plugin commands, however any -filters specified are not currently escaped. - -Note, the above two commands are just examples that can easily be achieved using -the following plugin commands: > - - :PF sync - :PF sync &altbranch#3 -< -============================================================================== - - *perforce-misc-commands* -These are some misc. commands that are provided by the plugin in addition to the -commands that are already described. - |PFRefreshActivePane|, |PFRefreshFileStatus|, - |perforce-edit-alternative-file|, |PFSwitch|, |PW|, |PFToggleCkOut|, - |PFLastMessage|, |PDiffLink|, |PDiffPLink| - - *perforce-refresh-active-pane* - *:PFRefreshActivePane* -This command allows you to refresh the active perforce window (the window where -the cursor currently is). The window should have been a result of a perforce -command, to be able to refresh it. There is also a menu entry and a normal-mode -mapping <Leader>prap to do the same. - - *perforce-refresh-file-status* - *:PFRefreshFileStatus* -Use this command to manually refresh the |perforce-ruler|. Useful when you -have the automatic refresh disabled by setting the |p4EnableActiveStatus| -to 0. You can also use the normal-mode mapping <Leader>prfs to do the same. - - *perforce-edit-alternative-file* - *E* - *ES* -These commands allow you to open the current file from an alternative codeline. -The syntax of the command is: > - - E [codeline] [files: default %] - ES [codeline] [files: default %] -< -The difference between the two is that ES opens the file by splitting the -current window, where as E opens the file in the current window. You can specify -more than one file in which case the first one is still opened, but the -remaining files are just added to the buffer list so you can open them later -using a buffer explorer, or using :e #<buf>. If no arguments are passed, (just -type E or ES on its own), you will be prompted to enter the codeline. - - *perforce-write-file-contents* - *:PW* -The |PW| command is a special command that you can use to filter the current -file contents through p4. You can specify the range of lines that need to be -written to the command and the default range is the entire file (1,$). The "W" -(|perforce-W|) or "WQ" (|perforce-WQ|) command described in |perforce-forms| -internally uses this command to write the form back to the perforce command and -read the result back. The command itself uses the |perforce-filter| feature to -do its job. - -The following command can be used to revert the contents of the current file -without using the perforce "revert" command. You can save the file, but you can -always do |:undo| to get back to your original contents (provided you haven't -lost your undo history). So this can be used to temporarily revert contents to -the depot version and then get back to your original version. -> - :PW print -q - :w - :undo -< -Also see |perforce-command-mode-specifier| for alternatives to using this -command. - - *perforce-toggle-checkout-prompt* - *:PFToggleCkOut* -This command can be used to disable/enable the automatic checkout prompt while -editing the readonly files. This is useful while you are in a read-only vim -(started with -R option), so even the files that are already checked out also -appear as read-only files, in which case, you don't want to see the checkout -prompt when you accidentally start modifying a file (or for that matter even -when you deliberately modify a file). - - *perforce-last-message* - *:PFLastMessage* -Prints the last given message again. - -============================================================================== - - *perforce-special-commands* - - *:<pfitem>* -You can use the special tag <pfitem> on the command-line to mean the current -list item. This works very close to how |:<cword>| etc. work. The command-line -parser would replace this with the value of the current item (which is dependent -on the type of list view) at runtime. This is useful to create your own -mappings/commands over what the plugin provides. - - *perforce-special-mappings* -There are some special mapping created for the command-line usage. - -While you are in a list view (such as list of labels), you can get the name of -the current label on to the command-line by just typing <Ctrl-X><Ctrl-I>. This -is useful to quickly and accurately execute commands on the items that have -long names. - -On the same lines as the E command (|perforce-edit-alternative-file|), there -is another command-line mapping created for inserting the name of an -alternate file right at the command-line. You can do this by typing -<Ctrl-X><Ctrl-P>. You will be prompted to enter the name of the alternative -codeline. -============================================================================== - - *perforce-utils* -These are available only when you install the perforce/perforceutils.vim plugin -as described in the |perforce-installation| section. - - *perforce-diff-mode* - *perforce-diff-hyperlink* - *:PDiffLink* *:PDiffPLink* -Executing various commands such as |PDiff| and |PDescribe| produce output in the -form of perforce diff (very similar to GNU diff output). The plugin provides two -commands to make it easier to navigate from the diff output to the original -source file like a hyperlink. The location of the original source file and the -line number are extracted from the diff output (supports the default, context -and unified formats). To open the source file and take the cursor to correct -location, use :PDiffLink command or press "O". To open the source file and -position the correct location in the preview window, use :PDiffPLink or press -<CR>. These commands are defined for only those windows that contain perforce -diff output. - -Note that the commands can be executed on both the old and new source lines, and -the plugin either opens the appropriate file on the local filesystem or -"print"s the correct version from Perforce to position the cursor. When diff -refers to a depot file and the corresponding local file is already open in Vim -and has the same revision as of the depot file that the diff refers to, the -plugin opens the local file instead. - -Note these commands are capable of handling regular GNU diff output formats too, -so you can use it on diff outputs generated using the "diff" command alone. - - *:PFDiffLink* - *:PFDiffPLink* -These commands provide the same functionality that |PDiffLink| and |PDiffPLink| -provide in a diff windows, except that you can run them in any buffer that has -diff style output. Mostly useful if you are viewing diff obtained in a patch. - - *perforce-show-conflicts* - *:PFShowConflicts* -This command is useful while resolving conflicts using an interactive -"p4 resolve" command. When you choose the "e" option to edit files, perforce -generates a single file containing changes from ORIGINAL, THEIRS and YOURS. It -is usually hard (especially when the conflicting region is large) to figure out -what others have changed and how to resolve them. Using a visual merge tool -usually helps, but this commands provides an alternative by allowing you to use -the |diff-mode| features in Vim. Once p4 invokes Vim as the EDITOR using a -tempfile as the argument, you can run this command to generate three vertical -windows each containing changes from ORIGINAL, THEIRS or YOURS only, and invokes -the |diff-options| on them. Edit the YOURS file as usual and use the |:diffget| -command from within YOURS or the |:diffput| command from the other two windows -to move diff regions into the YOURS file, and finally write the changes back to -the original temp file using the |:write| command. - - *perforce-selectbuf-ftplugin* - *perforce-selectbuf-integration* -The perforce plugin now comes with ftplugin that adds some perforce commands to -the SelectBuf buffer browser. If you have the SelectBuf plugin installed, you -don't need to do anything special to take advantage of this. When you are -viewing the buffer list, you can execute the following commands directly on the -current buffer in the list, or the current selection of buffers: - - P4 Command Map ~ - add <Leader>pfa - sync <Leader>pfg - edit <Leader>pfe - delete <Leader>pft - revert <Leader>pfr - submit <Leader>pfs - lock <Leader>pfl - unlock <Leader>pfu - diff <Leader>pfd - diff2 <Leader>pf2 - -I also recommend also installing multiselect.vim plugin that you can download -from www.vim.org that allows you to select multiple buffers that are -non-adjacent to do operations on them. This allows you to e.g., submit a few -files together that are spread out far from each other in the buffer list. -============================================================================== - - *perforce-API* -The plugin comes with an experimental API that you can use to extend the -functionality and provide some integration. Please send in your feedback to -improve the API. You should also look at the perforce/perforcemenu.vim and -perforce/perforcebugrep.vim for examples. -> - " Return the value of the variable in the script context (so add - " appropriate prefix). - " Ex: - " let curClient = perforce#PFGet('s:p4Client') - String perforce#PFGet(String var) - - " Set the value of the specified variable in the script context, to the - " value given. - " Ex: - " call perforce#PFSet('s:p4Client', 'xxx') - void perforce#PFSet(String var, String val) - - " Call the specified function in the script context with the arguments - " passed and return the result. Pass appropriate number of arguments - " based on the function that you are calling. - " Ex: - " echo perforce#PFCall('s:PFIF', '0', '4', 'info') - " let client = perforce#PFCall('s:GetSettingValue', 'Client') - String perforce#PFCall(String func, ...) - - " Evaluate the given expression in the script context and return the - " result. The expression can be any Vim expression that is valid on - " RHS of a variable assignment. - " Ex: - " let client = perforce#PFEval('s:p4Client') - " let client = perforce#PFEval('s:GetSettingValue("Client")') - String perforce#PFEval(String expr) -< -============================================================================== - - *perforce-tips* -- If you are new to Perforce, try the help browser using the |PH| command. You - can easily move back and forth in the help history using <BS> and <Tab> keys. - -- The :W and :WQ commands also accept arguments that are passed as they are to - the external p4 command. If you forgot to specify '-r' option to PSubmit, - you can still specify it to the :W or :WQ command. - -- How to quickly open the current file from a different codeline? -> - :E <codeline> -< -- How to quickly and easily find and open a file, say x.y, which you know is - somewhere under the current directory? -> - :PF files .../x.y - List the files that match x.y in the codeline. This - opens a new window with all the files that match x.y. - You can move cursor to the file-line that you want to - open. - O - Open the file that is displayed under the cursor. - ^Wo - Close all other windows (see |CTRL-W_o|). -< - This technique can also be used with other wildcards that perforce supports. - E.g, you can find all the shell scripts that are checked in to a branch by the - following command (assuming they all have .sh extension): -> -> - :PF files //depot/branch/.../*.sh -< -- How to quickly and easily find and launch a file in its associated - application (needs configuration on non-windows platforms)? -> - :PF files .../x.y - List the files that match x.y in the codeline. This - opens a new window with all the files that match x.y. - You can move cursor to the file-line that you want to - open. - A - LAunch the file. -< -- How to easily reach to a file that you know is currently checked out? -> - :PO - This will create a new window with all the opened - files. You can move cursor to the file-line that you - want to open. - O - Open the file that is displayed under the cursor. - ^Wo - Close all other windows. -< -- You can temporarily disable the p4DefaultListSize (by default set to 100) - while running some list commands by using the -m -1 arguments, to see all - the results. -> - :PChanges -s pending -m -1 -< -- The plugin defines some long normal mode mappings, which could be hard to type - without making errors or pausing for a brief moment. To type in such long - mappings comfortably, you can download and install the execmap.vim plugin from - www.vim.org. -- You can create aliases for most used command combinations using the Vim - |:command| feature (from your vimrc). E.g. the following gives my pending - change lists. -> - :command! PendingChanges :PF changes -s pending -u hkrishna -m -1 <args> -< -- To quickly go to the lines that you have modified in the current file, open - the diff window against the depot, scroll/find the line that you are - interested in and use |perforce-diff-mode| features. -> - :PD - /FIXME - O -< -- To quickly start over with the depot version, without needing to execute - "revert" followed by an "edit", use the |PW| command. -> - :PW print -q - -- To insert the output of any perforce command at the current location, first - open a blank line and run the command using |PW. -> - o<Esc> - :.PW describe -s 100 -< -- Set "p4CurDirExpr" to the following: -> - let g:p4CurDirExpr = "(isdirectory(expand('%')) ? substitute(expand('%:p'), - \ '\\\\$', '', '') : '')" -< - to have the commands run from the directory that you are currently viewing, - instead of the current directory of Vim. - -- If your colleague sends you diff for review, you can make use of :PFDiffLink - and :PFDiffPLink commands to make it easier to reach the "before" file. In - addition, if your colleague's dev folder is accessible by you in the same m/c - (typically for a UNIX server), you should be able to look at the "after" - changes in context. Even if the dev folder is accessible only over the - network, you can convert the local paths in the diff to the network paths - (E.g., you could convert "c:\dev" to "\\tom\dev"), and browse the changes - comfortably. - -- Do you know that :PFDiffLink and :PFDiffPLink commands can be used on regular - "diff" command output too? - -- To quickly search for change descriptions, you can print the list of changes - matching a given restriction, with their descriptions and use Vim to search - for the pattern. You can then describe the change for more information. Ex: > - - :PChanges -l //depot/branch/src/server/... - /socket -< -- Use VDiff if you want to revert only parts of your changes. - *perforce-explore-changed-lines* -- Here is a technique I often use to track who and when someone made a - particular change. The technique assumes you have a branch which includes all - the releases (typically called "release" or "main"). You would first get the - annotations as below: > - - :PF annotate -a &main&depot -< - Locate the line that has been changed (you might find multiple lines due to - reformatting) and identify the version. Run the below command to identify the - change (can be executed from the annotate window): > - - :PF filelog -i -< - This gives you the change number and integration history for that version. - Sometimes this is not enough to find the origin branch, so you can continue to - execute "annotate" and "filelog" commands until you find the original branch - and change number. - -============================================================================== - - *perforce-limitations* - - Interactive resolves can't be done using the plugin. You can however use - auto resolves by passing options such as -as to the 'resolve' command. See - "PH resolve" for help on auto-resolves. Also take a look at the - |PFShowConflicts| command. - - The plugin can work with only one depot at any time, but you can easily - switch between different depots by changing the |p4Depot| setting through - the |PFSettings| command. - - When executing commands that take a lot of time, such as syncing on the - entire branch, Vim waits for the command to complete and exit before - the plugin can display the result. So until Vim becomes more capable in - executing external commands in this regard, I recommend not to run such - commands using the plugin. - - Since 'q' is mapped to quit the perforce windows, it is hard to record - macros that involve dealing with perforce windows. A workaround is to - create a new mapping to the "q" command and use that to start and stop - recording instead, something like this: -> - nnoremap <F12> q -< - *perforce-troubleshooting* - - If none of the perforce operations work for you, then make sure you set - your |p4CmdPath| setting correctly. You can run PFS command and select - CmdPath setting to see what the current value is. On windows, if you have - back-slashes in the path, then make sure your 'shell' setting can honor - them. The 'shellslash' setting is also important if you use a UNIX-like - shells on windows. IF all seems to be well, then please report the problem - to me with your 'shell' setting and OS details. - - If you get E485 errors occassionally or most of the time, and your shell - related settings seem to be fine, then point your $TMP and $TEMP - environmental variables to some path that is shorter ("/tmp" instead of - "C:/DOCUME~1/HARI/LOCALS~1/Temp"). - - If the online perforce help is not working (ie., you are reading this by - directly opening the file, instead of by typing :h - perforce-troubleshooting :), then make sure you ran |:helpt| command. - - If you are not getting automatic checkout prompt when you modify a - read-only file for the first time (and everything else seems to work - fine), then make sure you set your |p4ClientRoot| property correctly. The - plugin ignores any files that are not under your root from giving this - prompt. - - If vdiff and vdiff2 commands don't work for you, make sure the vimdiff - itself works for you. Try running the following command on any two files: - > - gvim -d file1 file2 -< - If the above command doesn't produce any diff though they are different, - or gives any error messages, then first go through the help on |vimdiff| - to get the standalone diff working. - - While editing perforce specifications from commandline, if you don't see - the perforce syntax or cursor is not positioned at a convenient position, - then make sure you added perforce filetype as described in - |perforce-filetype|. - - If |perforce-ruler| doesn't work for you, make sure you have 'ruler' - option set. Also make sure you didn't disable |p4EnableRuler| setting. It - is also possible that another plugin is overwriting the 'rulerformat' - setting (instead of appending to it, as done by the perforce plugin) after - the perforce plugin configures it. Also, if you are in the 'paste' mode, - Vim automatically disables ruler, so make sure you don't currently have - 'paste' option set. - - If you observe a noticiable delay in Vim startup time after you installed - perforce plugin, it may be because, the plugin is trying to obtain the - value of |p4ClientRoot| setting by executing the "PF info" command. You - can avoid this by setting this property yourself in your vimrc. - - If piping a spec manually to a perforce command such as 'change' or - 'submit' using ++p option is not working, make sure the command accepts a - '-i' option to read the spec from stdin and that you are passing in this - option. - - If you get a weird invalid option error, or if the command behaves - weirdly, make sure you don't have a typo in the command-name. The - command-line parser recognizes only the known perforce commands, which - makes an incorrect command name a global option, making it an invalid - syntax. E.g., if you mistype "opened" as "open", you get an error that - "-u" is an invalid option. - - *perforce-version-changes* -These are just a summary of the changes done in the current and previous -versions. Though I have done a good attempt to list all, I could have very well -missed some changes. - - *perforce-changes-4.1* - - Fixed broken handling of <SHOW DIFF> in describe windows. But it is better - than before, as you can now describe multiple changelists and show diffs - selectively. - - For newer perforce servers, <Enter> on a pending change (in changelist) - showed the file list twice. Removed special handling for this, which means - for older perforce servers, you will see no file list. - - Force a file status update on auto checkout. - - File status handling has in general been improved. - - Now executing command on multiple files that result in changing the - file statuses (such as add, edit, revert etc.) will correctly result - in their file statuses getting reset. - - While create a new changelist or submitting a change, the Files: - section is examined and the file statuses for all of them will be - reset. This also works for most of the cases of modifying a changelist - to remove/add files. - - This will also solve a long standing issue that reload during submit - doesn't update its file status. - - All windows are getting navigatation commands mapped (like in help window) - - Workaround for one of the E788 errors (originating from the plugin) during - the auto-checkout. This part of the code has been cleaned up and - simplified. During the auto-checkout, if there are other users editing the - same file, it now results in the plugin echoing the output as a - |WarningMsg|. If you missed to read the output (because you pressed - <Enter> in advance), you can see it again using the |PFLastMessage| - command. The other E788 originating from Vim code can't be - fixed/workedaround, it has to be fixed by Bram. - - Fixed broken submit from changelist. - - When you create changelists, you can now safely undo to make any further - changes, and save them. This also works for submissions (to edit - description only), though you may have to remove the Files section before - saving the change description. - - *perforce-changes-4.0* - - Using Vim7 features, so it is no longer backwards compatible with older - Vim releases. All the logic using multvals has been changed to take - advantage of the Vim7 Lists, so it should be a lot more cleaner and - flexible. - - No longer depends on multvals plugin. - - It is now autoloaded on demand, which means it will help your vim session - load faster. Read the impact on the installation due to this change, - |perforce-installation|. - - A new Cancel option for checkout prompt, see - |perforce-automatic-checkout|. The default for checkout prompt is now - "Cancel". - - The perforce/perforcemenu.vim needs to be loaded from your vimrc if you - want menu to be enabled. See |perforce-installation|. - - The plugin no longer removes the global user setting variables but you - still need to call |:PFInitialize| for effect of some settings to - propogate further. This should have no user visible impact (except in rare - cases). This will only make it easier to deal with settings. You can - still use |:PFSettings| command conveniently for its prompting or - completion features. - - Setting a preset to the g:p4DefaultPreset directly now works fine. - - Most settings can now be overridden at the buffer/window/tab level. - - PFRefreshActivePane doesn't work well on the diff windows (especially when - the ++c option is used). - - *perforce-changes-3.2* - - Fixed PVDiff to work with two filenames. The problem was only with PVDiff - command, as "PF vdiff" worked fine. - - PFDiffOff command is a lot more flexible now, see |PFDiffOff|. - - New command PPasswd for changing passwords. - - Don't confirm revert if -a or -n option is passed. - - Avoid accidentally loosing existing buffers while opening new ones from - diff and other windows. - - Recognize additional p4 commands as valid. - - You can now pass multiple codeline modifiers, see - |perforce-alternative-codeline-modifier|. - - Misc. tuneups for peforce diff hyperlinking feature. - - Misc. bugfixes in the menu. - - *perforce-changes-3.1* - - - This version introduces the concept of overriding settints at the - buffer/window level (an extension of the existing support for - b:p4Options). Makes it easier to work with multiple clients from a single - vim instance. Currently only the p4Client/p4Port/p4User/clientRoot can be - set at buffer/window level. - - Now view mappings are maintained separately for each client. This allows - us to easily work with multiple clients at once. Also see - |perforce-buffer-local-options|. - - For diff hyperlinking, avoid refreshing the depot file if it already - visible. - - Now supports <pfitem> tag to mean the current list item. See |:<pfite>| - - New :PExec command to make it easier to execute exeternal perforce - commands directly, when plugin can't do what you want. See |PExec|. - - PFDiffLink and PFDiffVLink commands couldn't handle "diff -r" output. - - If the current directory is not same as the directory of file being - resolved PFShowConflicts didn't work. - - PItemOpen in describe window now opens the local file, as PItemDescribe - can be used to open the depot file. - - Misc. bug fixes: - - Negative revisions are not working any more. E.g., PP #-1 - - PW is not using the custom completion, so revision specifier (#1) - still needs to be escaped. - - While rerunning a command that opens up a new buffer (such as PD), - unexpected warning messages about matching an existing buffer. - Instead, it should silently refresh the output. - - Diff hyperlinking, prints the depot file everytime, this causes - unnecessary delays. - - PFRefreshActivePane would fail if there are filename special - characters in the command. - - PF command now implements a special completion mode to complete both the - perforce command as well as files. Now you no longer need to protect the - revision specifier (#<revision) as long as it appears at the end of the - argument. - - *perforce-changes-3.0* - - Discard the diff output if P4DIFF env. var. is set (Denis Perelyubskiy). - - There is an experimental API to allow some modularization of the plugin. - See |perforce-API|. There are plugin modules available under perforce - directory that take advantage of this. - - New PFBugReport command to generate "perforcebugrep.txt" file. This is - implemented as a new module perforcebugrep.vim using the above API. - - The menu creation is now separated as a new module that is executed on - demand. Other than giving some modularity, this effectively reduces the - resources consumed by the plugin, especially when the menus are disabled. - - New settings and features that allow dynamic switching of perforce client - settings (Mark Brophy). See |perforce-dynamic-client|. - - The default options don't get saved with the perforce windows (Mark - Brophy). - - IsFileUnderDepot() should ignore case for windows (Mark Brophy). - - Some enhancements to the "diff-hyperlink" feature, see |PFDiffLink|. - - The plugin now translates the depot paths to local paths and vice versa - accurately by reading the client specification. This is an experimental - feature and so will very likely have bugs in it. While reporting bugs, - please include the "View" section in your client specification and the - path. See |p4UseClientViewMap| and |PFUpdateViews|. - - For consistency and to avoid potential conflict with the actual perforce - commands, most of the plugin commands that are not associated with any - external perforce command are prefixed with "PF". This involves renaming - of the following commands. If you would like to continue to use the old - command, you can add your own commands with the old names that in turn - call the new commands. - PWipeoutBufs -> PFWipeoutBufs - PDiffOff -> PFDiffOff - PToggleCkOut -> PFToggleCkOut - PRefreshFileStatus -> PFRefreshFileStatus - PRefreshActivePane -> PFRefreshActivePane - PSwitch -> PFSwitch - PSwitchPortClientUser -> PFSwitchPortClientUser - PLastMessage -> PFLastMessage - PBugReport -> PFBugReport - - :PFSettings command now optionally takes the name of the setting (as - displayed in the interactive session) and the value. The command also - supports completion, so you can type in a partial setting name and let Vim - complete it for you. - - I have changed the way the perforce client related settings are done. - Instead of using three different settings, "p4Port", "p4Client" and - "p4User", I have introduced a single setting for all the three called - |p4DefaultPreset|. The old settings are no longer recognized and these - will not appear when |PFSettings| is run. However, you can use |PSwitch| - and |PSwitchPortClientUser| commands to change to an arbitrary client at - runtime. Other than |p4DefaultPreset|, there are two new settings, - |p4CurPresetExpr| and |p4CurDirExpr|. Also, to be consistent, the - p4Password setting is no longer supported. Use "P4PASSWORD" environmental - variable for the same effect, or just let the plugin prompt you for one - when required. - - New command |PFileEdit| in filelist view. - - New plugin perforce/perforceutils.vim. Adds a useful |PFShowConflicts| - command. See |perforce-utils|. The |perforce-diff-hyperlink| feature is - also moved into this module with some enhancements. - - For consistency, some built-in options have been changed. Now all the - built-in options should be prefixed with "++". The options prefixed with a - single "+" are reserved for passing options to the external commands. The - following options have been modified to accommodate this: - Old option New option Scope ~ - +y ++y PF, PWipeoutBufs - +c ++c PDiff - - New diff mode to execute external GNU diff command to generate the diff - output. See |perforce-external-diff|. - - New commands on filelist view, PFileLaunch, PFileLog. PFilePrint has been - enhanced to print previous version if the head action is "delete" and - avoid printing binary files. - - Many misc. bug fixes and enhancements and general toning down of the code. - - A new integration with SelectBuf plugin. If you install SelectBuf, you can - execute a bunch of commands right from the buffer list. See - |perforce-selectbuf-integration|. - - The default value for 'bufhidden' setting in the perforce result buffers - is now set to "wipe". This works much better than the earlier approach to - wiping out buffers as they get unloaded, and gives better control to - users. Consequently, the g:p4HideOnBufHidden option is now replaced with - the g:p4BufHidden option. - - The plugin no longer handles all the FileChangedShell events, instead only - the events generated during the execution of the perforce commands are - captured to refresh file-status. This is so that the default Vim mechanism - is least impacted. To manually refresh the ruler see - |perforce-refresh-file-status|. - - New :PChangesDiff command in changes window. - - Fixed the argument parser to recognize context size in the diff flags - (such as "-du10"), didn't actually know that you could pass context to the - diff flags. Also, the |perforce-default-diff-format| option has been - changed from "-dd" to simply "-d". - - All the perforce commands now implement a custom completion that completes - arguments in a context sensive manner. They can also complete depot paths - by running the "dirs" and "files" commands. In addition, |PHelp| supports - help topic completion, |PFSettings| supports setting name completion and - |PFSwitch| commands supports preset completion. - - *perforce-changes-2.0* - - Renamed g:p4CodelineRoot to g:p4ClientRoot. - - Fixed a problem with choosing a default username on cygwin. - - Added support for showing ruler with the file status from "Tom Slee", - Perforce plugin with some enhancements. - - Added support to obtain the clientRoot from the perforce server, if it - is not already defined. - - More robust error handling. Now there is very less chance (or none) of - messing up the current window. - - Fixed to use setlocal instead of set command for changing some settings. - - Filelog also honors the defaultListSize option. - - Better formatting options for the form windows. - - The default option for checkout file dialog is changed from "Yes" to - "No". Use the |p4CheckOutDefault| option to get the old behavior. - - On Windows, allow execution of commands containing filename special - characters by replacing them with a [x] sequence. They are mapped as, -> - '*' -> [S], - ':' -> [C], - '?' -> [Q], - '"' -> [D], - '<' -> [L], - '>' -> [G], - '|' -> [P], -< - - Now you can use -ve revisions to indicate previous revisions from the - head. You can also use branch specifiers to mean the same file from a - different branch. Also these enhanced revision specifiers are now - acceptable anywhere. - - Extended diff to take "++c" argument to specify change number. See - |perforce-pending-change-diff|. - - Added vdiff and vdiff2 commands. Added p4UseVimDiff - option. See |perforce-vim-diff|. - - Added PFileChange command for the filelist window. - - You can now pass "++y" option to revert to skip the prompt. - - New command |PFSettings| to interactively change the settings of a - session. - - The script now has a more robust and compact architecture, which actually - helped reducing the size of the plugin even after adding many more - features. I have also consolidated all the logic into one method described - by a set of metadata variables. Adding new features in the future should - be easier. - - The opened list is now better than ever. You can use it to quickly reach - to a file that you have already checked out of perforce. See - |perforce-filelist| - - You now have a way to preserve the perforce windows from getting wipedout - as soon as they are hidden. This feature can be used if you are intending - to keep them opened for a long time (such as "opened" list windows). - - You can now change the name of the depot from the default "depot". This is - useful if you have multiple depots in your system. - - I have extended the command syntax with the - |perforce-command-mode-specifier| for the more demanding users. - - The "change" command now takes perforce filename patterns to filter out - the initial list of files that should be included in the change. The - "submit" command already does this. See |perforce-changelist|. - - You can now press "q" to quit in read-only perforce windows (David - Fishburn). - - Improved the handling of back-slashes and spaces in filenames. - - The vim built-in :w and :wq commands work exactly like the :W and :WQ - commands respectively. For "submit", they now prompt for confirmation, - which can be suppressed by passing a "-y" option. - - Now the specification windows are regular buffers. For reasons on why this - is much better than the earlier approach, read towards the end of - |perforce-forms|. - - The plugin now uses try/finally blocks to avoid leaking any changes done - to global settings in case of unexpected errors. - - The submit command now detects partial errors that results in an - automatic changelist creation, and modify the template appropriately. This - also works while creating a new changelist, so that after saving the - changelist, you can just undo and continue making further changes. - See |perforce-submit|. - - Hyperlink the diff window to the source. Pressing O or <CR> on a line - takes you to the source line. See |perforce-diff-mode|. - - Fixed some bugs with passing special characters and whitespace to shell. - - A dummy option "-dd" to mean the default diff format. See - |perforce-default-diff-format| - - A new ftplugin for perforce forms which can be made to work even while - starting forms from p4 directly. See |perforce-ftplugin| - - This help file itself is new. - - *perforce-todo* - *perforce-known-issues* -Not in any particular order: - - PChangesDescribeCurrentItem doesn't work for pending changelists from - other clients. - - A deleted file is showing up as unopened. - - Consider #none also as revision in the syntax highlighting. - - I don't think the p4Depot setting is being handled correctly. We need to - investigate how depots created using "p4 depot" are used. - - There is a Syntax highlighting for: "<file>#1 - added as <file>". How is - this message generated? - - When you open a spec window with perforce wildcard patterns as arguments - (such as "P4 submit .../*") saving works as long as you don't change the - current working directory of Vim after creating the spec window, otherwise - because of some weird behavior in Vim, you get an E212. - - You can't login using the plugin. - - <pfitem> should be handled at a higher level for it to be more useful. - - During the auto-checkout, Vim will give error E788 if the ftplugin uses - :compiler command. This is a known issue with Vim7.0 release, and might - get fixed in a future patch. - - When PFSwitch fails because the perforce server is not up, you are forced - to switch to another setting and come back to it to select it again. - - When reverting files from files view, if you select No for the prompt, it - still refreshes the window. - - *perforce-wishlist* -Here is a list of changes that I think will be useful to do, in no particular -order: - - PChangeSubmit etc. should have menu entries in change menu. - - Sort change lists and show those that are by the current client and - others separately. - - The "nmap <buffer>" output can probably be used to generate a simple help. - - A command to rename files (Raj). Invoke integrate and delete internally, - for convenience. - - It will be nice if the change number is automatically remembered. - Also, we should be able to set a change number which should be - automatically applied to all the edits, deletes etc. - - How can we support interactive resolves? Will it be worth doing it? - - In filelist view, allow visual select on the files to be operated upon - (for revert etc.). - - I should be able to parse the output of p4 resolve using this command: - sh -c "while true; do echo s ;done" | p4 resolve - - How can we avoid prompting for checkout when the current vim session is - in view mode (-R option)? For now just use PFToggleCkOut command in such - sessions. - - The script now has knowledge of client-view settings. There may still be - places that assume that the branch name and local directory name are same. - - The menus can be further improved. - - The list specific menus should be disabled unless you are in that - window. - - Backup/Restore commands for opened files will be useful. For now, just use - the included shell scripts. - - A simple p4win style explorer will be helpful for quickly browsing the - depot. - - Negative revisions for dates also? Is it possible using vim functions? - - Check for unsaved buffers during submit. Requires us to look into the - buffer list. - - There should be an option to show/hide deleted files in the filelists - (PFiles). - - The PPasswd can't be used when either the old or new password is empty. - - There should be an option to have a single perforce-log window where all - the output gets appended, instead of opening new windows for each command. - - We should be able to pass file patterns to be used as the View while - creating a new label command. - - We should have a feature to diff2 in labels and changes views when started - with a filename as an argument. Also diff from changes view. - - A command to refresh only the files that are in a label. Works well for - lables containing only a partial list of files. - - Supporting backquotes could be useful when the shell is unixy. - - In list views (and filelog view), we should be able to map the mouse - presses such a way that single mouse click results in selecting the entire - line and mouse drag automatically selects the entire line. We will then - need to make sure all the list view local commands will work with visual - mode. - - If the current buffer is a directory (i.e. opened with the vim - filebrowser), it would be nice if the plugin could simply append '...' - to the relative path, so something like PSync would make perforce sync - all files under the current directory (Mark). In otherwords, it would make - sense to append '...' to the directory name whenever a command that - defaults to current buffer is executed on a directory buffer. - - How about using v:dying to determine if the vim session is crashing and - preserve the spec buffers? - - Executing "admin" command shouldn't open up a new window. - - Better support for "monitor" command. - - There should be an option to position the current line in the diff (if - exists) (like view current line in the diff). - - While viewing a directory, it will be nice if the file completion - happens relative to the directory that is being viewed, rather than the - working directory of Vim. We probably should have an option to turn it - off. - - It is possible to have a command that starts p4win with options such as - -s. - - vdiff should print the have version not head version, unless this - information is for some reason not available. - - While doing custom expansion for files (:PF command), the spaces in the - filenames should be escaped. - - For diff hyper linking, there should be a way to always open the depot - file (even for the context lines). - - In DiffLink, detect the column position also. Also add a way to jump the - diff region containing the current line. - - There should be a way to force deletion from the users list (-f option). - - Need a "blame" built-in command to produce annotated output with change - numbers in them. - - *perforce-bugreporting* -Please read the entire plugin online help before you report any bugs, as it will -help clear up scenarios which may not indeed be a bug. In addition, - - Refer the p4 user manual and online help to be clear about the right - behavior. - - Check if it is already mentioned in the |perforce-limitations| or - |perforce-known-issues| sections. - - Run :PFBugReport command to generate "perforcebugrep.txt" file in the - current directory and attach that with your email. Before sending this - out, check to make sure it doesn't contain any confidential information! - -Please send your reports to hari_vim at yahoo dot com. - - *perforce-acknowledgements* -- Tom Slee (tslee at ianywhere dot com) for his idea of creating a status - bar with the p4 fstat information (see - http://www.vim.org/script.php?script_id=167). -- Leo L. Schwab (leo dot schwab at openwave dot com) for reporting problems and - helping me with debugging them. -- David Fishburn (fishburn at ianywhere dot com) for his idea with mapping the - 'q' key to quit non-editable perforce windows, and reporting various bugs. -- Mark Brophy (mbrophy at esmertec dot com) for his ideas with using P4CONFIG - and others that allow dynamic configuration. -- Various others for sending bugs, patches, ideas and feedback. Some of them - are: - - Denis Perelyubskiy (denisp at CS dot UCLA dot EDU) - - Kevin McCarthy (tunacat at yahoo dot com) - - Paul Wright (paul at noctua dot org dot uk) - - Reva Revadigar (reva dot revadigar at autodesk dot com) - - Peter Hutkins (PHUTKINS at altera dot com) - - Brett Humphreys (bretth at aiinet dot com) - - Craig Emery (craig dot emery at ntlworld dot com) - - vim6:tw=80:ts=8:ft=help:ai:sw=4:et diff --git a/.vim/ftplugin/perforce.vim b/.vim/ftplugin/perforce.vim deleted file mode 100755 index e3bf7d4..0000000 --- a/.vim/ftplugin/perforce.vim +++ /dev/null @@ -1,59 +0,0 @@ -" Perforce spec filetype plugin file -" Language: Perforce Spec File -" Maintainer: Hari Krishna Dara <hari_vim at yahoo dot com> -" Last Change: 13-Jan-2006 @ 17:38 -" Since Version: 1.4 -" Revision: 1.0.6 -" Plugin Version: 2.1 -" Download From: -" http://vim.sourceforge.net/scripts/script.php?script_id=240 -" TODO: - -" Only do this when not done yet for this buffer -"if exists("b:did_ftplugin") -" finish -"endif - -" Don't load another plugin for this buffer -let b:did_ftplugin = 1 - -" Set some options suitable for pure text editing. -setlocal tabstop=8 -setlocal softtabstop=0 -setlocal shiftwidth=8 -setlocal noexpandtab -setlocal autoindent -setlocal formatoptions=tcqnl -setlocal comments=:#,fb:- -setlocal wrapmargin=0 -setlocal textwidth=80 -let b:undo_ftplugin = 'setl ts< sts< sw< et< ai< fo< com< wm< tw<' - -if !exists("loaded_perforce_ftplugin") -let s:patterns{'Change'} = '\%(^Description:\s*\_s\?\s*\)\zs\S\|^Description:' -let s:patterns{'Branch'} = '\%(^View:\s*\_s\?\s*\)\zs\S\|^View:' -let s:patterns{'Label'} = '\%(^View:\s*\_s\?\s*\)\zs\S\|^View:' -let s:patterns{'Client'} = '\%(^View:\s*\_s\?\s*\)\zs\S\|^View:' -let s:patterns{'Job'} = '\%(^Job:\s\+\)\@<=new\>\|\%(^Description:\s*\_s\?\s*\)\zs\S\|^Description:' -let s:patterns{'Job_Spec'} = '^Fields:' -let s:patterns{'User'} = '^User:' -let s:patterns{'Depot'} = '\%(^Description:\s*\_s\?\s*\)\zs\S\|^Description:' -let s:patterns{'Group'} = '\%(^Users:\s*\_s\?\s*\)\zs\S\|^Users:' -" Position cursor on the most appropriate line based on the type of spec being -" edited. -function! s:PositionLine() - let specPattern = '^# A Perforce \(.*\) Specification.$' - if getline(1) =~ specPattern - let spec = substitute(substitute(getline(1), specPattern, '\1', ''), ' ', - \ '_', 'g') - if spec != "" && exists('s:patterns'. spec) && - \ search(s:patterns{spec}, 'w') != 0 - let b:p4Pattern = s:patterns{spec} - normal! zz - endif - endif -endfunction -let loaded_perforce_ftplugin=1 -endif - -call s:PositionLine() diff --git a/.vim/ftplugin/selectbuf_perforce.vim b/.vim/ftplugin/selectbuf_perforce.vim deleted file mode 100755 index 0836aa0..0000000 --- a/.vim/ftplugin/selectbuf_perforce.vim +++ /dev/null @@ -1,15 +0,0 @@ - -if !exists('loaded_selectbuf') || loaded_selectbuf < 303 - finish -endif - -noremap <Leader>pfa :SBExec PF add<CR> -noremap <Leader>pfg :SBExec PF sync<CR> -noremap <Leader>pfe :SBExec PF edit<CR> -noremap <Leader>pft :SBExec PF delete<CR> -noremap <Leader>pfr :SBExec PF revert<CR> -noremap <Leader>pfs :SBExec PF submit<CR> -noremap <Leader>pfl :SBExec PF lock<CR> -noremap <Leader>pfu :SBExec PF unlock<CR> -noremap <Leader>pfd :SBExec PF diff<CR> -noremap <Leader>pf2 :SBExec PF diff2<CR> diff --git a/.vim/perforce/bakup.sh b/.vim/perforce/bakup.sh deleted file mode 100755 index 4b459c3..0000000 --- a/.vim/perforce/bakup.sh +++ /dev/null @@ -1,396 +0,0 @@ -#!/bin/bash -# Author: Hari Krishna Dara ( hari_vim at yahoo dot com ) -# Last Change: 17-Mar-2004 @ 18:47 -# Requires: -# - bash or ksh (tested on cygwin and MKS respectively). -# - Info Zip for the -z option to work (comes with linux/cygwin). Download for -# free from: -# http://www.info-zip.org/ -# - GNU tar for the -a option to work (comes with linux/cygwin). -# Version: 1.4.2 -# Licence: This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License. -# See http://www.gnu.org/copyleft/gpl.txt -# Description: -# Shell script to take backup of all the open files in perforce SCM. -# -#TODO: -# - Zip comment option -zz is no longer working? -# - To create cpio archives, I can use "cpio -o -H | gzip" command. -# - Option to generate a diff at the end. -# - Option to restrict by type (useful to avoid huge binary files). -# - Support to run zip from a different directory (to avoid certain path -# component from getting into zipfile). - -usage() -{ -cat <<END -$0 [<backup dir>] [<source dir>] ... -$0 -h -n -q -v -z -zz [-c <change number>] [-t <backup dir>] [-r <backup root>] [[-s <source dir>] ...] - -t specify full path name to the target directory. If -z is specified this - becomes the path to the zip file name. - -r set the root for creating the default backup dir/zip file. Not used if - "backup dir" is specified. You can also set BAKUP_ROOT environmental - variable. Defaults to p: (p drive), because that is what it is on my - system :). - -i incremental backup, which makes the program use the previous backup - directory/archive for that day (if it exists) instead of creating a new - one. For tar (with "-a" option), you will have to provide one of the - relevant options to force reuse an existing archive ("-ar" e.g.) or the - existing archive will simply get overwritten. However this will not work - with compressed tar archives. You can also specify any existing backup - directory/archive path explicitly by using the "-t" option. - -a create a tar file instead of copying the files. You can specify the - tar file name using -t option. - -a[-|--]<taropt> - Pass -taropt to tar command. - Ex: - - Pass "-aC <dir>" or "-adirectory=<dir>" to cd to a directory before - creating the tar file (thus dropping file component). - - Pass "-az" to gzip the created tar file. - -z create a zip file instead of copying the files. You can specify the - zip file name using -t option. - -z[-]<zipopt> - Pass -zipopt to zip command. - Ex: Pass -zz for a prompt from zip to enter a comment. - -s limit to open files matching the given wildcard (local or depot). This - can be repeated multiple times to specify multiple source directories. - You can pass in anything that the 'p4 opened' command itself accepts. - -c limit the files to those specified in the change number, in addition to - the -s option. This can't be repeated multiple times though. - -n don't execute any commands, just show what is going to be done. Does not - currently work with -z option. - -q quite mode, no messages - -v verbose mode, print messages (the default). - -h print help message (this message) and exit - The first unspecified directory is treated as target directory, and the - remaining directories are treated as source directories. The '-n' option can - be used to generate a batch script that can be run later. The source - directory can be in depot or local format (NO BACKSLASHES PLEASE). Do not - combine multiple options into one argument. -Examples: - bakup.sh - - Backup all the open files into a default generated backup dir. in p: - drive (p: driver is the default backup directory). - bakup.sh mybak c:/dev/branch/src - - Backup open files only under 'c:/dev/branch/src' into 'mybak' - directory. - bakup.sh -s //depot/branch/src -s //depot/branch/cfg - - Backup open files only under 'src' and 'cfg' into the default bakup - dir. - - You could add -z option to all the above usages to create a zip file - instead of creating a directory. You need to have Info-Zip installed in the - path for this to work. - - bakup.sh -n > mybackup.bat - - Generates a 'mybackup.bat' batch file that can be run at a later - time to take a backup. The files to be backed up are based on the - time the script was generated, so it should be regenerated if the - list has changed since then. -END -exit 1 -} - -generateTargetDirName() -{ - today=`date +"%d-%b-%Y"` - inc=1 - #echo "---first time" - tDir="$targetRoot/bakup-$today" - prevDir=$tDir - while [ -d $tDir -o -f $tDir.* ]; do - inc=$[inc + 1] - prevDir=$tDir - tDir="$targetRoot/bakup-${today}_$inc" - #echo "---subsequent time inc=$inc tDir=$tDir" - done - if [ $incrementalMode -ne 0 ]; then - tDir=$prevDir # Backup one level to use an existing db. - fi - echo "$tDir" -} - -getExtOpt() -{ - archiveOpt=${1/[-+]$2/} - case $archiveOpt in - --*) - ;; - -??*) # Mistyped long option - archiveOpt="-$archiveOpt" - ;; - -*) - ;; - ??*) # Long option. - archiveOpt="--$archiveOpt" - ;; - *) - archiveOpt="-$archiveOpt" - ;; - esac - echo $archiveOpt -} - -#getExtOpt '-a--directory' 'a' -#getExtOpt '-a-directory' 'a' -#getExtOpt '-adirectory' 'a' -#getExtOpt '-aC' 'a' -#getExtOpt '-a-C' 'a' -#exit - -checkOptArg=' - shift; - if [ $# -eq 0 ]; then - usage; - fi -' - -testMode=0 -archiveOpts='' -chDirectory='' # If set, the listing is generated relative to this dir. -archiveMode=0 -verboseMode=1 -targetDir="" -targetRoot="" -sourceDirs="" -changeNumber="" -compressedTar=0 -incrementalMode=0 -until [ $# -eq 0 ]; do - case $1 in - -h|-help|--help) - usage - ;; - -v) - verboseMode=1 - ;; - -q) - verboseMode=0 - ;; - -i) - incrementalMode=1 - ;; - -a) - archiveMode=2 # Tar. - verboseMode=0 # Turn on quite mode, as zip will anyway show the files. - testMode=1 # Turn on test mode, so we won't copy files. - ;; - -a*) - # Need to take care of options with optional args. - extOpt=`getExtOpt $1 a` - if [ $extOpt = -z -o $extOpt = -Z -o $extOpt = -j ]; then - compressedTar=1 - tarExt=`echo $extOpt | awk 'BEGIN{ext["-j"]="bz2";ext["-z"]="gz";ext["-Z"]="Z";}{print ext[$0];}'` - fi - archiveOpts="${archiveOpts} $extOpt" - case $extOpt in - --directory) - chDirectory=${extOpt/*=} - ;; - -C) - eval $checkOptArg - chDirectory=$1 - #echo "---setting chDirectory=$chDirectory" - archiveOpts="${archiveOpts} $chDirectory" - ;; - esac - ;; - -z) - archiveMode=1 # Zip. - verboseMode=0 # Turn on quite mode, as zip will anyway show the files. - testMode=1 # Turn on test mode, so we won't copy files. - ;; - -z*) - # Need to take care of options with optional args. - archiveOpts="${archiveOpts} `getExtOpt $1 z`" - ;; - -n) - testMode=1 - verboseMode=0 - ;; - -c) - eval $checkOptArg - changeNumber=$1 - ;; - -t) - eval $checkOptArg - targetDir=$1 - ;; - -r) - eval $checkOptArg - targetRoot=$1 - ;; - -s) - eval $checkOptArg - sourceDirs="$sourceDirs $1" - #echo "---setting sourceDirs=$sourceDirs" - ;; - -?) - usage - ;; - *) - if [ "$targetDir" = "" ]; then - #echo "---setting targetDir=$targetDir" - targetDir=$1 - else - #echo "---appending sourceDirs=$1" - sourceDirs="$sourceDirs $1" - fi - ;; - esac - shift -done - -# For tar, we can add -a option only if no other equivalent option is specified. -if [ $archiveMode -eq 2 ]; then - case $archiveOpts in - *-[Acdtrux]*) - ;; - *) - archiveOpts="$archiveOpts -c" - ;; - esac -fi - -if [ x${targetDir}x = xx -a x${targetRoot}x = xx ]; then - targetRoot=$BAKUP_ROOT - if [ "$targetRoot" = "" ]; then - targetRoot="p:" - fi -fi - -if [ "$targetDir" = "" ]; then - targetDir=`generateTargetDirName` -fi - -if [ "$sourceDirs" = "" ]; then - # By default backup all the open files. - sourceDirs="//..." -fi - - -# Create a dir if it doesn't exist, exit on error. -createDir() -{ - if ! [ -d "$1" ]; then - - if [ $testMode -eq 1 -o $verboseMode -eq 1 ]; then - echo "mkdir -p $1" 1>&4 - fi - - if [ $testMode -eq 0 ]; then - mkdir -p "$1" - if [ $? -ne 0 ]; then - echo "Error creating $1" 1>&2 - exit 1 - fi - fi - fi -} - - -#if [ $testMode -eq 1 ]; then -# echo "Running in test mode" -#fi - -if [ $archiveMode -eq 0 ]; then - createDir $targetDir 4>&1 -fi - -if [ $verboseMode -eq 1 ]; then - echo "Copying to target directory: $targetDir" -fi - -# Testing for $BASH will not work, if you happen to use the cygwin sh instead of -# bash. -unset PWD -codelineRoot=`p4 info | sed -n -e 's;\\\\;/;g' -e 's/Client root: //p'` -#echo "---codelineRoot=$codelineRoot" -rootDirLength=${#codelineRoot} - -if [ $archiveMode -eq 1 ]; then - fileExt='' - if [ ${targetDir%.zip} = $targetDir ]; then - fileExt='.zip' - fi - pipeCmd="zip ${archiveOpts} -@ ${targetDir}${fileExt}" - echo "Using: '${pipeCmd}' to create zip archive" -elif [ $archiveMode -eq 2 ]; then - fileExt='' - if [ $compressedTar -eq 1 -a ${targetDir%.tar.$tarExt} = $targetDir ]; then - fileExt=".tar.$tarExt" - elif [ $compressedTar -ne 1 -a ${targetDir%.tar} = $targetDir ]; then - fileExt='.tar' - fi - pipeCmd="tar -vf ${targetDir}${fileExt} ${archiveOpts} -T -" - echo "Using: '${pipeCmd}' to create tar archive" -else - pipeCmd="cat" -fi - -exec 4>&1; { - for sourceDir in $sourceDirs; do - if [ ! -f $sourceDir ]; then - case $sourceDir in - *...) - ;; - */) - sourceDir="${sourceDir}..." - ;; - *) - sourceDir="${sourceDir}/..." - ;; - esac - fi - if [ "$changeNumber" = "" ]; then - openedCmd="p4 opened $sourceDir" - else - openedCmd="p4 opened -c $changeNumber $sourceDir" - fi - if [ $verboseMode -eq 1 ]; then - echo "Collecing list of open files using: $openedCmd" 1>&4 - fi - - # FIXME: I couldn't get it working with the following IFS, don't know - # why. So as a temp. work-around, I am temporarily substituting spaces - # with '|' in sed and converting them back to spaces in the start of the - # loop. - #IFS="\n\r" - openedFiles=`$openedCmd | \ - sed -e '/ - delete \(default \)\?change /d' \ - -e 's/#.*//' | - p4 -x - where | \ - sed -e 's;.\+/[^/]\+/\([^ /]\+\) //.*\1 \(.*\1\);\2;' \ - -e "s;^${chDirectory}/*;;" \ - -e 's/ /|/g' \ - -e 's;\\\\;/;g'` - for file in `echo $openedFiles`; do - file=${file//\|/ } - #echo "---file = $file" 1>&4 - dir=`dirname "$file"` - # Relative to the codeline root. - tgtDir="${targetDir}/${dir:$rootDirLength}" - #echo "---tgtDir = $tgtDir" 1>&4 - - if [ $archiveMode -eq 0 ]; then - createDir "$tgtDir" - fi - - if [ $archiveMode -ne 0 ]; then - echo $file 1>&3 - elif [ $testMode -eq 1 -o $verboseMode -eq 1 ]; then - echo "cp \"$file\" \"$tgtDir\"" 1>&4 - fi - if [ $testMode -eq 0 ]; then - cp "$file" "$tgtDir" - if [ $? -ne 0 ]; then - echo "Error copying $1" 1>&2 - exit 1 - fi - fi - done - done -} 3>&1 | $pipeCmd - -# vim6: et sw=4 diff --git a/.vim/perforce/p4Utils.sh b/.vim/perforce/p4Utils.sh deleted file mode 100755 index bcc92c6..0000000 --- a/.vim/perforce/p4Utils.sh +++ /dev/null @@ -1,24 +0,0 @@ -# Get the list of unopened files under the given $1/$2 directory. -# It should be possible to implement the logic by using temp files and diff, -# but this was more challenging to me :) -# Ex: -# unOpenedFiles=`getUnOpenedFiles "$root" "src"` -getUnOpenedFiles() { - path=$1 - dir=$2 - p4 opened $path/$dir/... \ - | sed -e 's/.*'$dir'/'$dir'/' -e 's/#.*$//' \ - | perl -n -e ' - print; - END - { - # Merge the opened list with all the files under BaseClasses. - foreach $f (`find '$path/$dir' -type f | sed -e "s/.*'$dir'/'$dir'/"`) - { - print $f; - } - }' \ - | sort -f \ - | uniq -c \ - | sed -n -e 's/\s*1\s*//p' -} diff --git a/.vim/perforce/perforcebugrep.vim b/.vim/perforce/perforcebugrep.vim deleted file mode 100755 index 1bf1894..0000000 --- a/.vim/perforce/perforcebugrep.vim +++ /dev/null @@ -1,97 +0,0 @@ -" perforcebugrep.vim: Generate perforcebugrep.txt for perforce plugin. -" Author: Hari Krishna (hari_vim at yahoo dot com) -" Last Change: 29-Aug-2006 @ 17:57 -" Created: 07-Nov-2003 -" Requires: Vim-7.0, perforce.vim(4.0) -" Version: 2.1.0 -" Licence: This program is free software; you can redistribute it and/or -" modify it under the terms of the GNU General Public License. -" See http://www.gnu.org/copyleft/gpl.txt - -if !exists("loaded_perforce") - runtime plugin/perforce.vim -endif -if !exists("loaded_perforce") || loaded_perforce < 400 - echomsg "perforcebugrep: You need a newer version of perforce.vim plugin" - finish -endif - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - -" Based on $VIM/bugreport.vim -let _more = &more -try - PFInitialize " Make sure it is autoloaded. - - set nomore - call delete('perforcebugrep.txt') - if has("unix") - !echo "uname -a" >perforcebugrep.txt - !uname -a >>perforcebugrep.txt - endif - - redir >>perforcebugrep.txt - version - - echo "Perforce plugin version: " . loaded_perforce - echo "Genutils plugin version: " . loaded_genutils - - echo "--- Perforce Plugin Settings ---" - for nextSetting in perforce#PFGet('s:settings') - let value = perforce#PFCall('s:_', nextSetting) - echo nextSetting.': '.value - endfor - echo "s:p4Contexts: " . string(perforce#PFCall('s:_', 'Contexts')) - echo "g:p4CurDirExpr: " . perforce#PFCall('s:_', 'CurDirExpr') - echo "g:p4CurPresetExpr: " . perforce#PFCall('s:_', 'CurPresetExpr') - echo "s:p4Client: " . perforce#PFCall('s:_', 'Client') - echo "s:p4User: " . perforce#PFCall('s:_', 'User') - echo "s:p4Port: " . perforce#PFCall('s:_', 'Port') - - echo "--- Current Buffer ---" - echo "Current buffer: " . expand('%') - echo "Current directory: " . getcwd() - let tempDir = perforce#PFCall('s:_', 'TempDir') - if isdirectory(tempDir) - echo 'temp directory "' . tempDir . '" exists' - else - echo 'temp directory "' . tempDir . '" does NOT exist' - endif - if exists('b:p4OrgFileName') - echo 'b:p4OrgFileName: ' . b:p4OrgFileName - endif - if exists('b:p4Command') - echo 'b:p4Command: ' . b:p4Command - endif - if exists('b:p4Options') - echo 'b:p4Options: ' . b:p4Options - endif - if exists('b:p4FullCmd') - echo 'b:p4FullCmd: '. b:p4FullCmd - endif - if exists('g:p4FullCmd') - echo 'g:p4FullCmd: '. g:p4FullCmd - endif - setlocal - - echo "--- p4 info ---" - let info = perforce#PFCall('perforce#PFIF', '1', '4', 'info') - " The above resets redir. - redir >>perforcebugrep.txt - echo info - - set all -finally - redir END - let &more = _more - sp perforcebugrep.txt -endtry - -" Restore cpo. -let &cpo = s:save_cpo -unlet s:save_cpo - -" vim6:fdm=marker et sw=2 diff --git a/.vim/perforce/perforcemenu.vim b/.vim/perforce/perforcemenu.vim deleted file mode 100755 index 6d0be2b..0000000 --- a/.vim/perforce/perforcemenu.vim +++ /dev/null @@ -1,335 +0,0 @@ -" perforcemenu.vim: Create a menu for perforce plugin. -" Author: Hari Krishna (hari_vim at yahoo dot com) -" Last Change: 28-Aug-2006 @ 22:50 -" Created: 07-Nov-2003 -" Requires: Vim-6.2, perforce.vim(4.0) -" Version: 2.1.0 -" Licence: This program is free software; you can redistribute it and/or -" modify it under the terms of the GNU General Public License. -" See http://www.gnu.org/copyleft/gpl.txt - -if !exists("loaded_perforce") - runtime plugin/perforce.vim -endif -if !exists("loaded_perforce") || loaded_perforce < 400 - echomsg "perforcemenu: You need a newer version of perforce.vim plugin" - finish -endif - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - -function! s:Get(setting, ...) - if exists('g:p4'.a:setting) - return g:p4{a:setting} - endif - - if exists('*perforce#PFCall') - let val = perforce#PFCall('s:_', a:setting) - if val == '' && a:0 > 0 - let val = a:1 - endif - return val - endif - return 0 -endfunction - -function! s:PFExecCmd(cmd) " {{{ - if exists(':'.a:cmd) == 2 - exec a:cmd - else - call perforce#PFCall("s:EchoMessage", 'The command: ' . a:cmd . - \ ' is not defined for this buffer.', 'WarningMsg') - endif -endfunction -command! -nargs=1 PFExecCmd :call <SID>PFExecCmd(<q-args>) " }}} -let s:loaded_perforcemenu = 1 - -" CreateMenu {{{ -if s:Get('EnableMenu') || s:Get('EnablePopupMenu') " [-2f] -function! s:CreateMenu(sub, expanded) - if ! a:expanded - let fileGroup = '.' - else - let fileGroup = '.&File.' - endif - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '&Add :PAdd<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . 'S&ync :PSync<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '&Edit :PEdit<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '-Sep1- :' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . - \ '&Delete :PDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '&Revert :PRevert<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '-Sep2- :' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . 'Loc&k :PLock<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . - \ 'U&nlock :PUnlock<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '-Sep3- :' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '&Diff :PDiff<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . 'Diff&2 :PDiff2<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . - \ 'Revision\ &History :PFilelog<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . 'Propert&ies ' . - \ ':PFstat -C<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '&Print :PPrint<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce' . fileGroup . '-Sep4- :' - if a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.' . - \ 'Resol&ve.Accept\ &Their\ Changes<Tab>resolve\ -at ' . - \ ':PResolve -at<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.' . - \ 'Resol&ve.Accept\ &Your\ Changes<Tab>resolve\ -ay :PResolve -ay<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.' . - \ 'Resol&ve.&Automatic\ Resolve<Tab>resolve\ -am :PResolve -am<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.' . - \ 'Resol&ve.&Safe\ Resolve<Tab>resolve\ -as :PResolve -as<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.' . - \ 'Resol&ve.&Force\ Resolve<Tab>resolve\ -af :PResolve -af<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.' . - \ 'Resol&ve.S&how\ Integrations<Tab>resolve\ -n :PResolve -n<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.-Sep5- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.Sa&ve\ Current\ Spec ' . - \':PFExecCmd W<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&File.Save\ and\ &Quit\ ' . - \'Current\ Spec :PFExecCmd WQ<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Opened\ Files :POpened<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Refresh\ Active\ Pane ' . - \ ':PRefreshActivePane<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.-Sep6- :' - else - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&View.&BranchSpecs :PBranches<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Changelist.' . - \ '&Pending\ Changelists :PChanges -s pending<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Changelist.' . - \ '&Submitted\ Changelists :PChanges -s submitted<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&View.Cl&ientSpecs :PClients<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Jobs :PJobs<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Labels :PLabels<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Users :PUsers<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Depots :PDepots<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Opened\ Files :POpened<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&View.&Refresh\ Active\ Pane ' . - \ ':PRefreshActivePane<CR>' - endif - - if a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Settings.' . - \ '&Switch\ Port\ Client\ User '. - \ ':call perforce#PFCall("s:SwitchPortClientUser")<CR>' - let p4Presets = split(perforce#PFGet('s:p4Presets'), ',') - if len(p4Presets) > 0 - let index = 0 - while index < len(p4Presets) - exec 'amenu <silent>' a:sub.'&Perforce.&Settings.&'.index.'\ ' - \ .escape(p4Presets[index], ' .') ':PFSwitch' index.'<CR>' - let index = index + 1 - endwhile - endif - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.New\ &Submission\ Template :PSubmit<CR>' - else - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.&New :PChange<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.' . - \ '&Edit\ Current\ Changelist :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.' . - \ 'Descri&be\ Current\ Changelist :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.' . - \ '&Delete\ Current\ Changelist :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.' . - \ 'New\ &Submission\ Template :PSubmit<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.-Sep- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.' . - \ 'View\ &Pending\ Changelists :PChanges -s pending<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Changelist.' . - \ '&View\ Submitted\ Changelists :PChanges -s submitted<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Branch :PBranch<CR>' - else - exec 'amenu <silent> ' . a:sub . '&Perforce.&Branch.&New :PBranch<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Branch.' . - \ '&Edit\ Current\ BranchSpec :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Branch.' . - \ 'Descri&be\ Current\ BranchSpec :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Branch.' . - \ '&Delete\ Current\ BranchSpec :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Branch.-Sep- :' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Branch.&View\ BranchSpecs :PBranches<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label :PLabel<CR>' - else - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.&New :PLabel<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.' . - \ '&Edit\ Current\ LabelSpec :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.' . - \ 'Descri&be\ Current\ LabelSpec :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.' . - \ '&Delete\ Current\ LabelSpec :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.-Sep1- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.' . - \ '&Sync\ Client\ ' . s:Get('Client') . '\ to\ Current\ Label ' . - \ ':PFExecCmd PLabelsSyncClient<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.' . - \ '&Replace\ Files\ in\ Current\ Label\ with\ Client\ ' . - \ s:Get('Client') . '\ files ' . ':PFExecCmd PLabelsSyncLabel<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Label.-Sep2- :' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Label.&View\ Labels :PLabels<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.Cl&ient :PClient<CR>' - else - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.Cl&ient.&New :PClient +P<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.Cl&ient.' . - \ '&Edit\ Current\ ClientSpec :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.Cl&ient.' . - \ 'Descri&be\ Current\ ClientSpec :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.Cl&ient.' . - \ '&Delete\ Current\ ClientSpec :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.' . - \ 'Cl&ient.&Edit\ ' . escape(s:Get('Client', 'Current Client'), ' ') . - \ ' :PClient<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.Cl&ient.-Sep- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.Cl&ient.&Switch\ to\ Current' . - \ '\ Client :exec "PFSwitch ' . s:Get('Port') . - \ ' " . perforce#PFCall("s:GetCurrentItem")<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.Cl&ient.&View\ ClientSpecs :PClients<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&User :PUser<CR>' - else - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&User.&New :PUser +P<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&User.' . - \ '&Edit\ Current\ UserSpec :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&User.' . - \ 'Descri&be\ Current\ UserSpec :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&User.' . - \ '&Delete\ Current\ UserSpec :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&User.&Edit\ ' . - \ escape(s:Get('User', 'Current User'), ' ') . ' :PUser<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&User.-Sep- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.&User.&Switch\ to\ Current' . - \ '\ User :exec "PFSwitch ' . s:Get('Port') . ' ' . - \ s:Get('Client') . ' " . perforce#PFCall("s:GetCurrentItem")<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&User.&View\ Users :PUsers<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job :PJob<CR>' - else - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.&New :PJob<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.' . - \ '&Edit\ Current\ JobSpec :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.' . - \ 'Descri&be\ Current\ JobSpec :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.' . - \ '&Delete\ Current\ JobSpec :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.-Sep1- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.&Edit\ Job&Spec ' . - \ ':PJobspec<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.-Sep2- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Job.&View\ Jobs :PJobs<CR>' - endif - - if a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Depot.&New :PDepot<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Depot.' . - \ '&Edit\ Current\ DepotSpec :PFExecCmd PItemOpen<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Depot.' . - \ 'Descri&be\ Current\ DepotSpec :PFExecCmd PItemDescribe<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Depot.' . - \ '&Delete\ Current\ DepotSpec :PFExecCmd PItemDelete<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Depot.-Sep- :' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Depot.&View\ Depots :PDepots<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.Open\ Current\ File\ From\ A¬her\ Branch :E<CR>' - else - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Tools.Open\ Current\ File\ From\ A¬her\ Branch ' . - \ ':E<CR>' - endif - - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.-Sep7- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.Sa&ve\ Current\ Spec ' . - \':PFExecCmd W<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.Save\ and\ &Quit\ ' . - \'Current\ Spec :PFExecCmd WQ<CR>' - endif - - exec 'amenu <silent> ' . a:sub . '&Perforce.-Sep8- :' - exec 'amenu <silent> ' . a:sub . '&Perforce.Re-Initial&ze :PFInitialize<CR>' - if ! a:expanded - exec 'amenu <silent> ' . a:sub . '&Perforce.&Help :PHelp<CR>' - else - exec 'amenu <silent> ' . a:sub . '&Perforce.&Help.&General :PHelp<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Help.&Simple :PHelp simple<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Help.&Commands :PHelp commands<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Help.&Environment :PHelp environment<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Help.&Filetypes :PHelp filetypes<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Help.&Jobview :PHelp jobview<CR>' - exec 'amenu <silent> ' . a:sub . - \ '&Perforce.&Help.&Revisions :PHelp revisions<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Help.&Usage :PHelp usage<CR>' - exec 'amenu <silent> ' . a:sub . '&Perforce.&Help.&Views :PHelp views<CR>' - endif -endfunction -endif -" }}} - -" -" Add menu entries if user wants. -" - -silent! unmenu Perforce -silent! unmenu! Perforce -if s:Get('EnableMenu') - call s:CreateMenu('', s:Get('UseExpandedMenu')) -endif - -silent! unmenu PopUp.Perforce -silent! unmenu! PopUp.Perforce -if s:Get('EnablePopupMenu') - call s:CreateMenu('PopUp.', s:Get('UseExpandedPopupMenu')) -endif - -" We no longer need this. -silent! delf s:CreateMenu -silent! delf s:Get - -let v:errmsg = '' - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - -" vim6:fdm=marker et sw=2 diff --git a/.vim/perforce/perforceutils.vim b/.vim/perforce/perforceutils.vim deleted file mode 100755 index db093bb..0000000 --- a/.vim/perforce/perforceutils.vim +++ /dev/null @@ -1,39 +0,0 @@ -" perforceutils.vim: Add-On utilities for perforce plugin. -" Author: Hari Krishna (hari_vim at yahoo dot com) -" Last Change: 29-Aug-2006 @ 17:57 -" Created: 19-Apr-2004 -" Requires: Vim-7.0 -" Version: 1.2.0 -" Licence: This program is free software; you can redistribute it and/or -" modify it under the terms of the GNU General Public License. -" See http://www.gnu.org/copyleft/gpl.txt -" NOTE: -" - This may not work well if there are multiple diff formats are mixed in -" the same file. - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - -" CAUTION: Don't assume the existence of plugin/perforce.vim (or any other -" plugins) at the time this file is sourced. - -command! -nargs=0 PFDiffLink :call perforceutils#DiffOpenSrc(0) -command! -nargs=0 PFDiffPLink :call perforceutils#DiffOpenSrc(1) - -command! PFShowConflicts :call perforceutils#ShowConflicts() - -aug P4DiffLink - au! - au FileType * :if expand('<amatch>') ==# 'diff' && exists('b:p4OrgFileName') | - \ call perforceutils#SetupDiffLink() | - \ endif -aug END - - -" Restore cpo. -let &cpo = s:save_cpo -unlet s:save_cpo - -" vim6:fdm=marker et sw=2 diff --git a/.vim/perforce/restor.sh b/.vim/perforce/restor.sh deleted file mode 100755 index 2da076d..0000000 --- a/.vim/perforce/restor.sh +++ /dev/null @@ -1,125 +0,0 @@ -#!/bin/bash -# Author: Hari Krishna Dara ( hari_vim at yahoo dot com ) -# Last Change: 06-Jan-2004 @ 19:07 -# Requires: -# - bash or ksh (tested on cygwin and MKS respectively). -# - Info Zip for the -z option to work (comes with linux/cygwin). Download for -# free from: -# http://www.info-zip.org/ -# Version: 1.1.0 -# Licence: This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License. -# See http://www.gnu.org/copyleft/gpl.txt -usage() -{ -cat <<END -$0 <input package> - The input package is the name of the backup directory or the archive file(with - or without extension). -END -} - -inputType='' -inputPackage='' -verboseMode=1 -if [ -d $1 ]; then - inputType='dir' - inputPackage=$1 -elif [ -r $1.zip ]; then - inputType='zip' - inputPackage=$1.zip -elif [ -r $1.tar.gz ]; then - inputType='tar' - inputPackage=$1.tar.gz - tarOpt='z' -elif [ -r $1.tar.bz2 ]; then - inputType='tar' - inputPackage=$1.tar.bz2 - tarOpt='j' -elif [ -r $1.tar.Z ]; then - inputType='tar' - inputPackage=$1.tar.Z - tarOpt='Z' -elif [ -r $1.tar ]; then - inputType='tar' - inputPackage=$1.tar - tarOpt='' -elif [ -r $1 ]; then - case $1 in - *.zip) - inputType='zip' - ;; - *.tar.gz) - inputType='tar' - tarOpt='z' - ;; - *.tar.bz2) - inputType='tar' - tarOpt='j' - ;; - *.tar.Z) - inputType='tar' - tarOpt='Z' - ;; - *.tar) - inputType='tar' - tarOpt='' - ;; - *) - echo "$0: Unknown input package type." - exit 1 - ;; - esac - inputPackage=$1 -else - echo "$0: No input package found for $1" - exit 1 -fi - -if [ $inputType = 'dir' ]; then - listCmd="find $inputPackage -type f -print | sed -e 's;^$1/*;;'" - copyCmd="cp" - if [ $verboseMode -ne 0 ]; then - copyCmd="$copyCmd -v" - fi - copyCmd="$copyCmd -r $inputPackage/* ." -elif [ $inputType = 'zip' ]; then - listCmd="unzip -l -qq $inputPackage | awk 'BEGIN{OFS=\"\"}{\$1=\"\"; \$2=\"\"; \$3=\"\"; print \$0}'" - copyCmd="unzip" - if [ $verboseMode -ne 1 ]; then - copyCmd="$copyCmd -q" - fi - copyCmd="$copyCmd $inputPackage.zip" -elif [ $inputType = 'tar' ]; then - listCmd="tar -t${tarOpt}f $inputPackage" - copyCmd="tar" - if [ $verboseMode -ne 0 ]; then - copyCmd="$copyCmd -v" - fi - copyCmd="$copyCmd -x${tarOpt}f $inputPackage" -fi - -if [ $verboseMode -eq 1 ]; then - echo "Opening files in Perforce for edit." -fi -discardOutput='' -if [ $verboseMode -eq 0 ]; then - discardOutput=' > /dev/null' -fi -#eval $listCmd | cat -eval $listCmd | p4 -x - edit $discardOutput -if [ $? -ne 0 ]; then - echo "$0: There was an error opening files in Perforce for edit." - echo "Make sure you are in the right directory and try again." - exit 1 -fi - -if [ $verboseMode -eq 1 ]; then - echo "$0: Copying files to the target directories." -fi -#echo $copyCmd -eval $copyCmd -if [ $? -ne 0 ]; then - echo "$0: Error copying files." - exit 1 -fi diff --git a/.vim/plugin/info.vim b/.vim/plugin/info.vim deleted file mode 100644 index f78f0d9..0000000 --- a/.vim/plugin/info.vim +++ /dev/null @@ -1,396 +0,0 @@ -" GNU Info browser -" -" Copyright (c) 2001, 2002 Slavik Gorbanyov <rnd@web-drive.ru> -" All rights reserved. -" -" Redistribution and use, with or without modification, are permitted -" provided that the following conditions are met: -" -" 1. Redistributions must retain the above copyright notice, this list -" of conditions and the following disclaimer. -" -" 2. The name of the author may not be used to endorse or promote -" products derived from this script without specific prior written -" permission. -" -" THIS SCRIPT IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -" POSSIBILITY OF SUCH DAMAGE. -" -" $Id: info.vim,v 1.7 2002/11/30 21:59:05 rnd Exp $ - -let s:infoCmd = 'info --output=-' -if has('win32') - let s:infoBufferName = '-Info- ' -else - let s:infoBufferName = 'Info: ' -endif -let s:dirPattern = '^\* [^:]*: \(([^)]*)\)' -let s:menuPattern = '^\* \([^:]*\)::' -let s:notePattern = '\*[Nn]ote\%(\s\|$\)' -let s:indexPattern = '^\* [^:]*:\s*\([^.]*\)\.$' -let s:indexPatternHL = '^\* [^:]*:\s\+[^(]' - -command! -nargs=* Info call s:Info(<f-args>) - -fun! s:Info(...) - let file = "(dir)" - let node = "Top" - if a:0 - let file = a:1 - if file[0] != '(' - let file = '('.file.')' - endif - if a:0 > 1 - let node = a:2 - let arg_idx = 3 - while arg_idx <= a:0 - exe 'let node = node ." ". a:'.arg_idx - let arg_idx = arg_idx + 1 - endwhile - endif - endif - - call s:InfoExec(file, node) - if winheight(2) != -1 - exe 'resize' &helpheight - endif -endfun - -fun! s:InfoExec(file, node, ...) - " a:0 != 0 means last node requested - if a:0 - let line = a:1 - else - let line = 1 - endif - if a:0 == 0 && exists('b:info_file') - let last_file = b:info_file - let last_node = b:info_node - let last_line = line('.') - endif - let bufname = s:infoBufferName.a:file.a:node - if buflisted(bufname) && a:0 < 2 - if &ft == 'info' - silent exe 'b!' escape(bufname, '\ ') - else - silent exe 'sb' escape(bufname, '\ ') - endif - else - if &ft == 'info' - let command = 'e!' - else - let command = 'new' - endif - silent! exe command "+exe'setlocal''modifiable''noswapfile''buftype=nofile''bufhidden=delete'" escape(bufname, '\ ') - setf info - - let cmd = s:infoCmd." '".a:file.a:node."' 2>/dev/null" - - " handle shell redirection portable - if $OS !~? 'Windows' - let save_shell = &shell - set shell=/bin/sh - endif - let save_shellredir = &shellredir - set shellredir=> - exe "silent 0r!".cmd - let &shellredir = save_shellredir - if $OS !~? 'Windows' - let &shell = save_shell - endif - - call s:InfoBufferInit() - endif - let b:info_file = a:file - let b:info_node = a:node - if exists('last_file') - let b:info_last_file = last_file - let b:info_last_node = last_node - let b:info_last_line = last_line - endif - setlocal nomodifiable - if s:InfoFirstLine() - exe line - else - echohl ErrorMsg | echo 'Info failed (node not found)' | echohl None - endif -endfun - -fun! s:InfoBufferInit() - - " remove all insert mode abbreviations - iabc <buffer> - - if has("syntax") && exists("g:syntax_on") - syn case match - syn match infoMenuTitle /^\* Menu:/hs=s+2,he=e-1 - syn match infoTitle /^[A-Z][0-9A-Za-z `',/&]\{,43}\([a-z']\|[A-Z]\{2}\)$/ - syn match infoTitle /^[-=*]\{,45}$/ - syn match infoString /`[^`]*'/ - exec 'syn match infoLink /'.s:menuPattern.'/hs=s+2' - exec 'syn match infoLink /'.s:dirPattern.'/hs=s+2' - exec 'syn match infoLink /'.s:indexPatternHL.'/hs=s+2,he=e-2' - syn region infoLink start=/\*[Nn]ote/ end=/\(::\|[.,]\)/ - - if !exists("g:did_info_syntax_inits") - let g:did_info_syntax_inits = 1 - hi def link infoMenuTitle Title - hi def link infoTitle Comment - hi def link infoLink Directory - hi def link infoString String - endif - endif - - " FIXME: <h> is move cursor left - noremap <buffer> h :call <SID>Help()<cr> - noremap <buffer> <CR> :call <SID>FollowLink()<cr> - noremap <buffer> <C-]> :call <SID>FollowLink()<cr> - " FIXME: <l> is move cursor right -" noremap <buffer> l :call <SID>LastNode()<cr> - noremap <buffer> ; :call <SID>LastNode()<cr> - noremap <buffer> <C-T> :call <SID>LastNode()<cr> - noremap <buffer> <C-S> / - " FIXME: <n> is go to next match -" noremap <buffer> n :call <SID>NextNode()<cr> - noremap <buffer> . :call <SID>NextNode()<cr> - noremap <buffer> p :call <SID>PrevNode()<cr> - noremap <buffer> > :call <SID>NextNode()<cr> - noremap <buffer> < :call <SID>PrevNode()<cr> - noremap <buffer> u :call <SID>UpNode()<cr> - noremap <buffer> t :call <SID>TopNode()<cr> - noremap <buffer> d :call <SID>DirNode()<cr> - noremap <buffer> s :call <SID>Search()<cr> - noremap <buffer> <TAB> :call <SID>NextRef()<cr> - nnoremap <buffer> q :q!<cr> - noremap <buffer> <Space> <C-F> - noremap <buffer> <Backspace> <C-B> - - runtime info-local.vim -endfun - -fun! s:Help() - echohl Title - echo 'Info browser keys' - echo '-----------------' - echohl None - echo '<Space> Scroll forward (page down).' - echo '<Backspace> Scroll backward (page up).' - echo '<Tab> Move cursor to next hyperlink within this node.' - echo '<Enter>,<C-]> Follow hyperlink under cursor.' - echo ';,<C-T> Return to last seen node.' - echo '.,> Move to the "next" node of this node.' - echo 'p,< Move to the "previous" node of this node.' - echo 'u Move "up" from this node.' - echo 'd Move to "directory" node.' - echo 't Move to the Top node.' - echo '<C-S> Search forward within current node only.' - echo 's Search forward through all nodes for a specified string.' - echo 'q Quit browser.' - echohl SpecialKey - echo 'Note: "," means "or"' - echohl None -endfun - -fun! s:InfoFirstLine() - let b:info_next_node = '' - let b:info_prev_node = '' - let b:info_up_node = '' - let line = getline(1) - let node_offset = matchend(line, '^File: [^, ]*') - if node_offset == -1 - return 0 - endif - let file = strpart(line, 6, node_offset-6) - if file == 'dir' - return 1 - endif -" let file = substitute(file, '\(.*\)\.info\(\.gz\)\=', '\1', '') - let b:info_next_node = s:GetSubmatch( line, '\s\+Next: \([^,]*\),') - let b:info_prev_node = s:GetSubmatch( line, '\s\+Prev: \([^,]*\),') - let b:info_up_node = s:GetSubmatch( line, '\s\+Up: \(.*\)') - return 1 -endfun - -fun! s:GetSubmatch(string, pattern) - let matched = matchstr(a:string, a:pattern) - if matched != '' - let matched = substitute(matched, a:pattern, '\1', '') - endif - return matched -endfun - -fun! s:NextNode() - if exists('b:info_next_node') && b:info_next_node != '' - \ && match(b:info_next_node, '(.*)') == -1 - call s:InfoExec(b:info_file, b:info_next_node) - return 1 - else - echohl ErrorMsg | echo 'This is the last node' | echohl None - endif -endfun - -fun! s:TopNode() - if b:info_node == 'Top' - if b:info_file == '(dir)' - echohl ErrorMsg | echo 'Already at top node' | echohl None - return - endif - let file = '(dir)' - let node = b:info_node - else - let file = b:info_file - let node = 'Top' - endif - call s:InfoExec(file, node) -endfun - -fun! s:DirNode() - call s:InfoExec('(dir)', 'Top') -endfun - -fun! s:LastNode() - if !exists('b:info_last_node') - echohl ErrorMsg | echo 'No last node' | echohl None - return - endif - call s:InfoExec(b:info_last_file, b:info_last_node, b:info_last_line) -endfun - -fun! s:FollowLink() - let current_line = getline('.') - let link = matchstr(current_line, s:notePattern) - if link == '' - let link = matchstr(current_line, s:dirPattern) - if link == '' - let link = matchstr(current_line, s:menuPattern) - if link == '' - let link = matchstr(current_line, s:indexPattern) - if link == '' - echohl ErrorMsg | echo 'No link under cursor' | echohl None - return - endif - let successPattern = s:indexPattern - else - let successPattern = s:menuPattern - endif - let file = b:info_file - let node = substitute(link, successPattern, '\1', '') - else - let successPattern = s:dirPattern - let file = substitute(link, successPattern, '\1', '') - let node = 'Top' - endif - else - " we got a `*note' link. - let successPattern = s:notePattern - let current_line = current_line.' '.getline(line('.') + 1) - - if exists('g:info_debug') - echo 'current_line:' current_line - endif - - let link_pattern = '\*[Nn]ote [^:.]\+: \([^.,]\+\)\%([,.]\|$\)' - let link = matchstr(current_line, link_pattern) - if link == '' - let link_pattern = '\*[Nn]ote \([^:]\+\)\%(::\)' - let link = matchstr(current_line, link_pattern) - if link == '' - echohl ErrorMsg | echo 'No link under cursor' | echohl None - return - endif - endif - let node = substitute(link, link_pattern, '\1', '') - let successPattern = link_pattern - - let link_pattern = '^\(([^)]*)\)\=\s*\(.*\)' - let link = matchstr(node, link_pattern) - let file = substitute(link, link_pattern, '\1', '') - let node = substitute(link, link_pattern, '\2', '') - if file == '' - let file = b:info_file - endif - if node == '' - let node = 'Top' - endif - endif - let link_start_pos = match(current_line, successPattern) - let link_end_pos = matchend(current_line, successPattern) - let cursor_pos = col('.') - if cursor_pos <= link_start_pos || cursor_pos > link_end_pos - echohl ErrorMsg | echo 'No link under cursor' | echohl None - return - endif - if exists('g:info_debug') - echo 'Link:' strpart(current_line, link_start_pos, link_end_pos - link_start_pos) - echo 'File:' file 'Node:' node - endif - call s:InfoExec(file, node) -endfun - -fun! s:NextRef() - let link_pos = search('\('.s:dirPattern.'\|'.s:menuPattern.'\|'.s:notePattern.'\|'.s:indexPatternHL.'\)', 'w') - if link_pos == 0 - echohl ErrorMsg | echo 'No hyperlinks' | echohl None - else - echo - endif -endfun - -fun! s:PrevNode() - if exists('b:info_prev_node') && b:info_prev_node != '' - \ && match(b:info_prev_node, '(.*)') == -1 - call s:InfoExec(b:info_file, b:info_prev_node) - return 1 - else - echohl ErrorMsg | echo 'This is the first node' | echohl None - endif -endfun - -fun! s:UpNode() - if exists('b:info_up_node') && b:info_up_node != '' - \ && match(b:info_up_node, '(.*)') == -1 - call s:InfoExec(b:info_file, b:info_up_node) - return 1 - else - echohl ErrorMsg | echo 'This is the top node' | echohl None - endif -endfun - -" FIXME: there is no way to correctly abort searching. -" <CTRL-C> messes up the command window and stops at empty buffer. -fun! s:Search() - if !exists('s:info_search_string') - let s:info_search_string = '' - endif - let new_search = input('Search all nodes: ', s:info_search_string) - if new_search == '' - return - endif - let s:info_search_string = new_search - let start_file = b:info_file - let start_node = b:info_node - let start_line = line('.') - while search(s:info_search_string, 'W') == 0 - if !exists('b:info_next_node') || b:info_next_node == '' - \ || match(b:info_next_node, '(.*)') != -1 - silent! exe 'bwipe' escape(s:infoBufferName.start_file.start_node, '\ ') - silent! call s:InfoExec(start_file, start_node, start_line, 'force') - echohl ErrorMsg | echo "\rSearch pattern not found" | echohl None - return - endif - echo "\rSearching ... ".b:info_file b:info_next_node - let file = b:info_file - let node = b:info_next_node - silent bwipe - silent call s:InfoExec(file, node, 2) - endwhile -endfun diff --git a/.vim/plugin/perforce.vim b/.vim/plugin/perforce.vim deleted file mode 100755 index 7283df9..0000000 --- a/.vim/plugin/perforce.vim +++ /dev/null @@ -1,375 +0,0 @@ -" perforce.vim: Interface with perforce SCM through p4. -" Author: Hari Krishna (hari_vim at yahoo dot com) -" Last Change: 02-Sep-2006 @ 19:56 -" Created: Sometime before 20-Apr-2001 -" Requires: Vim-7.0, genutils.vim(2.3) -" Version: 4.1.3 -" Licence: This program is free software; you can redistribute it and/or -" modify it under the terms of the GNU General Public License. -" See http://www.gnu.org/copyleft/gpl.txt -" Acknowledgements: -" See ":help perforce-acknowledgements". -" Download From: -" http://www.vim.org//script.php?script_id=240 -" Usage: -" For detailed help, see ":help perforce" or read doc/perforce.txt. -" -" TODO: {{{ -" - Launch from describe window is not using the local path. -" -" - I need a test suite to stop things from breaking. -" - Should the client returned by g:p4CurPresetExpr be made permanent? -" - curPresetExpr can't support password, so how is the expression going to -" change password? -" - If you actually use python to execute, you may be able to display the -" output incrementally. -" - There seems to be a problem with 'autoread' change leaking. Not sure if -" we explicitly set it somewhere, check if we are using try block. -" - Buffer local autocommads are pretty useful for perforce plugin, send -" feedback. -" - Verify that the buffers/autocommands are not leaking. -" TODO }}} -" -" BEGIN NOTES {{{ -" - Now that we increase the level of escaping in the ParseOptions(), we -" need to be careful in reparsing the options (by not using -" scriptOrigin=2). When you CreateArgString() using these escaped -" arguments as if they were typed in by user, they get sent to p4 as they -" are, with incorrect number of back-slashes. -" - When issuing sub-commands, we should remember to use the s:p4Options -" that was passed to the main command (unless the main command already -" generated a new window, in which case the original s:p4Options are -" remembered through b:p4Options and automatically reused for the -" subcommands), or the user will see incorrect behavior or at the worst, -" errors. -" - The p4FullCmd now can have double-quotes surrounding each of the -" individual arguments if the shell is cmd.exe or command.com, so while -" manipulating it directly, we need to use "\?. -" - With the new mode of scriptOrigin=2, the changes done to the s:p4* -" variables will not get reflected in the s:p4WinName, unless there is -" some other relevant processing done in PFIF. -" - With the new mode of scriptOrigin=2, there is no reason to use -" scriptOrigin=1 in most of the calls from handlers. -" - The s:PFSetupBufAutoCommand and its cousines expect the buffer name to -" be plain with no escaping, as they do their own escaping. -" - Wherever we normally expect a depot name, we should use the s:p4Depot -" instead of hardcoded 'depot'. We should also consider the client name -" here. -" - Eventhough DefFileChangedShell event handling is now localized, we still -" need to depend on s:currentCommand to determine the 'autoread' value, -" this is because some other plugin might have already installed a -" FileChangedShell event to DefFileChangedShell, resulting in us receiving -" callbacks anytime, so we need a variable that has a lifespace only for -" the duration of the execution of p4 commands? -" - We need to pass special characters such as <space>, *, ?, [, (, &, |, ', $ -" and " to p4 without getting interpreted by the shell. We may have to use -" appropriate quotes around the characters when the shell treats them -" specially. Windows+native is the least bothersome of all as it doesn't -" treat most of the characters specially and the arguments can be -" sorrounded in double-quotes and embedded double-quotes can be easily -" passed in by just doubling them. -" - I am aware of the following unique ways in which external commands are -" executed (not sure if this is same for all of the variations possible: -" ":[{range}][read|write]!cmd | filter" and "system()"): -" For :! command -" On Windoze+native: -" cmd /c <command> -" On Windoze+sh: -" sh -c "<command>" -" On Unix+sh: -" sh -c (<command>) -" - By the time we parse arguments, we protect all the back-slashes, which -" means that we would never see a single-back-slash. -" - Using back-slashes on Cygwin vim is unique and causes E303. This is -" because it thinks it is on UNIX where it is not a special character, but -" underlying Windows obviously treats it special and so it bails out. -" - Using back-slashes on Windows+sh also seems to be different. Somewhere in -" the execution line (most probably the path from CreateProcess() to sh, -" as it doesn't happen in all other types of interfaces) consumes one -" level of extra back-slashes. If it is even number it becomes half, and -" if it is odd then the last unpaired back-slash is left as it is. -" - Some test cases for special character handling: -" - PF fstat a\b -" - PF fstat a\ b -" - PF fstat a&b -" - PF fstat a\&b -" - PF fstat a\#b -" - PF fstat a\|b -" - Careful using s:PFIF(1) from within script, as it doesn't redirect the -" call to the corresponding handler (if any). -" - Careful using ":PF" command from within handlers, especially if you are -" executing the same s:p4Command again as it will result in a recursion. -" - The outputType's -2 and -1 are local to the s:PFrangeIF() interface, the -" actual s:PFImpl() or any other methods shouldn't know anything about it. -" Which is why this outputType should be used only for those commands that -" don't have a handler. Besides this scheme will not even work if a -" handler exists, as the outputType will get permanently set to 4 by the -" time it gets redirected back to s:PFrangeIF() through the handler. (If -" this should ever be a requirement, we will need another state variable -" called s:orgOutputType.) -" - Be careful to pass argument 0 to s:PopP4Context() whenever the logical -" p4 operation ends, to avoid getting the s:errCode carried over. This is -" currently taken care of for all the known recursive or ignorable error -" cases. -" - We need to use s:outputType as much as possible, not a:outputType, which -" is there only to pass it on to s:ParseOptions(). After calling s:PFIF() -" the outputType is established in s:outputType. -" - s:errCode is reset by ParseOptions(). For cases that Push and Pop context -" even before the first call to ParseOptions() (such as the -" s:GetClientInfo() function), we have to check for s:errCode before we -" pop context, or we will just carry on an error code from a previous bad -" run (applies to mostly utility functions). -" END NOTES }}} - -if exists('loaded_perforce') - finish -endif -if v:version < 700 - "echomsg 'Perforce: You need at least Vim 7.0' - finish -endif - - -" We need these scripts at the time of initialization itself. -if !exists('loaded_genutils') - runtime plugin/genutils.vim -endif -if !exists('loaded_genutils') || loaded_genutils < 203 - echomsg 'perforce: You need a newer version of genutils.vim plugin' - finish -endif -let loaded_perforce=400 - -" Make sure line-continuations won't cause any problem. This will be restored -" at the end -let s:save_cpo = &cpo -set cpo&vim - -" User option initialization {{{ -function! s:CondDefSetting(settingName, def) - if !exists(a:settingName) - let {a:settingName} = a:def - endif -endfunction - -call s:CondDefSetting('g:p4CmdPath', 'p4') -call s:CondDefSetting('g:p4ClientRoot', '') -call s:CondDefSetting('g:p4DefaultListSize', '100') -call s:CondDefSetting('g:p4DefaultDiffOptions', '') -call s:CondDefSetting('g:p4DefaultPreset', -1) -call s:CondDefSetting('g:p4Depot', 'depot') -call s:CondDefSetting('g:p4Presets', '') -call s:CondDefSetting('g:p4DefaultOptions', '') -call s:CondDefSetting('g:p4UseGUIDialogs', 0) -call s:CondDefSetting('g:p4PromptToCheckout', 1) -call s:CondDefSetting('g:p4MaxLinesInDialog', 1) -call s:CondDefSetting('g:p4EnableActiveStatus', 1) -call s:CondDefSetting('g:p4ASIgnoreDefPattern', - \'\c\%(\<t\%(e\)\?mp\/.*\|^.*\.tmp$\|^.*\.log$\|^.*\.diff\?$\|^.*\.out$\|^.*\.buf$\|^.*\.bak$\)\C') -call s:CondDefSetting('g:p4ASIgnoreUsrPattern', '') -call s:CondDefSetting('g:p4OptimizeActiveStatus', 1) -call s:CondDefSetting('g:p4EnableRuler', 1) -call s:CondDefSetting('g:p4RulerWidth', 25) -call s:CondDefSetting('g:p4EnableMenu', 0) -call s:CondDefSetting('g:p4EnablePopupMenu', 0) -call s:CondDefSetting('g:p4UseExpandedMenu', 1) -call s:CondDefSetting('g:p4UseExpandedPopupMenu', 0) -call s:CondDefSetting('g:p4CheckOutDefault', 3) -call s:CondDefSetting('g:p4SortSettings', 1) -" Probably safer than reading $TEMP. -call s:CondDefSetting('g:p4TempDir', fnamemodify(tempname(), ':h')) -call s:CondDefSetting('g:p4SplitCommand', 'split') -call s:CondDefSetting('g:p4EnableFileChangedShell', 1) -call s:CondDefSetting('g:p4UseVimDiff2', 0) -call s:CondDefSetting('g:p4BufHidden', 'wipe') -call s:CondDefSetting('g:p4Autoread', 1) -call s:CondDefSetting('g:p4FileLauncher', '') -call s:CondDefSetting('g:p4CurPresetExpr', '') -call s:CondDefSetting('g:p4CurDirExpr', '') -call s:CondDefSetting('g:p4UseClientViewMap', 1) -delfunction s:CondDefSetting -" }}} - - -" Call this any time to reconfigure the environment. This re-performs the same -" initializations that the script does during the vim startup, without -" loosing what is already configured. -command! -nargs=0 PFInitialize :call perforce#Initialize(0) - -""" The following are some shortcut commands. Some of them are enhanced such -""" as the help window or the filelog window. - -" Command definitions {{{ - -command! -nargs=* -complete=custom,perforce#PFComplete PP - \ :call perforce#PFIF(0, 0, 'print', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PPrint - \ :call perforce#PFIF(0, 0, 'print', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PDiff - \ :call perforce#PFIF(0, 0, 'diff', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PD - \ :PDiff <args> -command! -nargs=* -complete=custom,perforce#PFComplete PEdit - \ :call perforce#PFIF(0, 2, 'edit', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PE - \ :PEdit <args> -command! -nargs=* -complete=custom,perforce#PFComplete PReopen - \ :call perforce#PFIF(0, 2, 'reopen', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PAdd - \ :call perforce#PFIF(0, 2, 'add', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PA - \ :PAdd <args> -command! -nargs=* -complete=custom,perforce#PFComplete PDelete - \ :call perforce#PFIF(0, 2, 'delete', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PLock - \ :call perforce#PFIF(0, 2, 'lock', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PUnlock - \ :call perforce#PFIF(0, 2, 'unlock', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PRevert - \ :call perforce#PFIF(0, 2, 'revert', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PR - \ :PRevert <args> -command! -nargs=* -complete=custom,perforce#PFComplete PSync - \ :call perforce#PFIF(0, 2, 'sync', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PG - \ :PSync <args> -command! -nargs=* -complete=custom,perforce#PFComplete PGet - \ :call perforce#PFIF(0, 2, 'get', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete POpened - \ :call perforce#PFIF(0, 0, 'opened', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PO - \ :POpened <args> -command! -nargs=* -complete=custom,perforce#PFComplete PHave - \ :call perforce#PFIF(0, 0, 'have', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PWhere - \ :call perforce#PFIF(0, 0, 'where', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PDescribe - \ :call perforce#PFIF(0, 0, 'describe', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PFiles - \ :call perforce#PFIF(0, 0, 'files', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PLabelsync - \ :call perforce#PFIF(0, 0, 'labelsync', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PFilelog - \ :call perforce#PFIF(0, 0, 'filelog', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PIntegrate - \ :call perforce#PFIF(0, 0, 'integrate', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PDiff2 - \ :call perforce#PFIF(0, 0, 'diff2', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PD2 - \ :PDiff2 <args> -command! -nargs=* -complete=custom,perforce#PFComplete PFstat - \ :call perforce#PFIF(0, 0, 'fstat', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PHelp - \ :call perforce#PFIF(0, 0, 'help', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PH - \ :PHelp <args> -command! -nargs=* PPasswd - \ :call perforce#PFIF(0, 2, 'passwd', <f-args>) - - -""" Some list view commands. -command! -nargs=* -complete=custom,perforce#PFComplete PChanges - \ :call perforce#PFIF(0, 0, 'changes', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PBranches - \ :call perforce#PFIF(0, 0, 'branches', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PLabels - \ :call perforce#PFIF(0, 0, 'labels', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PClients - \ :call perforce#PFIF(0, 0, 'clients', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PUsers - \ :call perforce#PFIF(0, 0, 'users', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PJobs - \ :call perforce#PFIF(0, 0, 'jobs', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PDepots - \ :call perforce#PFIF(0, 0, 'depots', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PGroups - \ :call perforce#PFIF(0, 0, 'groups', <f-args>) - - -""" The following support some p4 operations that normally involve some -""" interaction with the user (they are more than just shortcuts). - -command! -nargs=* -complete=custom,perforce#PFComplete PChange - \ :call perforce#PFIF(0, 0, 'change', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PBranch - \ :call perforce#PFIF(0, 0, 'branch', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PLabel - \ :call perforce#PFIF(0, 0, 'label', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PClient - \ :call perforce#PFIF(0, 0, 'client', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PUser - \ :call perforce#PFIF(0, 0, 'user', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PJob - \ :call perforce#PFIF(0, 0, 'job', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PJobspec - \ :call perforce#PFIF(0, 0, 'jobspec', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PDepot - \ :call perforce#PFIF(0, 0, 'depot', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PGroup - \ :call perforce#PFIF(0, 0, 'group', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PSubmit - \ :call perforce#PFIF(0, 0, 'submit', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PResolve - \ :call perforce#PFIF(0, 0, 'resolve', <f-args>) - -" Some built-in commands. -command! -nargs=* -complete=custom,perforce#PFComplete PVDiff - \ :call perforce#PFIF(0, 0, 'vdiff', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PVDiff2 - \ :call perforce#PFIF(0, 0, 'vdiff2', <f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete PExec - \ :call perforce#PFIF(0, 5, 'exec', <f-args>) - -""" Other utility commands. - -command! -nargs=* -complete=file E :call perforce#PFOpenAltFile(0, <f-args>) -command! -nargs=* -complete=file ES :call perforce#PFOpenAltFile(2, <f-args>) -command! -nargs=* -complete=custom,perforce#PFSwitchComplete PFSwitch - \ :call perforce#PFSwitch(1, <f-args>) -command! -nargs=* PFSwitchPortClientUser :call perforce#SwitchPortClientUser() -command! -nargs=0 PFRefreshActivePane :call perforce#PFRefreshActivePane() -command! -nargs=0 PFRefreshFileStatus :call perforce#GetFileStatus(0, 1) -command! -nargs=0 PFToggleCkOut :call perforce#ToggleCheckOutPrompt(1) -command! -nargs=* -complete=custom,perforce#PFSettingsComplete PFS - \ :PFSettings <args> -command! -nargs=* -complete=custom,perforce#PFSettingsComplete PFSettings - \ :call perforce#PFSettings(<f-args>) -command! -nargs=0 PFDiffOff :call perforce#PFDiffOff( - \ exists('w:p4VDiffWindow') ? w:p4VDiffWindow : -1) -command! -nargs=? PFWipeoutBufs :call perforce#WipeoutP4Buffers(<f-args>) -"command! -nargs=* -complete=file -range=% PF -command! -nargs=* -complete=custom,perforce#PFComplete -range=% PF - \ :call perforce#PFrangeIF(<line1>, <line2>, 0, 0, <f-args>) -command! -nargs=* -complete=file PFRaw :call perforce#PFRaw(<f-args>) -command! -nargs=* -complete=custom,perforce#PFComplete -range=% PW - \ :call perforce#PW(<line1>, <line2>, 0, <f-args>) -command! -nargs=0 PFLastMessage :call perforce#LastMessage() -command! -nargs=0 PFBugReport :runtime perforce/perforcebugrep.vim -command! -nargs=0 PFUpdateViews :call perforce#UpdateViewMappings() - -" New normal mode mappings. -if (! exists('no_plugin_maps') || ! no_plugin_maps) && - \ (! exists('no_perforce_maps') || ! no_execmap_maps) - nnoremap <silent> <Leader>prap :PFRefreshActivePane<cr> - nnoremap <silent> <Leader>prfs :PFRefreshFileStatus<cr> - - " Some generic mappings. - if maparg('<C-X><C-P>', 'c') == "" - cnoremap <C-X><C-P> <C-R>=perforce#PFOpenAltFile(1)<CR> - endif -endif - -" Command definitions }}} - -if exists('g:p4EnableActiveStatus') && g:p4EnableActiveStatus - aug P4Init - au! - au BufRead * exec 'au! P4Init' | exec 'PFInitialize' | PFRefreshFileStatus - aug END -endif - -" Restore cpo. -let &cpo = s:save_cpo -unlet s:save_cpo - -" vim6:fdm=marker et sw=2 diff --git a/.xbindkeys/lock b/.xbindkeys/lock index 72802c6..537cbfa 100755 --- a/.xbindkeys/lock +++ b/.xbindkeys/lock @@ -1,4 +1,4 @@ # Launch XScreenSaver if it isn't already running. -flock --timeout=1 ~/.xscreensaver.lock xscreensaver & +setlock -nx /tmp/.xscreensaver.$USER.lock xscreensaver & # And lock the screen. xscreensaver-command -lock diff --git a/opt/bin/phier b/opt/Linux/bin/phier similarity index 100% rename from opt/bin/phier rename to opt/Linux/bin/phier diff --git a/opt/bin/sshcolourterm b/opt/bin/sshcolourterm index c144a3b..0cf4b9f 100755 --- a/opt/bin/sshcolourterm +++ b/opt/bin/sshcolourterm @@ -6,12 +6,24 @@ fqdn=${1##*@} colour= # Get colour by regex. -for path in $(ls "$SSHCOLOURS" | lensort -r); do - re=${path##*/} - echo "$fqdn" | grep -qs "$re" || continue - colour=$(readlink "$SSHCOLOURS/$path") - break -done +if [ -z "$colour" ]; then + for path in $(ls "$SSHCOLOURS" | lensort -r); do + re=${path##*/} + echo "$fqdn" | grep -qs "$re" || continue + colour=$(readlink "$SSHCOLOURS/$path") + break + done +fi + +# Get colour by netgroup. +if [ -z "$colour" ]; then + for netgroup in $(ls "$SSHCOLOURS" | grep ^\@); do + if netgroups $netgroup ${fqdn%%.*} 2>/dev/null; then + colour=$(readlink "$SSHCOLOURS/$netgroup") + break + fi + done +fi if [ ! -z "$colour" ]; then colour=${colour##*/} diff --git a/opt/bin/sshterm b/opt/bin/sshterm index 158b328..eb209e6 100755 --- a/opt/bin/sshterm +++ b/opt/bin/sshterm @@ -1,4 +1,8 @@ #!/bin/bash - +cd / +if [ "$SSHTERM" = "urxvtc" ]; then + setlock -nx ${RXVT_SOCKET:-$HOME/rxvt-unicode-$HOSTNAME}.lock urxvtd -q -o -f & +fi ${SSHTERM:-xterm} ${SSHTERM_TITLE:--title} "$1" ${SSHTERM_EXEC:--e} \ -sshcolourterm ${1+"$@"} +sshcolourterm ${1+"$@"} & +disown -- 2.7.4