From 19a30cda6029906dbfadf0ea0e284b518947e429 Mon Sep 17 00:00:00 2001 From: Iain Patterson 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 +- .../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?|{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 xx xx - let s:sid = maparg("xx") - unmap 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, '\') != -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("")' - -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 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", '']) - 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("\$", '%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('W', - \ [0]+b:p4Options+['submit']+split(, '\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('W', - \ [0]+b:p4Options+['change']+split(, '\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 D - silent! delcommand PItemDelete - command! -range -buffer -nargs=0 PFilelogDiff - \ :call s:FilelogDiff2(, ) - vnoremap D :PFilelogDiff - command! -buffer -nargs=0 PFilelogPrint :call perforce#PFIF(0, 0, 'print', - \ GetCurrentItem()) - nnoremap p :PFilelogPrint - command! -buffer -nargs=0 PFilelogSync :call FilelogSyncToCurrentItem() - nnoremap S :PFilelogSync - command! -buffer -nargs=0 PFilelogDescribe - \ :call FilelogDescribeChange() - nnoremap C :PFilelogDescribe - - 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', GetCurrentItem()) - nnoremap P :PClientsTemplate - - 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 PChangesDescribeCurrentItem() - command! -buffer -nargs=0 PChangesSubmit - \ :call ChangesSubmitChangeList() - nnoremap S :PChangesSubmit - command! -buffer -nargs=0 PChangesOpened - \ :if getline('.') =~# " \\*pending\\* '" | - \ call perforce#PFIF(1, 0, 'opened', '-c', GetCurrentItem()) | - \ endif - nnoremap o :PChangesOpened - command! -buffer -nargs=0 PChangesDiff - \ :if getline('.') =~# " \\*pending\\* '" | - \ call perforce#PFIF(0, 0, 'diff', '++c', GetCurrentItem()) | - \ else | - \ call perforce#PFIF(0, 0, 'describe', (('DefaultDiffOptions') - \ =~ '^\s*$' ? '-dd' : ('DefaultDiffOptions')), - \ GetCurrentItem()) | - \ endif - nnoremap d :PChangesDiff - command! -buffer -nargs=0 PItemOpen - \ :if getline('.') =~# " \\*pending\\* '" | - \ call perforce#PFIF(0, 0, 'change', GetCurrentItem()) | - \ else | - \ call perforce#PFIF(0, 0, 'describe', '-dd', 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 LabelsSyncClientToLabel() - nnoremap S :PLabelsSyncClient - command! -buffer -nargs=0 PLabelsSyncLabel - \ :call LabelsSyncLabelToClient() - nnoremap C :PLabelsSyncLabel - command! -buffer -nargs=0 PLabelsFiles :call perforce#PFIF(0, 0, '++n', 'files', - \ '//...@'. GetCurrentItem()) - nnoremap I :PLabelsFiles - command! -buffer -nargs=0 PLabelsTemplate :call perforce#PFIF(0, 0, '++A', - \ 'label', '-t', GetCurrentItem()) - nnoremap P :PLabelsTemplate - - 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("")) - nnoremap :PHelpSelect - nnoremap K :PHelpSelect - nnoremap <2-LeftMouse> :PHelpSelect - 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 /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" - 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 D - silent! delcommand PItemDelete - command! -buffer -nargs=0 PFileDiff :call perforce#PFIF(0, 1, 'diff', - \ GetCurrentDepotFile(line("."))) - nnoremap D :PFileDiff - command! -buffer -nargs=0 PFileProps :call perforce#PFIF(1, 0, 'fstat', '-C', - \ GetCurrentDepotFile(line("."))) - nnoremap P :PFileProps - command! -buffer -nargs=0 PFileLog :call perforce#PFIF(1, 0, 'filelog', - \ GetCurrentDepotFile(line("."))) - command! -buffer -nargs=0 PFileEdit :call perforce#PFIF(1, 2, 'edit', - \ GetCurrentItem()) - nnoremap I :PFileEdit - command! -buffer -bar -nargs=0 PFileRevert :call perforce#PFIF(1, 2, 'revert', - \ GetCurrentItem()) - nnoremap R :PFileRevert \| PFRefreshActivePane - command! -buffer -nargs=0 PFilePrint - \ :if getline('.') !~# '(\%(u\|ux\)binary)$' | - \ call perforce#PFIF(0, 0, 'print', - \ substitute(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 p :PFilePrint - command! -buffer -nargs=0 PFileGet :call perforce#PFIF(1, 2, 'sync', - \ GetCurrentDepotFile(line("."))) - command! -buffer -nargs=0 PFileSync :call perforce#PFIF(1, 2, 'sync', - \ GetCurrentItem()) - nnoremap S :PFileSync - command! -buffer -nargs=0 PFileChange :call perforce#PFIF(0, 0, 'change', - \ GetCurrentChangeNumber(line("."))) - nnoremap C :PFileChange - command! -buffer -nargs=0 PFileLaunch :call LaunchCurrentFile() - nnoremap A :PFileLaunch -endfunction " }}} - -function! s:SetupDiff() " {{{ - setlocal ft=diff -endfunction " }}} - -function! s:SetupSelectItem() " {{{ - nnoremap D :PItemDelete - nnoremap O :PItemOpen - nnoremap :PItemDescribe - nnoremap <2-LeftMouse> :PItemDescribe - command! -buffer -nargs=0 PItemDescribe :call OpenCurrentItem(1) - command! -buffer -nargs=0 PItemOpen :call OpenCurrentItem(0) - command! -buffer -nargs=0 PItemDelete :call DeleteCurrentItem() - cnoremap =GetCurrentItem() -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("\") -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 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 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: - " (?:) - " - " (?:) - 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('W', - \ [0]+b:p4Options+[b:p4Command]+b:p4CmdOptions+split(, - \ '\s')) - command! -buffer -nargs=* WQ :call call('W', - \ [1]+b:p4Options+[b:p4Command]+b:p4CmdOptions+split(, - \ '\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 q q - endif - endif - - if index(s:navigateCmds, s:p4Command) != -1 - nnoremap :call NavigateBack() - nnoremap :call NavigateBack() - nnoremap :call NavigateForward() - 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., &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! \e'".cmdLine."'\" - " 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', "") - return '' - endif - finally - call s:PopP4Context(0) - endtry - - if match(fileStatusStr, ' - file(s) not in client view\.') >= 0 - call setbufvar(bufNr, 'p4RulerErr', "") - " Required for optimizing out in future runs. - call setbufvar(bufNr, 'p4HeadRev', '') - return '' - elseif match(fileStatusStr, ' - no such file(s).') >= 0 - call setbufvar(bufNr, 'p4RulerErr', "") - " 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', '') - 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 == '' - 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('') + 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 nested :call CancelEdit(1) - au CursorMoved nested :call CancelEdit(1) - elseif a:stage == 1 - stopinsert - silent undo - setl readonly - endif - aug END -endfunction - -function! perforce#FileChangedShell() - let bufNr = expand("") + 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\)\@$", '%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 | - " Ex: PF -c hari integrate -b branch -s - 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, '\\\@' - 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, '^ \+\|\%(\\\@ or // 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, - \ '\(\*\|\%(\.\)\@ 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, '\\\@ 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) =~# '\TestParseOptions() -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('') + 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 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 xx xx - let s:sid = maparg("xx") - unmap 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 O :PDiffLink - nnoremap :PDiffPLink -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 :call 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 /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 = '' -< - 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): -> - -< -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 = ' ' -< - 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 = '' -< - 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 = '' -< - 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 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 = -< - 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 =