Cross merge with CSR.
[profile.git] / .vim / autoload / perforce.vim
diff --git a/.vim/autoload/perforce.vim b/.vim/autoload/perforce.vim
deleted file mode 100755 (executable)
index 460ef9c..0000000
+++ /dev/null
@@ -1,3715 +0,0 @@
-" perforce.vim: Please see plugin/perforce.vim
-
-" Make sure line-continuations won't cause any problem. This will be restored
-"   at the end
-let s:save_cpo = &cpo
-set cpo&vim
-
-
-""" BEGIN: Initializations {{{
-
-" Determine the script id.
-function! s:MyScriptId()
-  map <SID>xx <SID>xx
-  let s:sid = maparg("<SID>xx")
-  unmap <SID>xx
-  return substitute(s:sid, "xx$", "", "")
-endfunction
-let s:myScriptId = s:MyScriptId()
-delfunction s:MyScriptId " This is not needed anymore.
-
-""" BEGIN: One-time initialization of some script variables {{{
-let s:lastMsg = ''
-let s:lastMsgGrp = 'None'
-" Indicates the current recursion level for executing p4 commands.
-let s:recLevel = 0
-
-if genutils#OnMS() && match(&shell, '\<bash\>') != -1
-  " When using cygwin bash with native vim, p4 gets confused by the PWD, which
-  "   is in cygwin style.
-  let s:p4CommandPrefix = "unset PWD && "
-else
-  let s:p4CommandPrefix = ""
-endif
-
-" Special characters in a filename that are not acceptable in a filename (as a
-"   window title) on windows.
-let s:specialChars = '\([*:?"<>|]\)' 
-let s:specialCharsMap = {
-      \   '*': 'S',
-      \   ':': 'C',
-      \   '?': 'Q',
-      \   '"': 'D',
-      \   '<': 'L',
-      \   '>': 'G',
-      \   '|': 'P',
-      \ }
-
-"
-" A lot of metadata on perforce command syntax and handling.
-"
-
-let s:p4KnownCmds = split('add,admin,annotate,branch,branches,change,changes,' .
-      \ 'client,clients,counter,counters,delete,depot,depots,describe,diff,' .
-      \ 'diff2,dirs,edit,filelog,files,fix,fixes,flush,fstat,get,group,' .
-      \ 'groups,have,help,info,integ,integrate,integrated,job,jobs,jobspec,' .
-      \ 'label,labels,labelsync,lock,logger,login,monitor,obliterate,opened,' .
-      \ 'passwd,print,protect,rename,reopen,resolve,resolved,revert,review,' .
-      \ 'reviews,set,submit,sync,triggers,typemap,unlock,user,users,verify,' .
-      \ 'where,workspaces,', ',')
-" Add some built-in commands to this list.
-let s:builtinCmds = split('vdiff,vdiff2,exec,', ',')
-let s:allCommands = s:p4KnownCmds + s:builtinCmds
-let s:p4KnownCmdsCompStr = ''
-
-" Map between the option and the commands that reqire us to pass an argument
-"   with this option.
-let s:p4OptCmdMap = {}
-let s:p4OptCmdMap['b'] = split('diff2,integrate', ',')
-let s:p4OptCmdMap['c'] = split('add,delete,edit,fix,fstat,integrate,lock,' .
-      \ 'opened,reopen,r[ver],review,reviews,submit,unlock', ',')
-let s:p4OptCmdMap['e'] = ['jobs']
-let s:p4OptCmdMap['j'] = ['fixes']
-let s:p4OptCmdMap['l'] = ['labelsync']
-let s:p4OptCmdMap['m'] = split('changes,filelog,jobs', ',')
-let s:p4OptCmdMap['o'] = ['print']
-let s:p4OptCmdMap['s'] = split('changes,integrate', ',')
-let s:p4OptCmdMap['t'] = split('add,client,edit,label,reopen', ',')
-let s:p4OptCmdMap['O'] = ['passwd']
-let s:p4OptCmdMap['P'] = ['passwd']
-let s:p4OptCmdMap['S'] = ['set']
-
-" These built-in options require us to pass an argument. These options start
-"   with a '+'.
-let s:biOptCmdMap = {}
-let s:biOptCmdMap['c'] = ['diff']
-
-" Map the commands with short name to their long versions.
-let s:shortCmdMap = {}
-let s:shortCmdMap['p'] = 'print'
-let s:shortCmdMap['d'] = 'diff'
-let s:shortCmdMap['e'] = 'edit'
-let s:shortCmdMap['a'] = 'add'
-let s:shortCmdMap['r'] = 'revert'
-let s:shortCmdMap['g'] = 'get'
-let s:shortCmdMap['o'] = 'open'
-let s:shortCmdMap['d2'] = 'diff2'
-let s:shortCmdMap['h'] = 'help'
-
-
-" NOTE: The current file is used as the default argument, only when the
-"   command is not one of the s:askUserCmds and it is not one of
-"   s:curFileNotDefCmds or s:nofileArgsCmds.
-" For these commands, we don't need to default to the current file, as these
-"   commands can work without any arguments.
-let s:curFileNotDefCmds = split('change,changes,client,files,integrate,job,' .
-      \ 'jobs,jobspec,labels,labelsync,opened,resolve,submit,user,', ',')
-" For these commands, we need to ask user for the argument, as we can't assume
-"   the current file is the default.
-let s:askUserCmds = split('admin,branch,counter,depot,fix,group,label,', ',')
-" A subset of askUserCmds, that should use a more generic prompt.
-let s:genericPromptCmds = split('admin,counter,fix,', ',')
-" Commands that essentially display a list of files.
-let s:filelistCmds = split('files,have,integrate,opened,', ',')
-" Commands that work with a spec.
-let s:specCmds = split('branch,change,client,depot,group,job,jobspec,label,' .
-      \ 'protect,submit,triggers,typemap,user,', ',')
-" Out of the above specCmds, these are the only commands that don't
-"   support '-o' option. Consequently we have to have our own template.
-let s:noOutputCmds = ['submit']
-" The following are used only to create a specification, not to view them.
-"   Consequently, they don't accept a '-d' option to delete the spec.
-let s:specOnlyCmds = split('jobspec,submit,', ',')
-" These commands might change the fstat of files, requiring an update on some
-"   or all the buffers loaded into vim.
-"let s:statusUpdReqCmds = 'add,delete,edit,get,lock,reopen,revert,sync,unlock,'
-"" For these commands we need to call :checktime, as the command might have
-""   changed the state of the file.
-"let s:checktimeReqCmds = 'edit,get,reopen,revert,sync,'
-" For these commands, we can even set 'autoread' along with doing a :checktime.
-let s:autoreadCmds = split('edit,get,reopen,revert,sync,', ',')
-" These commands don't expect filename arguments, so no special processing for
-"   file expansion.
-let s:nofileArgsCmds = split('branch,branches,change,client,clients,counters,' .
-      \ 'depot,depots,describe,dirs,group,groups,help,info,job,jobspec,label,' .
-      \ 'logger,passwd,protect,rename,review,triggers,typemap,user,users,', ',')
-" For these commands, the output should not be set to perforce type.
-let s:ftNotPerforceCmds = split('diff,diff2,print,vdiff,vdiff2', ',')
-" Allows navigation keys in the command window.
-let s:navigateCmds = ['help']
-" These commands accept a '-m' argument to limit the list size.
-let s:limitListCmds = split('filelog,jobs,changes,', ',')
-" These commands take the diff option -dx.
-let s:diffCmds = split('describe,diff,diff2,', ',')
-" The following commands prefer dialog output. If the output exceeds
-"   g:p4MaxLinesInDialog, we should switch to showing the output in a window.
-let s:dlgOutputCmds =
-      \ split('add,delete,edit,get,lock,reopen,revert,sync,unlock,', ',')
-
-" If there is a confirm message, then PFIF() will prompt user before
-"   continuing with the run.
-let s:confirmMsgs{'revert'} = "Reverting file(s) will overwrite any edits to " .
-      \ "the files(s)\n Do you want to continue?"
-let s:confirmMsgs{'submit'} = "This will commit the changelist to the depot." .
-      \ "\n Do you want to continue?"
-
-" Settings that are not directly exposed to the user. These can be accessed
-"   using the public API.
-" Refresh the contents of perforce windows, even if the window is already open.
-let s:refreshWindowsAlways = 1
-
-" List of the global variable names of the user configurable settings.
-let s:settings = split('ClientRoot,CmdPath,Presets,' .
-      \ 'DefaultOptions,DefaultDiffOptions,EnableMenu,EnablePopupMenu,' .
-      \ 'UseExpandedMenu,UseExpandedPopupMenu,EnableRuler,RulerWidth,' .
-      \ 'DefaultListSize,EnableActiveStatus,OptimizeActiveStatus,' .
-      \ 'ASIgnoreDefPattern,ASIgnoreUsrPattern,PromptToCheckout,' .
-      \ 'CheckOutDefault,UseGUIDialogs,MaxLinesInDialog,SortSettings,' .
-      \ 'TempDir,SplitCommand,UseVimDiff2,EnableFileChangedShell,' .
-      \ 'BufHidden,Depot,Autoread,UseClientViewMap,DefaultPreset', ',')
-let s:settingsCompStr = ''
-
-let s:helpWinName = 'P4\ help'
-
-" Unprotected space.
-let s:SPACE_AS_SEP = genutils#CrUnProtectedCharsPattern(' ')
-let s:EMPTY_STR = '^\_s*$'
-
-if !exists('s:p4Client') || s:p4Client =~# s:EMPTY_STR
-  let s:p4Client = $P4CLIENT
-endif
-if !exists('s:p4User') || s:p4User =~# s:EMPTY_STR
-  if exists("$P4USER") && $P4USER !~# s:EMPTY_STR
-    let s:p4User = $P4USER
-  elseif genutils#OnMS() && exists("$USERNAME")
-    let s:p4User = $USERNAME
-  elseif exists("$LOGNAME")
-    let s:p4User = $LOGNAME
-  elseif exists("$USERNAME") " Happens if you are on cygwin too.
-    let s:p4User = $USERNAME
-  else
-    let s:p4User = ''
-  endif
-endif
-if !exists('s:p4Port') || s:p4Port =~# s:EMPTY_STR
-  let s:p4Port = $P4PORT
-endif
-let s:p4Password = $P4PASSWD
-
-let s:CM_RUN = 'run' | let s:CM_FILTER = 'filter' | let s:CM_DISPLAY = 'display'
-let s:CM_PIPE = 'pipe'
-
-let s:changesExpr  = "matchstr(getline(\".\"), '" .
-      \ '^Change \zs\d\+\ze ' . "')"
-let s:branchesExpr = "matchstr(getline(\".\"), '" .
-      \ '^Branch \zs[^ ]\+\ze ' . "')"
-let s:labelsExpr   = "matchstr(getline(\".\"), '" .
-      \ '^Label \zs[^ ]\+\ze ' . "')"
-let s:clientsExpr  = "matchstr(getline(\".\"), '" .
-      \ '^Client \zs[^ ]\+\ze ' . "')"
-let s:usersExpr    = "matchstr(getline(\".\"), '" .
-      \ '^[^ ]\+\ze <[^@>]\+@[^>]\+> ([^)]\+)' . "')"
-let s:jobsExpr     = "matchstr(getline(\".\"), '" .
-      \ '^[^ ]\+\ze on ' . "')"
-let s:depotsExpr   = "matchstr(getline(\".\"), '" .
-      \ '^Depot \zs[^ ]\+\ze ' . "')"
-let s:describeExpr = 's:DescribeGetCurrentItem()'
-let s:filelogExpr  = 's:GetCurrentDepotFile(line("."))'
-let s:groupsExpr   = 'expand("<cword>")'
-
-let s:fileBrowseExpr = 's:ConvertToLocalPath(s:GetCurrentDepotFile(line(".")))'
-let s:openedExpr   = s:fileBrowseExpr
-let s:filesExpr    = s:fileBrowseExpr
-let s:haveExpr     = s:fileBrowseExpr
-let s:integrateExpr = s:fileBrowseExpr
-" Open in describe window should open the local file.
-let s:describeOpenItemExpr = s:fileBrowseExpr
-
-" If an explicit handler is defined, then it will override the default rule of
-"   finding the command with the singular form.
-let s:filelogItemHandler = "s:printHdlr"
-let s:changesItemHandler = "s:changeHdlr"
-let s:openedItemHandler = "s:OpenFile"
-let s:describeItemHandler = "s:OpenFile"
-let s:filesItemHandler = "s:OpenFile"
-let s:haveItemHandler = "s:OpenFile"
-
-" Define handlers for built-in commands. These have no arguments, they will
-"   use the existing parsed command-line vars. Set s:errCode on errors.
-let s:builtinCmdHandler{'vdiff'} = 's:VDiffHandler' 
-let s:builtinCmdHandler{'vdiff2'} = 's:VDiff2Handler' 
-let s:builtinCmdHandler{'exec'} = 's:ExecHandler' 
-
-let s:vdiffCounter = 0
-
-" A stack of contexts.
-let s:p4Contexts = []
-
-" Cache of client view mappings, with client name as the key.
-let s:fromDepotMapping = {}
-let s:toDepotMapping = {}
-
-aug Perforce | aug END " Define autocommand group.
-call genutils#AddToFCShellPre('perforce#FileChangedShell')
-
-""" END: One-time initialization of some script variables }}}
-
-""" END: Initializations }}}
-
-
-""" BEGIN: Command specific functions {{{
-
-function! s:printHdlr(scriptOrigin, outputType, ...)
-  let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'print']
-        \ +a:000)
-
-  if s:StartBufSetup()
-    let undo = 0
-    " The first line printed by p4 for non-q operation causes vim to misjudge
-    " the filetype.
-    if getline(1) =~# '//[^#]\+#\d\+ - '
-      setlocal modifiable
-      let firstLine = getline(1)
-      silent! 1delete _
-    endif
-
-    set ft=
-    doautocmd filetypedetect BufNewFile
-    " If automatic detection doesn't work...
-    if &ft == ""
-      let &ft=s:GuessFileTypeForCurrentWindow()
-    endif
-
-    if exists('firstLine')
-      silent! 1put! =firstLine
-      setlocal nomodifiable
-    endif
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-function! s:describeHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'describe']+a:000)
-  endif
-  " If -s doesn't exist, and user doesn't intent to see a diff, then let us
-  "   add -s option. In any case he can press enter on the <SHOW DIFFS> to see
-  "   it later.
-  if index(s:p4CmdOptions, '-s') == -1 &&
-        \ s:indexMatching(s:p4CmdOptions, '^-d.\+$') == -1
-    call add(s:p4CmdOptions, '-s')
-    let s:p4WinName = s:MakeWindowName() " Adjust window name.
-  endif
-
-  let retVal = perforce#PFIF(2, a:outputType, 'describe')
-  if s:StartBufSetup() && getline(1) !~# ' - no such changelist'
-    call s:SetupFileBrowse()
-    if index(s:p4CmdOptions, '-s') != -1
-      setlocal modifiable
-      silent! 2,$g/^Change \d\+ by \|\%$/
-            \ call append(line('.')-1, ['', "\t<SHOW DIFFS>", ''])
-      setlocal nomodifiable
-    else
-      call s:SetupDiff()
-    endif
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-function! s:diffHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'diff']+a:000)
-  endif
-
-  " If a change number is specified in the diff, we need to handle it
-  "   ourselves, as p4 doesn't understand this.
-  let changeOptIdx = index(s:p4CmdOptions, '++c')
-  let changeNo = ''
-  if changeOptIdx != -1 " If a change no. is specified.
-    let changeNo = s:p4CmdOptions[changeOptIdx+1]
-    call s:PushP4Context()
-    try
-      call extend(s:p4Options, ['++T', '++N'], 0) " Testmode.
-      let retVal = perforce#PFIF(2, a:outputType, 'diff') " Opens window.
-      if s:errCode == 0
-        setlocal modifiable
-        exec '%PF ++f opened -c' changeNo
-      endif
-    finally
-      let cntxtStr = s:PopP4Context()
-    endtry
-  else
-    " Any + option is treated like a signal to run external diff.
-    let externalDiffOptExists = (s:indexMatching(s:p4CmdOptions, '^+\S\+$') != -1)
-    if externalDiffOptExists
-      if len(s:p4Arguments) > 1
-        return s:SyntaxError('External diff options can not be used with multiple files.')
-      endif
-      let needsPop = 0
-      try
-        let _p4Options = copy(s:p4Options)
-        call insert(s:p4Options, '++T', 0) " Testmode, just open the window.
-        let retVal = perforce#PFIF(2, 0, 'diff')
-        let s:p4Options = _p4Options
-        if s:errCode != 0
-          return
-        endif
-        call s:PushP4Context() | let needsPop = 1
-        PW print -q
-        if s:errCode == 0
-          setlocal modifiable
-          let fileName = s:ConvertToLocalPath(s:p4Arguments[0])
-          call s:PeekP4Context()
-          " Gather and process only external options.
-          " Sample:
-          " '-x +width=10 -du -y +U=20 -z -a -db +tabsize=4'
-          "   to
-          " '--width=10 -U 20 --tabsize=4'
-          let diffOpts = []
-          for opt in s:p4CmdOptions
-            if opt =~ '^+'
-              call add(diffOpts, substitute(opt, '^+\([^= ]\+\)=\(.*\)$',
-                    \ '\=(strlen(submatch(1)) > 1 ? '.
-                    \     '("--".submatch(1).'.
-                    \      '(submatch(2) != "" ? "=".submatch(2) : "")) : '.
-                    \     '("-".submatch(1).'.
-                    \      '(submatch(2) != "" ? " ".submatch(2) : "")))',
-                    \ 'g'))
-            endif
-          endfor
-          if getbufvar(bufnr('#'), '&ff') ==# 'dos'
-            setlocal ff=dos
-          endif
-          silent! exec '%!'.
-                \ genutils#EscapeCommand('diff', diffOpts+['--', '-', fileName],
-                \ '')
-          if v:shell_error > 1
-            call s:EchoMessage('Error executing external diff command. '.
-                  \ 'Verify that GNU (or a compatible) diff is in your path.',
-                  \ 'ERROR')
-            return ''
-          endif
-          call genutils#SilentSubstitute("\<CR>$", '%s///')
-          call genutils#SilentSubstitute('^--- -', '1s;;--- '.
-                \ s:ConvertToDepotPath(fileName))
-          1
-        endif
-      finally
-        setlocal nomodifiable
-        if needsPop
-          call s:PopP4Context()
-        endif
-      endtry
-    else
-      let retVal = perforce#PFIF(2, exists('$P4DIFF') ? 5 : a:outputType, 'diff')
-    endif
-  endif
-
-  if s:StartBufSetup()
-    call s:SetupDiff()
-
-    if changeNo != '' && getline(1) !~# 'ile(s) not opened on this client\.'
-      setl modifiable
-      call genutils#SilentSubstitute('#.*', '%s///e')
-      call s:SetP4ContextVars(cntxtStr) " Restore original diff context.
-      call perforce#PFIF(1, 0, '-x', '-', '++f', '++n', 'diff')
-      setl nomodifiable
-    endif
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-function! s:diff2Hdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'diff2']+a:000)
-  endif
-
-  let s:p4Arguments = s:GetDiff2Args()
-
-  let retVal = perforce#PFIF(2, exists('$P4DIFF') ? 5 : a:outputType, 'diff2')
-  if s:StartBufSetup()
-    call s:SetupDiff()
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-function! s:passwdHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'passwd']+a:000)
-  endif
-
-  let oldPasswd = ""
-  if index(s:p4CmdOptions, '-O') == -1
-    let oldPasswd = input('Enter old password: ')
-    " FIXME: Handle empty passwords.
-    call add(add(s:p4CmdOptions, '-O'), oldPasswd)
-  endif
-  let newPasswd = ""
-  if index(s:p4CmdOptions, '-P') == -1
-    while 1
-      let newPasswd = input('Enter new password: ')
-      if (input('Re-enter new password: ') != newPasswd)
-        call s:EchoMessage("Passwords don't match", 'Error')
-      else
-        " FIXME: Handle empty passwords.
-        call add(add(s:p4CmdOptions, '-P'), newPasswd)
-        break
-      endif
-    endwhile
-  endif
-  let retVal = perforce#PFIF(2, a:outputType, 'passwd')
-  return retVal
-endfunction
-
-" Only to avoid confirming for -n and -a options.
-function! s:revertHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1,
-          \ a:outputType, 'passwd']+a:000)
-  endif
-
-  if index(s:p4CmdOptions, '-n') != -1 || index(s:p4CmdOptions, '-a') != -1
-    call add(s:p4Options, '++y')
-  endif
-  let retVal = perforce#PFIF(2, a:outputType, 'revert')
-  return retVal
-endfunction
-
-function! s:changeHdlrImpl(outputType)
-  let _p4Arguments = s:p4Arguments
-  " If argument(s) is not a number...
-  if len(s:p4Arguments) != 0 && s:indexMatching(s:p4Arguments, '^\d\+$') == -1
-    let s:p4Arguments = [] " Let a new changelist be created.
-  endif
-  let retVal = perforce#PFIF(2, a:outputType, 'change')
-  let s:p4Arguments = _p4Arguments
-  if s:errCode == 0 && s:indexMatching(s:p4Arguments, '^\d\+$') == -1
-        \ && (s:StartBufSetup() || s:commandMode ==# s:CM_FILTER)
-    if len(s:p4Arguments) != 0
-      if search('^Files:\s*$', 'w') && line('.') != line('$')
-        +
-        call s:PushP4Context()
-        try
-          call call('perforce#PFrangeIF', [line("."), line("$"), 1, 0]+
-                \ s:p4Options+['++f', 'opened', '-c', 'default']+
-                \ s:p4Arguments)
-        finally
-          call s:PopP4Context()
-        endtry
-
-        if s:errCode == 0
-          call genutils#SilentSubstitute('^', '.,$s//\t/e')
-          call genutils#SilentSubstitute('#\d\+ - \(\S\+\) .*$',
-                \ '.,$s//\t# \1/e')
-        endif
-      endif
-    endif
-
-    call s:EndBufSetup()
-    setl nomodified
-    if len(s:p4Arguments) != 0 && &cmdheight > 1
-      " The message about W and WQ must have gone by now.
-      redraw | call perforce#LastMessage()
-    endif
-  else
-    " Save the filelist in this changelist so that we can update their status
-    " later.
-    if search('Files:\s*$', 'w')
-      let b:p4OrgFilelist = getline(line('.')+1, line('$'))
-    endif
-  endif
-  return retVal
-endfunction
-
-function! s:changeHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'change']+a:000)
-  endif
-  let retVal = s:changeHdlrImpl(a:outputType)
-  if s:StartBufSetup()
-    command! -buffer -nargs=* PChangeSubmit :call call('<SID>W',
-          \ [0]+b:p4Options+['submit']+split(<q-args>, '\s'))
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-" Create a template for submit.
-function! s:submitHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'submit']+a:000)
-  endif
-
-  if index(s:p4CmdOptions, '-c') != -1
-    " Non-interactive.
-    let retVal = perforce#PFIF(2, a:outputType, 'submit')
-  else
-    call s:PushP4Context()
-    try
-      " This is done just to get the :W and :WQ commands defined properly and
-      " open the window with a proper name. The actual job is done by the call
-      " to s:changeHdlrImpl() which is then run in filter mode to avoid the
-      " side-effects (such as :W and :WQ getting overwritten etc.)
-      call extend(s:p4Options, ['++y', '++T'], 0) " Don't confirm, and testmode.
-      call perforce#PFIF(2, 0, 'submit')
-      if s:errCode == 0
-        call s:PeekP4Context()
-        let s:p4CmdOptions = [] " These must be specific to 'submit'.
-        let s:p4Command = 'change'
-        let s:commandMode = s:CM_FILTER | let s:filterRange = '.'
-        let retVal = s:changeHdlrImpl(a:outputType)
-        setlocal nomodified
-        if s:errCode != 0
-          return
-        endif
-       endif
-    finally
-      call s:PopP4Context()
-    endtry
-
-    if s:StartBufSetup()
-      command! -buffer -nargs=* PSubmitPostpone :call call('<SID>W',
-            \ [0]+b:p4Options+['change']+split(<q-args>, '\s'))
-      set ft=perforce " Just to get the cursor placement right.
-      call s:EndBufSetup()
-    endif
-
-    if s:errCode
-      call s:EchoMessage("Error creating submission template.", 'Error')
-    endif
-  endif
-  return s:errCode
-endfunction
-
-function! s:resolveHdlr(scriptOrigin, outputType, ...)
-  if !a:scriptOrigin
-    call call('s:ParseOptionsIF', [1, line('$'), 1, a:outputType, 'resolve']+a:000)
-  endif
-
-  if (s:indexMatching(s:p4CmdOptions, '^-a[fmsty]$') == -1) &&
-        \ (index(s:p4CmdOptions, '-n') == -1)
-    return s:SyntaxError("Interactive resolve not implemented (yet).")
-  endif
-  let retVal = perforce#PFIF(2, a:outputType, 'resolve')
-  return retVal
-endfunction
-
-function! s:filelogHdlr(scriptOrigin, outputType, ...)
-  let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'filelog']+a:000)
-
-  if s:StartBufSetup()
-    " No meaning for delete.
-    silent! nunmap <buffer> D
-    silent! delcommand PItemDelete
-    command! -range -buffer -nargs=0 PFilelogDiff
-          \ :call s:FilelogDiff2(<line1>, <line2>)
-    vnoremap <silent> <buffer> D :PFilelogDiff<CR>
-    command! -buffer -nargs=0 PFilelogPrint :call perforce#PFIF(0, 0, 'print',
-          \ <SID>GetCurrentItem())
-    nnoremap <silent> <buffer> p :PFilelogPrint<CR>
-    command! -buffer -nargs=0 PFilelogSync :call <SID>FilelogSyncToCurrentItem()
-    nnoremap <silent> <buffer> S :PFilelogSync<CR>
-    command! -buffer -nargs=0 PFilelogDescribe
-          \ :call <SID>FilelogDescribeChange()
-    nnoremap <silent> <buffer> C :PFilelogDescribe<CR>
-
-    call s:EndBufSetup()
-  endif
-endfunction
-
-function! s:clientsHdlr(scriptOrigin, outputType, ...)
-  let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'clients']+a:000)
-
-  if s:StartBufSetup()
-    command! -buffer -nargs=0 PClientsTemplate
-          \ :call perforce#PFIF(0, 0, '++A', 'client', '-t', <SID>GetCurrentItem())
-    nnoremap <silent> <buffer> P :PClientsTemplate<CR>
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-function! s:changesHdlr(scriptOrigin, outputType, ...)
-  let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'changes']+a:000)
-
-  if s:StartBufSetup()
-    command! -buffer -nargs=0 PItemDescribe
-          \ :call <SID>PChangesDescribeCurrentItem()
-    command! -buffer -nargs=0 PChangesSubmit
-          \ :call <SID>ChangesSubmitChangeList()
-    nnoremap <silent> <buffer> S :PChangesSubmit<CR>
-    command! -buffer -nargs=0 PChangesOpened
-          \ :if getline('.') =~# " \\*pending\\* '" |
-          \    call perforce#PFIF(1, 0, 'opened', '-c', <SID>GetCurrentItem()) |
-          \  endif
-    nnoremap <silent> <buffer> o :PChangesOpened<CR>
-    command! -buffer -nargs=0 PChangesDiff
-          \ :if getline('.') =~# " \\*pending\\* '" |
-          \    call perforce#PFIF(0, 0, 'diff', '++c', <SID>GetCurrentItem()) |
-          \  else |
-          \    call perforce#PFIF(0, 0, 'describe', (<SID>('DefaultDiffOptions')
-          \                 =~ '^\s*$' ? '-dd' : <SID>('DefaultDiffOptions')),
-          \                   <SID>GetCurrentItem()) |
-          \  endif
-    nnoremap <silent> <buffer> d :PChangesDiff<CR>
-    command! -buffer -nargs=0 PItemOpen
-          \ :if getline('.') =~# " \\*pending\\* '" |
-          \    call perforce#PFIF(0, 0, 'change', <SID>GetCurrentItem()) |
-          \  else |
-          \    call perforce#PFIF(0, 0, 'describe', '-dd', <SID>GetCurrentItem()) |
-          \  endif
-
-    call s:EndBufSetup()
-  endif
-endfunction
-
-function! s:labelsHdlr(scriptOrigin, outputType, ...)
-  let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'labels']+a:000)
-
-  if s:StartBufSetup()
-    command! -buffer -nargs=0 PLabelsSyncClient
-          \ :call <SID>LabelsSyncClientToLabel()
-    nnoremap <silent> <buffer> S :PLabelsSyncClient<CR>
-    command! -buffer -nargs=0 PLabelsSyncLabel
-          \ :call <SID>LabelsSyncLabelToClient()
-    nnoremap <silent> <buffer> C :PLabelsSyncLabel<CR>
-    command! -buffer -nargs=0 PLabelsFiles :call perforce#PFIF(0, 0, '++n', 'files',
-          \ '//...@'. <SID>GetCurrentItem())
-    nnoremap <silent> <buffer> I :PLabelsFiles<CR>
-    command! -buffer -nargs=0 PLabelsTemplate :call perforce#PFIF(0, 0, '++A',
-          \ 'label', '-t', <SID>GetCurrentItem())
-    nnoremap <silent> <buffer> P :PLabelsTemplate<CR>
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-function! s:helpHdlr(scriptOrigin, outputType, ...)
-  call genutils#SaveWindowSettings2("PerforceHelp", 1)
-  " If there is a help window already open, then we need to reuse it.
-  let helpWin = bufwinnr(s:helpWinName)
-  let retVal = call('perforce#PFIF', [a:scriptOrigin + 1, a:outputType, 'help']+a:000)
-
-  if s:StartBufSetup()
-    command! -buffer -nargs=0 PHelpSelect
-          \ :call perforce#PFIF(0, 0, 'help', expand("<cword>"))
-    nnoremap <silent> <buffer> <CR> :PHelpSelect<CR>
-    nnoremap <silent> <buffer> K :PHelpSelect<CR>
-    nnoremap <silent> <buffer> <2-LeftMouse> :PHelpSelect<CR>
-    call genutils#AddNotifyWindowClose(s:helpWinName, s:myScriptId .
-          \ "RestoreWindows")
-    if helpWin == -1 " Resize only when it was not already visible.
-      exec "resize " . 20
-    endif
-    redraw | echo
-          \ "Press <CR>/K/<2-LeftMouse> to drilldown on perforce help keywords."
-
-    call s:EndBufSetup()
-  endif
-  return retVal
-endfunction
-
-" Built-in command handlers {{{
-function! s:VDiffHandler()
-  let nArgs = len(s:p4Arguments)
-  if nArgs > 2
-    return s:SyntaxError("vdiff: Too many arguments.")
-  endif
-
-  let firstFile = ''
-  let secondFile = ''
-  if nArgs == 2
-    let firstFile = s:p4Arguments[0]
-    let secondFile = s:p4Arguments[1]
-  elseif nArgs == 1
-    let secondFile = s:p4Arguments[0]
-  else
-    let secondFile = s:EscapeFileName(s:GetCurFileName())
-  endif
-  if firstFile == ''
-    let firstFile = s:ConvertToDepotPath(secondFile)
-  endif
-  call s:VDiffImpl(firstFile, secondFile, 0)
-endfunction
-
-function! s:VDiff2Handler()
-  if len(s:p4Arguments) > 2
-    return s:SyntaxError("vdiff2: Too many arguments")
-  endif
-
-  let s:p4Arguments = s:GetDiff2Args()
-  call s:VDiffImpl(s:p4Arguments[0], s:p4Arguments[1], 1)
-endfunction
-
-function! s:VDiffImpl(firstFile, secondFile, preferDepotPaths)
-  let firstFile = a:firstFile
-  let secondFile = a:secondFile
-
-  if a:preferDepotPaths || s:PathRefersToDepot(firstFile)
-    let firstFile = s:ConvertToDepotPath(firstFile)
-    let tempFile1 = s:MakeTempName(firstFile)
-  else
-    let tempFile1 = firstFile
-  endif
-  if a:preferDepotPaths || s:PathRefersToDepot(secondFile)
-    let secondFile = s:ConvertToDepotPath(secondFile)
-    let tempFile2 = s:MakeTempName(secondFile)
-  else
-    let tempFile2 = secondFile
-  endif
-  if firstFile =~# s:EMPTY_STR || secondFile =~# s:EMPTY_STR ||
-        \ (tempFile1 ==# tempFile2)
-    return s:SyntaxError("diff requires two distinct files as arguments.")
-  endif
-
-  let s:vdiffCounter = s:vdiffCounter + 1
-
-  if s:IsDepotPath(firstFile)
-    let s:p4Command = 'print'
-    let s:p4CmdOptions = ['-q']
-    let s:p4WinName = tempFile1
-    let s:p4Arguments = [firstFile]
-    call perforce#PFIF(2, 0, 'print')
-    if s:errCode != 0
-      return
-    endif
-  else
-    let v:errmsg = ''
-    silent! exec 'split' firstFile
-    if v:errmsg != ""
-      return s:ShowVimError("Error opening file: ".firstFile."\n".v:errmsg, '')
-    endif
-  endif
-  diffthis
-  let w:p4VDiffWindow = s:vdiffCounter
-  wincmd K
-
-  " CAUTION: If there is a buffer or window local value, then this will get
-  " overridden, but it is OK.
-  if exists('t:p4SplitCommand')
-    let _splitCommand = t:p4SplitCommand
-  endif
-  let t:p4SplitCommand = 'vsplit'
-  let _splitright = &splitright
-  set splitright
-  try
-    if s:IsDepotPath(secondFile)
-      let s:p4Command = 'print'
-      let s:p4CmdOptions = ['-q']
-      let s:p4WinName = tempFile2
-      let s:p4Arguments = [secondFile]
-      call perforce#PFIF(2, 0, 'print')
-      if s:errCode != 0
-        return
-      endif
-    else
-      let v:errmsg = ''
-      silent! exec 'vsplit' secondFile
-      if v:errmsg != ""
-        return s:ShowVimError("Error opening file: ".secondFile."\n".v:errmsg, '')
-      endif
-    endif
-  finally
-    if exists('_splitCommand')
-      let t:p4SplitCommand = _splitCommand
-    else
-      unlet t:p4SplitCommand
-    endif
-    let &splitright = _splitright
-  endtry
-  diffthis
-  let w:p4VDiffWindow = s:vdiffCounter
-  wincmd _
-endfunction
-
-" Returns a fileName in the temp directory that is unique for the branch and
-"   revision specified in the fileName.
-function! s:MakeTempName(filePath)
-  let depotPath = s:ConvertToDepotPath(a:filePath)
-  if depotPath =~# s:EMPTY_STR
-    return ''
-  endif
-  let tmpName = s:_('TempDir') . '/'
-  let branch = s:GetBranchName(depotPath)
-  if branch !~# s:EMPTY_STR
-    let tmpName = tmpName . branch . '-'
-  endif
-  let revSpec = s:GetRevisionSpecifier(depotPath)
-  if revSpec !~# s:EMPTY_STR
-    let tmpName = tmpName . substitute(strpart(revSpec, 1), '/', '_', 'g') . '-'
-  endif
-  return tmpName . fnamemodify(substitute(a:filePath, '\\*#\d\+$', '', ''),
-        \ ':t')
-endfunction
-
-function! s:ExecHandler()
-  if len(s:p4Arguments) != 0
-    echo join(s:p4Arguments, ' ')
-    let cmdHasBang = 0
-    if s:p4Arguments[0] =~# '^!'
-      let cmdHasBang = 1
-      " FIXME: Pipe itself needs to be escaped, and they could be chained.
-      let cmd = genutils#EscapeCommand(substitute(s:p4Arguments[0], '^!', '',
-            \ ''), s:p4Arguments[1:], s:p4Pipe)
-    else
-      let cmd = join(s:p4Arguments, ' ')
-    endif
-    let cmd = genutils#Escape(cmd, '#%!')
-    try
-      exec (cmdHasBang ? '!' : '').cmd
-    catch
-      let v:errmsg = substitute(v:exception, '^[^:]\+:', '', '')
-      call s:ShowVimError(v:errmsg, v:throwpoint)
-    endtry
-  endif
-endfunction
-
-" Built-in command handlers }}}
-
-""" END: Command specific functions }}}
-
-
-""" BEGIN: Helper functions {{{
-
-" Open a file from an alternative codeline.
-" If mode == 0, first file is opened and all other files are added to buffer
-"   list.
-" If mode == 1, the files are not really opened, the list is just returned.
-" If mode == 2, it behaves the same as mode == 0, except that the file is
-"   split opened.
-" If there are no arguments passed, user is prompted to enter. He can then
-"   enter a codeline followed by a list of filenames.
-" If only one argument is passed, it is assumed to be the codeline and the
-"   current filename is assumed (user is not prompted).
-function! perforce#PFOpenAltFile(mode, ...) " {{{
-  let argList = copy(a:000)
-  if a:0 < 2
-    if a:0 == 0
-      " Prompt for codeline string (codeline optionally followed by filenames).
-      let codelineStr = s:PromptFor(0, s:_('UseGUIDialogs'),
-            \ "Enter the alternative codeline string: ", '')
-      if codelineStr =~# s:EMPTY_STR
-        return ""
-      endif
-      let argList = split(codelineStr, s:SPACE_AS_SEP)
-    endif
-    if len(argList) == 1
-      call add(argList, s:EscapeFileName(s:GetCurFileName()))
-    endif
-  endif
-
-  let altFileNames = call('s:PFGetAltFiles', ['']+argList)
-  if a:mode == 0 || a:mode == 2
-    let firstFile = 1
-    for altFileName in altFileNames
-      if firstFile
-        execute ((a:mode == 0) ? ":edit " : ":split ") . altFileName
-        let firstFile = 0
-      else
-        execute ":badd " . altFileName
-      endif
-    endfor
-  else
-    return join(altFileNames, ' ')
-  endif
-endfunction " }}}
-
-" Interactively change the port/client/user. {{{
-function! perforce#SwitchPortClientUser()
-  let p4Port = s:PromptFor(0, s:_('UseGUIDialogs'), "Port: ", s:_('p4Port'))
-  let p4Client = s:PromptFor(0, s:_('UseGUIDialogs'), "Client: ", s:_('p4Client'))
-  let p4User = s:PromptFor(0, s:_('UseGUIDialogs'), "User: ", s:_('p4User'))
-  call perforce#PFSwitch(1, p4Port, p4Client, p4User)
-endfunction
-
-" No args: Print presets and prompt user to select a preset.
-" Number: Select that numbered preset.
-" port [client] [user]: Set the specified settings.
-function! perforce#PFSwitch(updateClientRoot, ...)
-  if a:0 == 0 || match(a:1, '^\d\+$') == 0
-    let selPreset = ''
-    let presets = split(s:_('Presets'), ',')
-    if a:0 == 0
-      if len(presets) == 0
-        call s:EchoMessage("No presets to select from.", 'Error')
-        return
-      endif
-
-      let selPreset = genutils#PromptForElement(presets, -1,
-            \ "Select the setting: ", -1, s:_('UseGUIDialogs'), 1)
-    else
-      let index = a:1 + 0
-      if index >= len(presets)
-        call s:EchoMessage("Not that many presets.", 'Error')
-        return
-      endif
-      let selPreset = presets[index]
-    endif
-    if selPreset == ''
-      return
-    endif
-    let argList = split(selPreset, s:SPACE_AS_SEP)
-  else
-    if a:0 == 1
-      let argList = split(a:1, ' ')
-    else
-      let argList = a:000
-    endif
-  endif
-  call call('s:PSwitchHelper', [a:updateClientRoot]+argList)
-
-  " Loop through all the buffers and invalidate the filestatuses.
-  let lastBufNr = bufnr('$')
-  let i = 1
-  while i <= lastBufNr
-    if bufexists(i) && getbufvar(i, '&buftype') == ''
-      call s:ResetFileStatusForBuffer(i)
-    endif
-    let i = i + 1
-  endwhile
-endfunction
-
-function! s:PSwitchHelper(updateClientRoot, ...)
-  let p4Port = a:1
-  let p4Client = s:_('p4Client')
-  let p4User = s:_('p4User')
-  if a:0 > 1
-    let p4Client = a:2
-  endif
-  if a:0 > 2
-    let p4User = a:3
-  endif
-  if ! s:SetPortClientUser(p4Port, p4Client, p4User)
-    return
-  endif
-
-  if a:updateClientRoot
-    if s:p4Port !=# 'P4CONFIG'
-      call s:GetClientInfo()
-    else
-      let g:p4ClientRoot = '' " Since the client is chosen dynamically.
-    endif
-  endif
-endfunction
-
-function! s:SetPortClientUser(port, client, user)
-  if s:p4Port ==# a:port && s:p4Client ==# a:client && s:p4User ==# a:user
-    return 0
-  endif
-
-  let s:p4Port = a:port
-  let s:p4Client = a:client
-  let s:p4User = a:user
-  let s:p4Password = ''
-  return 1
-endfunction
-
-function! perforce#PFSwitchComplete(ArgLead, CmdLine, CursorPos)
-  return substitute(s:_('Presets'), ',', "\n", 'g')
-endfunction
-" port/client/user }}}
-
-function! s:PHelpComplete(ArgLead, CmdLine, CursorPos)
-  if s:p4KnownCmdsCompStr == ''
-    let s:p4KnownCmdsCompStr = join(s:p4KnownCmds, "\n")
-  endif
-  return s:p4KnownCmdsCompStr.
-          \ "simple\ncommands\nenvironment\nfiletypes\njobview\nrevisions\n".
-          \ "usage\nviews\n"
-endfunction
-" Handler for opened command.
-function! s:OpenFile(scriptOrigin, outputType, fileName) " {{{
-  if filereadable(a:fileName)
-    if a:outputType == 0
-      let curWin = winnr()
-      let bufNr = genutils#FindBufferForName(a:fileName)
-      let winnr = bufwinnr(bufNr)
-      if winnr != -1
-        exec winnr.'wincmd w'
-      else
-        wincmd p
-      endif
-      if curWin != winnr() && &previewwindow
-        wincmd p " Don't use preview window.
-      endif
-      " Avoid loosing temporary buffers accidentally.
-      if winnr() == curWin || getbufvar('%', '&bufhidden') != ''
-        split
-      endif
-      if winbufnr(winnr()) != bufNr
-        if bufNr != -1
-          exec "buffer" bufNr | " Preserves cursor position.
-        else
-          exec "edit " . a:fileName
-        endif
-      endif
-    else
-      exec "pedit " . a:fileName
-    endif
-  else
-    call perforce#PFIF(0, a:outputType, 'print', a:fileName)
-  endif
-endfunction " }}}
-
-function! s:DescribeGetCurrentItem() " {{{
-  if getline(".") ==# "\t<SHOW DIFFS>"
-    let [changeHdrLine, col] = searchpos('^Change \zs\d\+ by ', 'bnW')
-    if changeHdrLine != 0
-      let changeNo = matchstr(getline(changeHdrLine), '\d\+', col-1)
-      let _modifiable = &l:modifiable
-      try
-        setlocal modifiable
-        call genutils#SaveHardPosition('DescribeGetCurrentItem')
-        exec changeHdrLine.',.PF ++f describe' s:_('DefaultDiffOptions') changeNo
-        call genutils#RestoreHardPosition('DescribeGetCurrentItem')
-        call genutils#ResetHardPosition('DescribeGetCurrentItem')
-      finally
-        let &l:modifiable = _modifiable
-      endtry
-      call s:SetupDiff()
-    endif
-    return ""
-  endif
-  return s:GetCurrentDepotFile(line('.'))
-endfunction " }}}
-
-function! s:getCommandItemHandler(outputType, command, args) " {{{
-  let itemHandler = ""
-  if exists("s:{a:command}ItemHandler")
-    let itemHandler = s:{a:command}ItemHandler
-  elseif match(a:command, 'e\?s$') != -1
-    let handlerCmd = substitute(a:command, 'e\?s$', '', '')
-    if exists('*s:{handlerCmd}Hdlr')
-      let itemHandler = 's:' . handlerCmd . 'Hdlr'
-    else
-      let itemHandler = 'perforce#PFIF'
-    endif
-  endif
-  if itemHandler ==# 'perforce#PFIF'
-    return "call perforce#PFIF(1, " . a:outputType . ", '" . handlerCmd . "', " .
-          \ a:args . ")"
-  elseif itemHandler !~# s:EMPTY_STR
-    return 'call ' . itemHandler . '(0, ' . a:outputType . ', ' . a:args . ')'
-  endif
-  return itemHandler
-endfunction " }}}
-
-function! s:OpenCurrentItem(outputType) " {{{
-  let curItem = s:GetOpenItem(a:outputType)
-  if curItem !~# s:EMPTY_STR
-    let commandHandler = s:getCommandItemHandler(a:outputType, b:p4Command,
-          \ "'" . curItem . "'")
-    if commandHandler !~# s:EMPTY_STR
-      exec commandHandler
-    endif
-  endif
-endfunction " }}}
-
-function! s:GetCurrentItem() " {{{
-  if exists("b:p4Command") && exists("s:{b:p4Command}Expr")
-    exec "return " s:{b:p4Command}Expr
-  endif
-  return ""
-endfunction " }}}
-
-function! s:GetOpenItem(outputType) " {{{
-  " For non-preview open.
-  if exists("b:p4Command") && a:outputType == 0 &&
-        \ exists("s:{b:p4Command}OpenItemExpr")
-    exec "return " s:{b:p4Command}OpenItemExpr
-  endif
-  return s:GetCurrentItem()
-endfunction " }}}
-
-function! s:DeleteCurrentItem() " {{{
-  let curItem = s:GetCurrentItem()
-  if curItem !~# s:EMPTY_STR
-    let answer = s:ConfirmMessage("Are you sure you want to delete " .
-          \ curItem . "?", "&Yes\n&No", 2, "Question")
-    if answer == 1
-      let commandHandler = s:getCommandItemHandler(2, b:p4Command,
-            \ "'-d', '" . curItem . "'")
-      if commandHandler !~# s:EMPTY_STR
-        exec commandHandler
-      endif
-      if v:shell_error == ""
-        call perforce#PFRefreshActivePane()
-      endif
-    endif
-  endif
-endfunction " }}}
-
-function! s:LaunchCurrentFile() " {{{
-  if g:p4FileLauncher =~# s:EMPTY_STR
-    call s:ConfirmMessage("There was no launcher command configured to launch ".
-          \ "this item, use g:p4FileLauncher to configure." , "OK", 1, "Error")
-    return
-  endif
-  let curItem = s:GetCurrentItem()
-  if curItem !~# s:EMPTY_STR
-    exec 'silent! !'.g:p4FileLauncher curItem
-  endif
-endfunction " }}}
-
-function! s:FilelogDiff2(line1, line2) " {{{
-  let line1 = a:line1
-  let line2 = a:line2
-  if line1 == line2
-    if line2 < line("$")
-      let line2 = line2 + 1
-    elseif line1 > 1
-      let line1 = line1 - 1
-    else
-      return
-    endif
-  endif
-
-  let file1 = s:GetCurrentDepotFile(line1)
-  if file1 !~# s:EMPTY_STR
-    let file2 = s:GetCurrentDepotFile(line2)
-    if file2 !~# s:EMPTY_STR && file2 != file1
-      " file2 will be older than file1.
-      exec "call perforce#PFIF(0, 0, \"" . (s:_('UseVimDiff2') ? 'vdiff2' : 'diff2') .
-            \ "\", file2, file1)"
-    endif
-  endif
-endfunction " }}}
-
-function! s:FilelogSyncToCurrentItem() " {{{
-  let curItem = s:GetCurrentItem()
-  if curItem !~# s:EMPTY_STR
-    let answer = s:ConfirmMessage("Do you want to sync to: " . curItem . " ?",
-          \ "&Yes\n&No", 2, "Question")
-    if answer == 1
-      call perforce#PFIF(1, 2, 'sync', curItem)
-    endif
-  endif
-endfunction " }}}
-
-function! s:ChangesSubmitChangeList() " {{{
-  let curItem = s:GetCurrentItem()
-  if curItem !~# s:EMPTY_STR
-    let answer = s:ConfirmMessage("Do you want to submit change list: " .
-          \ curItem . " ?", "&Yes\n&No", 2, "Question")
-    if answer == 1
-      call perforce#PFIF(0, 0, '++y', 'submit', '-c', curItem)
-    endif
-  endif
-endfunction " }}}
-
-function! s:LabelsSyncClientToLabel() " {{{
-  let curItem = s:GetCurrentItem()
-  if curItem !~# s:EMPTY_STR
-    let answer = s:ConfirmMessage("Do you want to sync client to the label: " .
-          \ curItem . " ?", "&Yes\n&No", 2, "Question")
-    if answer == 1
-      let retVal = call('perforce#PFIF', [1, 1, 'sync',
-            \ '//".s:_('Depot')."/...@'.curItem])
-      return retVal
-    endif
-  endif
-endfunction " }}}
-
-function! s:LabelsSyncLabelToClient() " {{{
-  let curItem = s:GetCurrentItem()
-  if curItem !~# s:EMPTY_STR
-    let answer = s:ConfirmMessage("Do you want to sync label: " . curItem .
-          \ " to client " . s:_('p4Client') . " ?", "&Yes\n&No", 2, "Question")
-    if answer == 1
-      let retVal = perforce#PFIF(1, 1, 'labelsync', '-l', curItem)
-      return retVal
-    endif
-  endif
-endfunction " }}}
-
-function! s:FilelogDescribeChange() " {{{
-  let changeNo = matchstr(getline("."), ' change \zs\d\+\ze ')
-  if changeNo !~# s:EMPTY_STR
-    exec "call perforce#PFIF(0, 1, 'describe', changeNo)"
-  endif
-endfunction " }}}
-
-function! s:SetupFileBrowse() " {{{
-  " For now, assume that a new window is created and we are in the new window.
-  exec "setlocal includeexpr=P4IncludeExpr(v:fname)"
-
-  " No meaning for delete.
-  silent! nunmap <buffer> D
-  silent! delcommand PItemDelete
-  command! -buffer -nargs=0 PFileDiff :call perforce#PFIF(0, 1, 'diff',
-        \ <SID>GetCurrentDepotFile(line(".")))
-  nnoremap <silent> <buffer> D :PFileDiff<CR>
-  command! -buffer -nargs=0 PFileProps :call perforce#PFIF(1, 0, 'fstat', '-C',
-        \ <SID>GetCurrentDepotFile(line(".")))
-  nnoremap <silent> <buffer> P :PFileProps<CR>
-  command! -buffer -nargs=0 PFileLog :call perforce#PFIF(1, 0, 'filelog',
-        \ <SID>GetCurrentDepotFile(line(".")))
-  command! -buffer -nargs=0 PFileEdit :call perforce#PFIF(1, 2, 'edit',
-        \ <SID>GetCurrentItem())
-  nnoremap <silent> <buffer> I :PFileEdit<CR>
-  command! -buffer -bar -nargs=0 PFileRevert :call perforce#PFIF(1, 2, 'revert',
-        \ <SID>GetCurrentItem())
-  nnoremap <silent> <buffer> R :PFileRevert \| PFRefreshActivePane<CR>
-  command! -buffer -nargs=0 PFilePrint
-        \ :if getline('.') !~# '(\%(u\|ux\)binary)$' |
-        \   call perforce#PFIF(0, 0, 'print',
-        \   substitute(<SID>GetCurrentDepotFile(line('.')), '#[^#]\+$', '', '').
-        \   '#'.
-        \   ((getline(".") =~# '#\d\+ - delete change') ?
-        \    matchstr(getline('.'), '#\zs\d\+\ze - ') - 1 :
-        \    matchstr(getline('.'), '#\zs\d\+\ze - '))
-        \   ) |
-        \ else |
-        \   echo 'PFilePrint: Binary file... ignored.' |
-        \ endif
-  nnoremap <silent> <buffer> p :PFilePrint<CR>
-  command! -buffer -nargs=0 PFileGet :call perforce#PFIF(1, 2, 'sync',
-        \ <SID>GetCurrentDepotFile(line(".")))
-  command! -buffer -nargs=0 PFileSync :call perforce#PFIF(1, 2, 'sync',
-        \ <SID>GetCurrentItem())
-  nnoremap <silent> <buffer> S :PFileSync<CR>
-  command! -buffer -nargs=0 PFileChange :call perforce#PFIF(0, 0, 'change', 
-        \ <SID>GetCurrentChangeNumber(line(".")))
-  nnoremap <silent> <buffer> C :PFileChange<CR>
-  command! -buffer -nargs=0 PFileLaunch :call <SID>LaunchCurrentFile()
-  nnoremap <silent> <buffer> A :PFileLaunch<CR>
-endfunction " }}}
-
-function! s:SetupDiff() " {{{
-  setlocal ft=diff
-endfunction " }}}
-
-function! s:SetupSelectItem() " {{{
-  nnoremap <buffer> <silent> D :PItemDelete<CR>
-  nnoremap <buffer> <silent> O :PItemOpen<CR>
-  nnoremap <buffer> <silent> <CR> :PItemDescribe<CR>
-  nnoremap <buffer> <silent> <2-LeftMouse> :PItemDescribe<CR>
-  command! -buffer -nargs=0 PItemDescribe :call <SID>OpenCurrentItem(1)
-  command! -buffer -nargs=0 PItemOpen :call <SID>OpenCurrentItem(0)
-  command! -buffer -nargs=0 PItemDelete :call <SID>DeleteCurrentItem()
-  cnoremap <buffer> <C-X><C-I> <C-R>=<SID>GetCurrentItem()<CR>
-endfunction " }}}
-
-function! s:RestoreWindows(dummy) " {{{
-  call genutils#RestoreWindowSettings2("PerforceHelp")
-endfunction " }}}
-
-function! s:NavigateBack() " {{{
-  call s:Navigate('u')
-  if line('$') == 1 && getline(1) == ''
-    call s:NavigateForward()
-  endif
-endfunction " }}}
-
-function! s:NavigateForward() " {{{
-  call s:Navigate("\<C-R>")
-endfunction " }}}
-
-function! s:Navigate(key) " {{{
-  let _modifiable = &l:modifiable
-  try
-    setlocal modifiable
-    " Use built-in markers as Vim takes care of remembering and restoring them
-    "   during the undo/redo.
-    normal! mt
-
-    silent! exec "normal" a:key
-
-    if line("'t") > 0 && line("'t") <= line('$')
-      normal! `t
-    endif
-  finally
-    let &l:modifiable = _modifiable
-  endtry
-endfunction " }}}
-
-function! s:GetCurrentChangeNumber(lineNo) " {{{
-  let line = getline(a:lineNo)
-  let changeNo = matchstr(line, ' - \S\+ change \zs\S\+\ze (')
-  if changeNo ==# 'default'
-    let changeNo = ''
-  endif
-  return changeNo
-endfunction " }}}
-
-function! s:PChangesDescribeCurrentItem() " {{{
-  let currentChangeNo = s:GetCurrentItem()
-  if currentChangeNo !~# s:EMPTY_STR
-    call perforce#PFIF(0, 1, 'describe', '-s', currentChangeNo)
-  endif
-endfunction " }}}
-
-" {{{
-function! perforce#PFSettings(...)
-  if s:_('SortSettings ')
-    if exists("s:sortedSettings")
-      let settings = s:sortedSettings
-    else
-      let settings = sort(s:settings)
-      let s:sortedSettings = settings
-    endif
-  else
-    let settings = s:settings
-  endif
-  if a:0 > 0
-    let selectedSetting = a:1
-  else
-    let selectedSetting = genutils#PromptForElement(settings, -1,
-          \ "Select the setting: ", -1, 0, 3)
-  endif
-  if selectedSetting !~# s:EMPTY_STR
-    let oldVal = s:_(selectedSetting)
-    if a:0 > 1
-      let newVal = a:2
-      echo 'Current value for' selectedSetting.': "'.oldVal.'" New value: "'.
-            \ newVal.'"'
-    else
-      let newVal = input('Current value for ' . selectedSetting . ' is: ' .
-            \ oldVal . "\nEnter new value: ", oldVal)
-    endif
-    if newVal != oldVal
-      let g:p4{selectedSetting} = newVal
-      call perforce#Initialize(1)
-    endif
-  endif
-endfunction
-
-function! perforce#PFSettingsComplete(ArgLead, CmdLine, CursorPos)
-  if s:settingsCompStr == ''
-    let s:settingsCompStr = join(s:settings, "\n")
-  endif
-  return s:settingsCompStr
-endfunction
-" }}}
-
-function! s:MakeRevStr(ver) " {{{
-  let verStr = ''
-  if a:ver =~# '^[#@&]'
-    let verStr = a:ver
-  elseif a:ver =~# '^[-+]\?\d\+\>\|^none\>\|^head\>\|^have\>'
-    let verStr = '#' . a:ver
-  elseif a:ver !~# s:EMPTY_STR
-    let verStr = '@' . a:ver
-  endif
-  return verStr
-endfunction " }}}
-
-function! s:GetBranchName(fileName) " {{{
-  if s:IsFileUnderDepot(a:fileName)
-    " TODO: Need to run where command at this phase.
-  elseif stridx(a:fileName, '//') == 0
-    return matchstr(a:fileName, '^//[^/]\+/\zs[^/]\+\ze')
-  else
-    return ''
-  endif
-endfunction " }}}
-
-function! s:GetDiff2Args()
-  let p4Arguments = s:p4Arguments
-  if len(p4Arguments) < 2
-    if len(p4Arguments) == 0
-      let file = s:EscapeFileName(s:GetCurFileName())
-    else
-      let file = p4Arguments[0]
-    endif
-    let ver1 = s:PromptFor(0, s:_('UseGUIDialogs'), "Version1? ", '')
-    let ver2 = s:PromptFor(0, s:_('UseGUIDialogs'), "Version2? ", '')
-    let p4Arguments = [file.s:MakeRevStr(ver1), file.s:MakeRevStr(ver2)]
-  endif
-  return p4Arguments
-endfunction
-
-function! perforce#ToggleCheckOutPrompt(interactive)
-  aug P4CheckOut
-  au!
-  if g:p4PromptToCheckout
-    let g:p4PromptToCheckout = 0
-  else
-    let g:p4PromptToCheckout = 1
-    au FileChangedRO * nested :call <SID>CheckOutFile()
-  endif
-  aug END
-  if a:interactive
-    echomsg "PromptToCheckout is now " . ((g:p4PromptToCheckout) ? "enabled." :
-          \ "disabled.")
-  endif
-endfunction
-
-function! perforce#PFDiffOff(diffCounter)
-  " Cycle through all windows and turn off diff options for the specified diff
-  " run, or all, if none specified.
-  let curWinNr = winnr()
-  let eventignore = &eventignore
-  set eventignore=all
-  try
-    let i = 1
-    while winbufnr(i) != -1
-      try
-        exec i 'wincmd w'
-        if ! exists('w:p4VDiffWindow')
-          continue
-        endif
-
-        if a:diffCounter == -1 || w:p4VDiffWindow == a:diffCounter
-          call genutils#CleanDiffOptions()
-          unlet w:p4VDiffWindow
-        endif
-      finally
-        let i = i + 1
-      endtry
-    endwhile
-  finally
-    " Return to the original window.
-    exec curWinNr 'wincmd w'
-    let &eventignore = eventignore
-  endtry
-endfunction
-""" END: Helper functions }}}
-
-
-""" BEGIN: Middleware functions {{{
-
-" Filter contents through p4.
-function! perforce#PW(fline, lline, scriptOrigin, ...) range
-  if a:scriptOrigin != 2
-    call call('s:ParseOptions', [a:fline, a:lline, 0, '++f'] + a:000)
-  else
-    let s:commandMode = s:CM_FILTER
-  endif
-  setlocal modifiable
-  let retVal = perforce#PFIF(2, 5, s:p4Command)
-  return retVal
-endfunction
-
-" Generate raw output into a new window.
-function! perforce#PFRaw(...)
-  call call('s:ParseOptions', [1, line('$'), 0] + a:000)
-
-  let retVal = s:PFImpl(1, 0)
-  return retVal
-endfunction
-
-function! s:W(quitWhenDone, commandName, ...)
-  call call('s:ParseOptionsIF', [1, line('$'), 0, 5, a:commandName]+a:000)
-  if index(s:p4CmdOptions, '-i') == -1
-    call insert(s:p4CmdOptions, '-i', 0)
-  endif
-  let retVal = perforce#PW(1, line('$'), 2)
-  if s:errCode == 0
-    setl nomodified
-    if a:quitWhenDone
-      close
-    else
-      if s:p4Command ==# 'change' || s:p4Command ==# 'submit'
-        " Change number fixed, or files added/removed.
-        if s:FixChangeNo() || search('^Change \d\+ updated, ', 'w')
-          silent! undo
-          if search('^Files:\s*$', 'w')
-            let b:p4NewFilelist = getline(line('.')+1, line('$'))
-            if !exists('b:p4OrgFilelist')
-              let filelist = b:p4NewFilelist
-            else
-              " Find outersection.
-              let filelist = copy(b:p4NewFilelist)
-              call filter(filelist, 'index(b:p4OrgFilelist, v:val)==-1')
-              call extend(filelist, filter(copy(b:p4OrgFilelist), 'index(b:p4NewFilelist, v:val)==-1'))
-            endif
-            let files = map(filelist, 's:ConvertToLocalPath(v:val)')
-            call s:ResetFileStatusForFiles(files)
-          endif
-          silent! redo
-        endif
-      endif
-    endif
-  else
-    call s:FixChangeNo()
-  endif
-endfunction
-
-function! s:FixChangeNo()
-  if search('^Change \d\+ created', 'w') ||
-        \ search('^Change \d\+ renamed change \d\+ and submitted', 'w')
-    let newChangeNo = matchstr(getline('.'), '\d\+\ze\%(created\|and\)')
-    let _undolevels=&undolevels
-    try
-      let allLines = getline(1, line('$'))
-      silent! undo
-      " Make the below changes such a way that they can't be undo. This in a
-      "   way, forces Vim to create an undo point, so that user can later
-      "   undo and see these changes, with proper change number and status
-      "   in place. This has the side effect of loosing the previous undo
-      "   history, which can be considered desirable, as otherwise the user
-      "   can undo this change and back to the new state.
-      set undolevels=-1
-      if search("^Change:\t\%(new\|\d\+\)$")
-        silent! keepjumps call setline('.', "Change:\t" . newChangeNo)
-        " If no Date is present (happens for new changelists)
-        if !search("^Date:\t", 'w')
-          call append('.', ['', "Date:\t".strftime('%Y/%m/%d %H:%M:%S')])
-        endif
-      endif
-      if search("^Status:\tnew$")
-        silent! keepjumps call setline('.', "Status:\tpending")
-      endif
-      setl nomodified
-      let &undolevels=_undolevels
-      silent! 0,$delete _
-      call setline(1, allLines)
-      setl nomodified
-      call s:PFSetupForSpec()
-    finally
-      let &undolevels=_undolevels
-    endtry
-    let b:p4Command = 'change'
-    let b:p4CmdOptions = ['-i']
-    return 1
-  else
-    return 0
-  endif
-endfunction
-
-function! s:ParseOptionsIF(fline, lline, scriptOrigin, outputType, commandName,
-      \ ...) " range
-  " There are multiple possibilities here:
-  "   - scriptOrigin, in which case the commandName contains the name of the
-  "     command, but the varArgs also may contain it.
-  "   - commandOrigin, in which case the commandName may actually be the
-  "     name of the command, or it may be the first argument to p4 itself, in
-  "     any case we will let p4 handle the error cases.
-  if index(s:allCommands, a:commandName) != -1 && a:scriptOrigin
-    call call('s:ParseOptions', [a:fline, a:lline, a:outputType] + a:000)
-    " Add a:commandName only if it doesn't already exist in the var args.
-    " Handles cases like "PF help submit" and "PF -c <client> change changeno#",
-    "   where the commandName need not be at the starting and there could be
-    "   more than one valid commandNames (help and submit).
-    if s:p4Command != a:commandName
-      call call('s:ParseOptions',
-            \ [a:fline, a:lline, a:outputType, a:commandName] + a:000)
-    endif
-  else
-    call call('s:ParseOptions',
-          \ [a:fline, a:lline, a:outputType, a:commandName] + a:000)
-  endif
-endfunction
-
-" PFIF {{{
-" The commandName may not be the perforce command when it is not of script
-"   origin (called directly from a command), but it should be always command
-"   name, when it is script origin.
-" scriptOrigin: An integer indicating the origin of the call. 
-"   0 - Originated directly from the user, so should redirect to the specific
-"       command handler (if exists), after some basic processing.
-"   1 - Originated from the script, continue with the full processing (makes
-"       difference in some command parsing).
-"   2 - Same as 1 but, avoid processing arguments (they are already processing
-"       by the caller).
-function! perforce#PFIF(scriptOrigin, outputType, commandName, ...)
-  return call('perforce#PFrangeIF', [1, line('$'), a:scriptOrigin, a:outputType,
-        \ a:commandName]+a:000)
-endfunction
-
-function! perforce#PFrangeIF(fline, lline, scriptOrigin, outputType,
-      \ commandName, ...)
-  if a:scriptOrigin != 2
-    call call('s:ParseOptionsIF', [a:fline, a:lline,
-          \ a:scriptOrigin, a:outputType, a:commandName]+a:000)
-  endif
-  if ! a:scriptOrigin
-    " Save a copy of the arguments so that the refresh can invoke this exactly
-    " as it was before.
-    let s:userArgs = [a:fline, a:lline, a:scriptOrigin, a:outputType, a:commandName]
-          \ +a:000
-  endif
-
-
-  let outputOptIdx = index(s:p4Options, '++o')
-  if outputOptIdx != -1
-    " Get the argument followed by ++o.
-    let s:outputType = get(s:p4Options, outputIdx + 1) + 0
-  endif
-  " If this command prefers a dialog output, then just take care of
-  "   it right here.
-  if index(s:dlgOutputCmds, s:p4Command) != -1
-    let s:outputType = 2
-  endif
-  if ! a:scriptOrigin
-    if exists('*s:{s:p4Command}Hdlr')
-      return s:{s:p4Command}Hdlr(1, s:outputType, a:commandName)
-    endif
-  endif
-  let modifyWindowName = 0
-  let dontProcess = (index(s:p4Options, '++n') != -1)
-  let noDefaultArg = (index(s:p4Options, '++N') != -1)
-  " If there is a confirm message for this command, then first prompt user.
-  let dontConfirm = (index(s:p4Options, '++y') != -1)
-  if exists('s:confirmMsgs{s:p4Command}') && ! dontConfirm
-    let option = s:ConfirmMessage(s:confirmMsgs{s:p4Command}, "&Yes\n&No", 2,
-          \ "Question")
-    if option == 2
-      let s:errCode = 2
-      return ''
-    endif
-  endif
-
-  if index(s:limitListCmds, s:p4Command) != -1 &&
-        \ index(s:p4CmdOptions, '-m') == -1 && s:_('DefaultListSize') > -1
-    call extend(s:p4CmdOptions, ['-m', s:_('DefaultListSize')], 0)
-    let modifyWindowName = 1
-  endif
-  if index(s:diffCmds, s:p4Command) != -1 &&
-        \ s:indexMatching(s:p4CmdOptions, '^-d.*$') == -1
-        \ && s:_('DefaultDiffOptions') !~# s:EMPTY_STR
-    " FIXME: Avoid split().
-    call extend(s:p4CmdOptions, split(s:_('DefaultDiffOptions'), '\s'), 0)
-    let modifyWindowName = 1
-  endif
-
-  " Process p4Arguments, unless explicitly not requested to do so, or the '-x'
-  "   option to read arguments from a file is given.
-  let unprotectedSpecPat = genutils#CrUnProtectedCharsPattern('&#@')
-  if ! dontProcess && ! noDefaultArg && len(s:p4Arguments) == 0 &&
-        \ index(s:p4Options, '-x') == -1
-    if (index(s:askUserCmds, s:p4Command) != -1 &&
-          \ index(s:p4CmdOptions, '-i') == -1) ||
-          \ index(s:p4Options, '++A') != -1
-      if index(s:genericPromptCmds, s:p4Command) != -1
-        let prompt = 'Enter arguments for ' . s:p4Command . ': '
-      else
-        let prompt = "Enter the " . s:p4Command . " name: "
-      endif
-      let additionalArg = s:PromptFor(0, s:_('UseGUIDialogs'), prompt, '')
-      if additionalArg =~# s:EMPTY_STR
-        if index(s:genericPromptCmds, s:p4Command) != -1
-          call s:EchoMessage('Arguments required for '. s:p4Command, 'Error')
-        else
-          call s:EchoMessage(substitute(s:p4Command, "^.", '\U&', '') .
-                \ " name required.", 'Error')
-        endif
-        let s:errCode = 2
-        return ''
-      endif
-      let s:p4Arguments = [additionalArg]
-    elseif ! dontProcess &&
-          \ index(s:curFileNotDefCmds, s:p4Command) == -1 &&
-          \ index(s:nofileArgsCmds, s:p4Command) == -1
-      let s:p4Arguments = [s:EscapeFileName(s:GetCurFileName())]
-      let modifyWindowName = 1
-    endif
-  elseif ! dontProcess && s:indexMatching(s:p4Arguments, unprotectedSpecPat) != -1
-    let branchModifierSpecified = 0
-    let unprotectedAmp = genutils#CrUnProtectedCharsPattern('&')
-    if s:indexMatching(s:p4Arguments, unprotectedAmp) != -1
-      let branchModifierSpecified = 1
-      " CAUTION: We make sure the view mappings are generated before
-      "   s:PFGetAltFiles() gets invoked, otherwise the call results in a
-      "   recursive |sub-replace-special| and corrupts the mappings.
-      call s:CondUpdateViewMappings()
-    endif
-
-    " This is like running substitute(v:val, 'pat', '\=expr', 'g') on each
-    "   element.
-    " Pattern is (the start of line or series of non-space chars) followed by
-    "   an unprotected [#@&] with a revision/codeline specifier.
-    " Expression is a concatenation of each of:
-    "   (<no filename specified>?<current file>:<specified file>)
-    "   <revision specifier>
-    "   (<offset specified>?<adjusted revision>:<specified revision>)
-    call map(s:p4Arguments, "substitute(v:val, '".
-          \ '\(^\|\%(\S\)\+\)\('.unprotectedSpecPat.'\)\%(\2\)\@!\([-+]\?\d\+\|\S\+\)'."', ".
-          \ "'\\=s:ExpandRevision(submatch(1), submatch(2), submatch(3))', 'g')")
-    if s:errCode != 0
-      return ''
-    endif
-
-    if branchModifierSpecified
-      call map(s:p4Arguments, 
-            \ '(v:val =~ unprotectedAmp ? s:ApplyBranchSpecs(v:val, unprotectedAmp) : v:val)')
-    endif
-    " Unescape them, as user is required to escape them to avoid the above
-    " processing.
-    call map(s:p4Arguments, "genutils#UnEscape(v:val, '&@')")
-
-    let modifyWindowName = 1
-  endif
-
-  let testMode = 0
-  if index(s:p4Options, '++T') != -1
-    let testMode = 1 " Dry run, opens the window.
-  elseif index(s:p4Options, '++D') != -1
-    let testMode = 2 " Debug. Opens the window and displays the command.
-  endif
-
-  let oldOptLen = len(s:p4Options)
-  " Remove all the built-in options.
-  call filter(s:p4Options, "v:val !~ '".'++\S\+\%(\s\+[^-+]\+\|\s\+\)\?'."'")
-  if len(s:p4Options) != oldOptLen
-    let modifyWindowName = 1
-  endif
-  if index(s:diffCmds, s:p4Command) != -1
-    " Remove the dummy option, if exists (see |perforce-default-diff-format|).
-    call filter(s:p4CmdOptions, 'v:val != "-d"')
-    let modifyWindowName = 1
-  endif
-
-  if s:p4Command ==# 'help'
-    " Use simple window name for all the help commands.
-    let s:p4WinName = s:helpWinName
-  elseif modifyWindowName
-    let s:p4WinName = s:MakeWindowName() 
-  endif
-
-  " If the command is a built-in command, then don't pass it to external p4.
-  if exists('s:builtinCmdHandler{s:p4Command}')
-    let s:errCode = 0
-    return {s:builtinCmdHandler{s:p4Command}}()
-  endif
-
-  let specMode = 0
-  if index(s:specCmds, s:p4Command) != -1
-    if index(s:p4CmdOptions, '-d') == -1
-          \ && index(s:p4CmdOptions, '-o') == -1
-          \ && index(s:noOutputCmds, s:p4Command) == -1
-      call add(s:p4CmdOptions, '-o')
-    endif
-
-    " Go into specification mode only if the user intends to edit the output.
-    if ((s:p4Command ==# 'submit' && index(s:p4CmdOptions, '-c') == -1) ||
-          \ (index(s:specOnlyCmds, s:p4Command) == -1 &&
-          \  index(s:p4CmdOptions, '-d') == -1)) &&
-          \ s:outputType == 0
-      let specMode = 1
-    endif
-  endif
-  
-  let navigateCmd = 0
-  if index(s:navigateCmds, s:p4Command) != -1
-    let navigateCmd = 1
-  endif
-
-  let retryCount = 0
-  let retVal = ''
-  " FIXME: When is "not clearing" (value 2) useful at all?
-  let clearBuffer = (testMode != 2 ? ! navigateCmd : 2)
-  " CAUTION: This is like a do..while loop, but not exactly the same, be
-  " careful using continue, the counter will not get incremented.
-  while 1
-    let retVal = s:PFImpl(clearBuffer, testMode)
-
-    " Everything else in this loop is for password support.
-    if s:errCode == 0
-      break
-    else
-      if retVal =~# s:EMPTY_STR
-        let retVal = getline(1)
-      endif
-      " FIXME: Works only with English as the language.
-      if retVal =~# 'Perforce password (P4PASSWD) invalid or unset.'
-        let p4Password = inputsecret("Password required for user " .
-              \ s:_('p4User') . ": ", s:p4Password)
-        if p4Password ==# s:p4Password
-          break
-        endif
-        let s:p4Password = p4Password
-      else
-        break
-      endif
-    endif
-    let retryCount = retryCount + 1
-    if retryCount > 2
-      break
-    endif
-  endwhile
-
-  if s:errCode == 0 && index(s:autoreadCmds, s:p4Command) != -1
-    call s:ResetFileStatusForFiles(s:p4Arguments)
-  endif
-
-  if s:errCode != 0
-    return retVal
-  endif
-
-  call s:SetupWindow(specMode)
-
-  return retVal
-endfunction
-
-function! s:SetupWindow(specMode)
-  if s:StartBufSetup()
-    " If this command has a handler for the individual items, then enable the
-    " item selection commands.
-    if s:getCommandItemHandler(0, s:p4Command, '') !~# s:EMPTY_STR
-      call s:SetupSelectItem()
-    endif
-
-    if index(s:ftNotPerforceCmds, s:p4Command) == -1
-      setlocal ft=perforce
-    endif
-
-    if index(s:filelistCmds, s:p4Command) != -1
-      call s:SetupFileBrowse()
-    endif
-
-    if s:NewWindowCreated()
-      if a:specMode
-        " It is not possible to have an s:p4Command which is in s:allCommands
-        "         and still not be the actual intended command.
-        command! -buffer -nargs=* W :call call('<SID>W',
-              \ [0]+b:p4Options+[b:p4Command]+b:p4CmdOptions+split(<q-args>,
-              \ '\s'))
-        command! -buffer -nargs=* WQ :call call('<SID>W',
-              \ [1]+b:p4Options+[b:p4Command]+b:p4CmdOptions+split(<q-args>,
-              \ '\s'))
-        call s:EchoMessage("When done, save " . s:p4Command .
-              \ " spec by using :W or :WQ command. Undo on errors.", 'None')
-        call s:PFSetupForSpec()
-      else " Define q to quit the read-only perforce windows (David Fishburn)
-        nnoremap <buffer> q <C-W>q
-      endif
-    endif
-
-    if index(s:navigateCmds, s:p4Command) != -1
-      nnoremap <silent> <buffer> <C-O> :call <SID>NavigateBack()<CR>
-      nnoremap <silent> <buffer> <BS> :call <SID>NavigateBack()<CR>
-      nnoremap <silent> <buffer> <Tab> :call <SID>NavigateForward()<CR>
-    endif
-
-    call s:EndBufSetup()
-  endif
-endfunction
-
-function! s:ExpandRevision(fName, revType, revSpec)
-  return (a:fName==''?s:EscapeFileName(s:GetCurFileName()):a:fName).
-        \ a:revType.
-        \ (a:revSpec=~'^[-+]'?s:AdjustRevision(a:fName, a:revSpec):a:revSpec)
-endfunction
-
-function! s:ApplyBranchSpecs(arg, unprotectedAmp)
-  " The first arg will be filename, followed by multiple specifiers.
-  let toks = split(a:arg, a:unprotectedAmp)
-  " FIXME: Handle "&" in the filename.
-  " FIXME: Handle other revision specifiers occuring in any order
-  " (e.g., <file>&branch#3).
-  " Ex: c:/dev/docs/Triage/Tools/Machine\ Configurations\ &\ Codeline\ Requirements.xls
-  if len(toks) == 0 || toks[0] == ''
-    return a:arg
-  endif
-  let fname = remove(toks, 0)
-  " Reduce filename according to the branch tokens.
-  for altBranch in toks
-    let fname = s:PFGetAltFiles("&", altBranch, fname)[0]
-  endfor
-  return fname
-endfunction
-
-function! perforce#PFComplete(ArgLead, CmdLine, CursorPos)
-  if s:p4KnownCmdsCompStr == ''
-    let s:p4KnownCmdsCompStr = join(s:p4KnownCmds, "\n")
-  endif
-  if a:CmdLine =~ '^\s*P[FW] '
-    let argStr = strpart(a:CmdLine, matchend(a:CmdLine, '^\s*PF '))
-    let s:p4Command = ''
-    if argStr !~# s:EMPTY_STR
-      if exists('g:p4EnableUserFileExpand')
-        let _p4EnableUserFileExpand = g:p4EnableUserFileExpand
-      endif
-      try
-        " WORKAROUND for :redir broken, when called from here.
-        let g:p4EnableUserFileExpand = 0
-        exec 'call s:ParseOptionsIF(-1, -1, 0, 0, ' .
-              \ genutils#CreateArgString(argStr, s:SPACE_AS_SEP).')'
-      finally
-        if exists('_p4EnableUserFileExpand')
-          let g:p4EnableUserFileExpand = _p4EnableUserFileExpand
-        else
-          unlet g:p4EnableUserFileExpand
-        endif
-      endtry
-    endif
-    if s:p4Command ==# '' || s:p4Command ==# a:ArgLead
-      return s:p4KnownCmdsCompStr."\n".join(s:builtinCmds, "\n")
-    endif
-  else
-    let userCmd = substitute(a:CmdLine, '^\s*P\(.\)\(\w*\).*', '\l\1\2', '')
-    if strlen(userCmd) < 3
-      if !has_key(s:shortCmdMap, userCmd)
-        throw "Perforce internal error: no map found for short command: ".
-              \ userCmd
-      endif
-      let userCmd = s:shortCmdMap[userCmd]
-    endif
-    let s:p4Command = userCmd
-  endif
-  if s:p4Command ==# 'help'
-    return s:PHelpComplete(a:ArgLead, a:CmdLine, a:CursorPos)
-  endif
-  if index(s:nofileArgsCmds, s:p4Command) != -1
-    return ''
-  endif
-
-  " FIXME: Can't set command-line from user function.
-  "let argLead = genutils#UserFileExpand(a:ArgLead)
-  "if argLead !=# a:ArgLead
-  "  let cmdLine = strpart(a:CmdLine, 0, a:CursorPos-strlen(a:ArgLead)) .
-  "        \ argLead . strpart(a:CmdLine, a:CursorPos)
-  "  exec "normal! \<C-\>e'".cmdLine."'\<CR>"
-  "  call setcmdpos(a:CursorPos+(strlen(argLead) - strlen(a:ArgLead)))
-  "  return ''
-  "endif
-  if a:ArgLead =~ '^//'.s:_('Depot').'/'
-    " Get directory matches.
-    let dirMatches = s:GetOutput('dirs', a:ArgLead, "\n", '/&')
-    " Get file matches.
-    let fileMatches = s:GetOutput('files', a:ArgLead, '#\d\+[^'."\n".']\+', '')
-    if dirMatches !~ s:EMPTY_STR || fileMatches !~ s:EMPTY_STR
-      return dirMatches.fileMatches
-    else
-      return ''
-    endif
-  endif
-  return genutils#UserFileComplete(a:ArgLead, a:CmdLine, a:CursorPos, 1, '')
-endfunction
-
-function! s:GetOutput(p4Cmd, arg, pat, repl)
-  let matches = perforce#PFIF(0, 4, a:p4Cmd, a:arg.'*')
-  if s:errCode == 0
-    if matches =~ 'no such file(s)'
-      let matches = ''
-    else
-      let matches = substitute(substitute(matches, a:pat, a:repl, 'g'),
-            \ "\n\n", "\n", 'g')
-    endif
-  endif
-  return matches
-endfunction
-" PFIF }}}
-
-""" START: Adopted from Tom's perforce plugin. {{{
-
-"---------------------------------------------------------------------------
-" Produce string for ruler output
-function! perforce#RulerStatus()
-  if exists('b:p4RulerStr') && b:p4RulerStr !~# s:EMPTY_STR
-    return b:p4RulerStr
-  endif
-  if !exists('b:p4FStatDone') || !b:p4FStatDone
-    return ''
-  endif
-
-  "let b:p4RulerStr = '[p4 '
-  let b:p4RulerStr = '['
-  if exists('b:p4RulerErr') && b:p4RulerErr !~# s:EMPTY_STR
-    let b:p4RulerStr = b:p4RulerStr . b:p4RulerErr
-  elseif !exists('b:p4HaveRev')
-    let b:p4RulerStr = ''
-  elseif b:p4Action =~# s:EMPTY_STR
-    if b:p4OtherOpen =~# s:EMPTY_STR
-      let b:p4RulerStr = b:p4RulerStr . 'unopened'
-    else
-      let b:p4RulerStr = b:p4RulerStr . b:p4OtherOpen . ':' . b:p4OtherAction
-    endif
-  else
-    if b:p4Change ==# 'default' || b:p4Change =~# s:EMPTY_STR
-      let b:p4RulerStr = b:p4RulerStr . b:p4Action
-    else
-      let b:p4RulerStr = b:p4RulerStr . b:p4Action . ':' . b:p4Change
-    endif
-  endif
-  if exists('b:p4HaveRev') && b:p4HaveRev !~# s:EMPTY_STR
-    let b:p4RulerStr = b:p4RulerStr . ' #' . b:p4HaveRev . '/' . b:p4HeadRev
-  endif
-
-  if b:p4RulerStr !~# s:EMPTY_STR
-    let b:p4RulerStr = b:p4RulerStr . ']'
-  endif
-  return b:p4RulerStr
-endfunction
-
-function! s:GetClientInfo()
-  let infoStr = ''
-  call s:PushP4Context()
-  try
-    let infoStr = perforce#PFIF(0, 4, 'info')
-    if s:errCode != 0
-      return s:ConfirmMessage((v:errmsg != '') ? v:errmsg : infoStr, 'OK', 1,
-            \ 'Error')
-    endif
-  finally
-    call s:PopP4Context(0)
-  endtry
-  let g:p4ClientRoot = genutils#CleanupFileName(s:StrExtract(infoStr,
-        \ '\CClient root: [^'."\n".']\+', 13))
-  let s:p4Client = s:StrExtract(infoStr, '\CClient name: [^'."\n".']\+', 13)
-  let s:p4User = s:StrExtract(infoStr, '\CUser name: [^'."\n".']\+', 11)
-endfunction
-
-" Get/refresh filestatus for the specified buffer with optimizations.
-function! perforce#GetFileStatus(buf, refresh)
-  if ! type(a:buf) " If number.
-    let bufNr = (a:buf == 0) ? bufnr('%') : a:buf
-  else
-    let bufNr = bufnr(a:buf)
-  endif
-
-  " If it is not a normal buffer, then ignore it.
-  if getbufvar(bufNr, '&buftype') != '' || bufname(bufNr) == ''
-    return ""
-  endif
-  if bufNr == -1 || (!a:refresh && s:_('OptimizeActiveStatus') &&
-        \ getbufvar(bufNr, "p4FStatDone"))
-    return ""
-  endif
-
-  " This is an optimization by restricting status to the files under the
-  "   client root only.
-  if !s:IsFileUnderDepot(expand('#'.bufNr.':p'))
-    return ""
-  endif
-
-  return s:GetFileStatusImpl(bufNr)
-endfunction
-
-function! s:ResetFileStatusForFiles(files)
-  for file in a:files
-    let bufNr = genutils#FindBufferForName(file)
-    if bufNr != -1
-      " FIXME: Check for other tabs also.
-      if bufwinnr(bufNr) != -1 " If currently visible.
-        call perforce#GetFileStatus(bufNr, 1)
-      else
-        call s:ResetFileStatusForBuffer(bufNr)
-      endif
-    endif
-  endfor
-endfunction
-
-function! s:ResetFileStatusForBuffer(bufNr)
-  " Avoid proliferating this buffer variable.
-  if getbufvar(a:bufNr, 'p4FStatDone') != 0
-    call setbufvar(a:bufNr, 'p4FStatDone', 0)
-  endif
-endfunction
-
-"---------------------------------------------------------------------------
-" Obtain file status information
-function! s:GetFileStatusImpl(bufNr)
-  if bufname(a:bufNr) == ""
-    return ''
-  endif
-  let fileName = fnamemodify(bufname(a:bufNr), ':p')
-  let bufNr = a:bufNr
-  " If the filename matches with one of the ignore patterns, then don't do
-  " status.
-  if s:_('ASIgnoreDefPattern') !~# s:EMPTY_STR &&
-        \ match(fileName, s:_('ASIgnoreDefPattern')) != -1
-    return ''
-  endif
-  if s:_('ASIgnoreUsrPattern') !~# s:EMPTY_STR &&
-        \ match(fileName, s:_('ASIgnoreUsrPattern')) != -1
-    return ''
-  endif
-
-  call setbufvar(bufNr, 'p4RulerStr', '') " Let this be reconstructed.
-
-  " This could very well be a recursive call, so we should save the current
-  "   state.
-  call s:PushP4Context()
-  try
-    let fileStatusStr = perforce#PFIF(1, 4, 'fstat', fileName)
-    call setbufvar(bufNr, 'p4FStatDone', '1')
-
-    if s:errCode != 0
-      call setbufvar(bufNr, 'p4RulerErr', "<ERROR>")
-      return ''
-    endif
-  finally
-    call s:PopP4Context(0)
-  endtry
-
-  if match(fileStatusStr, ' - file(s) not in client view\.') >= 0
-    call setbufvar(bufNr, 'p4RulerErr', "<Not In View>")
-    " Required for optimizing out in future runs.
-    call setbufvar(bufNr, 'p4HeadRev', '')
-    return ''
-  elseif match(fileStatusStr, ' - no such file(s).') >= 0
-    call setbufvar(bufNr, 'p4RulerErr', "<Not In Depot>")
-    " Required for optimizing out in future runs.
-    call setbufvar(bufNr, 'p4HeadRev', '')
-    return ''
-  else
-    call setbufvar(bufNr, 'p4RulerErr', '')
-  endif
-
-  call setbufvar(bufNr, 'p4HeadRev',
-        \ s:StrExtract(fileStatusStr, '\CheadRev [0-9]\+', 8))
-  "call setbufvar(bufNr, 'p4DepotFile',
-  "      \ s:StrExtract(fileStatusStr, '\CdepotFile [^'."\n".']\+', 10))
-  "call setbufvar(bufNr, 'p4ClientFile',
-  "      \ s:StrExtract(fileStatusStr, '\CclientFile [^'."\n".']\+', 11))
-  call setbufvar(bufNr, 'p4HaveRev',
-        \ s:StrExtract(fileStatusStr, '\ChaveRev [0-9]\+', 8))
-  let headAction = s:StrExtract(fileStatusStr, '\CheadAction [^[:space:]]\+',
-        \ 11)
-  if headAction ==# 'delete'
-    call setbufvar(bufNr, 'p4Action', '<Deleted>')
-    call setbufvar(bufNr, 'p4Change', '')
-  else
-    call setbufvar(bufNr, 'p4Action',
-          \ s:StrExtract(fileStatusStr, '\Caction [^[:space:]]\+', 7))
-    call setbufvar(bufNr, 'p4OtherOpen',
-          \ s:StrExtract(fileStatusStr, '\CotherOpen0 [^[:space:]@]\+', 11))
-    call setbufvar(bufNr, 'p4OtherAction',
-          \ s:StrExtract(fileStatusStr, '\CotherAction0 [^[:space:]@]\+', 13))
-    call setbufvar(bufNr, 'p4Change',
-          \ s:StrExtract(fileStatusStr, '\Cchange [^[:space:]]\+', 7))
-  endif
-
-  return fileStatusStr
-endfunction
-
-function! s:StrExtract(str, pat, pos)
-  let part = matchstr(a:str, a:pat)
-  let part = strpart(part, a:pos)
-  return part
-endfunction
-
-function! s:AdjustRevision(file, adjustment)
-  let s:errCode = 0
-  let revNum = a:adjustment
-  if revNum =~# '[-+]\d\+'
-    let revNum = substitute(revNum, '^+', '', '')
-    if getbufvar(a:file, 'p4HeadRev') =~# s:EMPTY_STR
-      " If fstat is not done yet, do it now.
-      call perforce#GetFileStatus(a:file, 1)
-      if getbufvar(a:file, 'p4HeadRev') =~# s:EMPTY_STR
-        call s:EchoMessage("Current revision is not available. " .
-              \ "To be able to use negative revisions, see help on " .
-              \ "'perforce-active-status'.", 'Error')
-        let s:errCode = 1
-        return -1
-      endif
-    endif
-    let revNum = getbufvar(a:file, 'p4HaveRev') + revNum
-    if revNum < 1
-      call s:EchoMessage("Not that many revisions available. Try again " .
-            \ "after running PFRefreshFileStatus command.", 'Error')
-      let s:errCode = 1
-      return -1
-    endif
-  endif
-  return revNum
-endfunction
-
-"---------------------------------------------------------------------------
-" One of a set of functions that returns fields from the p4 fstat command
-function! s:IsCurrent()
-  let revdiff = b:p4HeadRev - b:p4HaveRev
-  if revdiff == 0
-    return 0
-  else
-    return -1
-  endif
-endfunction
-
-function! s:CheckOutFile()
-  if ! g:p4PromptToCheckout || ! s:IsFileUnderDepot(expand('%:p'))
-    return
-  endif
-  " If we know that the file is deleted from the depot, don't prompt.
-  if exists('b:p4Action') && b:p4Action == '<Deleted>'
-    return
-  endif
-
-  if filereadable(expand("%")) && ! filewritable(expand("%"))
-    let option = s:ConfirmMessage("Readonly file, do you want to checkout " .
-          \ "from perforce?", "&Yes\n&No\n&Cancel", s:_('CheckOutDefault'),
-          \ "Question")
-    if option == 1
-      call perforce#PFIF(1, 2, 'edit')
-      if ! s:errCode
-        edit
-        call perforce#GetFileStatus(expand('<abuf>') + 0, 1)
-      endif
-    elseif option == 3
-      call s:CancelEdit(0)
-    endif
-  endif
-endfunction
-
-function! s:CancelEdit(stage)
-  aug P4CancelEdit
-    au!
-    if a:stage == 0
-      au CursorMovedI <buffer> nested :call <SID>CancelEdit(1)
-      au CursorMoved <buffer> nested :call <SID>CancelEdit(1)
-    elseif a:stage == 1
-      stopinsert
-      silent undo
-      setl readonly
-    endif
-  aug END
-endfunction
-
-function! perforce#FileChangedShell()
-  let bufNr = expand("<abuf>") + 0
-  if s:_('EnableActiveStatus')
-    call s:ResetFileStatusForBuffer(bufNr)
-  endif
-  let autoread = -1
-  if index(s:autoreadCmds, s:currentCommand) != -1
-    let autoread = s:_('Autoread')
-    if autoread
-      call setbufvar(bufNr, '&readonly', 0)
-    endif
-  endif
-  return autoread
-endfunction
-""" END: Adapted from Tom's perforce plugin. }}}
-
-""" END: Middleware functions }}}
-
-
-""" BEGIN: Infrastructure {{{
-
-" Assumes that the arguments are already parsed and are ready to be used in
-"   the script variables.
-" Low level interface with the p4 command.
-" clearBuffer: If the buffer contents should be cleared before
-"     adding the new output (See s:GotoWindow).
-" testMode (number):
-"   0 - Run normally.
-"   1 - testing, ignore.
-"   2 - debugging, display the command-line instead of the actual output..
-" Returns the output if available. If there is any error, the error code will
-"   be available in s:errCode variable.
-function! s:PFImpl(clearBuffer, testMode) " {{{
-  try " [-2f]
-
-  let s:errCode = 0
-  let p4Options = s:GetP4Options()
-  let fullCmd = s:CreateFullCmd(s:MakeP4ArgList(p4Options, 0))
-  " Save the name of the current file.
-  let p4OrgFileName = s:GetCurFileName()
-
-  let s:currentCommand = ''
-  " Make sure all the already existing changes are detected. We don't have
-  "     s:currentCommand set here, so the user will get an appropriate prompt.
-  try
-    checktime
-  catch
-    " FIXME: Ignore error for now.
-  endtry
-
-  " If the output has to be shown in a window, position cursor appropriately,
-  " creating a new window if required.
-  let v:errmsg = ""
-  " Ignore outputType in this case.
-  if s:commandMode != s:CM_PIPE && s:commandMode != s:CM_FILTER
-    if s:outputType == 0 || s:outputType == 1
-      " Only when "clear with undo" is selected, we optimize out the call.
-      if s:GotoWindow(s:outputType,
-            \ (!s:refreshWindowsAlways && (a:clearBuffer == 1)) ?
-            \  2 : a:clearBuffer, p4OrgFileName, 0) != 0
-        return s:errCode
-      endif
-    endif
-  endif
-
-  let output = ''
-  if s:errCode == 0
-    if ! a:testMode
-      let s:currentCommand = s:p4Command
-      if s:_('EnableFileChangedShell')
-        call genutils#DefFCShellInstall()
-      endif
-
-      try
-        if s:commandMode ==# s:CM_RUN
-          " Only when "clear with undo" is selected, we optimize out the call.
-          if s:refreshWindowsAlways ||
-                \ ((!s:refreshWindowsAlways && (a:clearBuffer == 1)) &&
-                \  (line('$') == 1 && getline(1) =~ '^\s*$'))
-            " If we are placing the output in a new window, then we should
-            "   avoid system() for performance reasons, imagine doing a
-            "   'print' on a huge file.
-            " These two outputType's correspond to placing the output in a
-            "   window.
-            if s:outputType != 0 && s:outputType != 1
-              let output = s:System(fullCmd)
-            else
-              exec '.call s:Filter(fullCmd, 1)'
-              let output = ''
-            endif
-          endif
-        elseif s:commandMode ==# s:CM_FILTER
-          exec s:filterRange . 'call s:Filter(fullCmd, 1)'
-        elseif s:commandMode ==# s:CM_PIPE
-          exec s:filterRange . 'call s:Filter(fullCmd, 2)'
-        endif
-        " Detect any new changes to the loaded buffers.
-        " CAUTION: This actually results in a reentrant call back to this
-        "   function, but our Push/Pop mechanism for the context should take
-        "   care of it.
-        try
-          checktime
-        catch
-          " FIXME: Ignore error for now.
-        endtry
-      finally
-        if s:_('EnableFileChangedShell')
-          call genutils#DefFCShellUninstall()
-        endif
-        let s:currentCommand = ''
-      endtry
-    elseif a:testMode != 1
-      let output = fullCmd
-    endif
-
-    let v:errmsg = ""
-    " If we have non-null output, then handling it is still pending.
-    if output !~# s:EMPTY_STR
-      let echoGrp = 'NONE' " The default
-      let maxLinesInDlg = s:_('MaxLinesInDialog')
-      if s:outputType == 2 && maxLinesInDlg != -1
-        " Count NLs.
-        let nNLs = 0
-        let nlIdx = 0
-        while 1
-          let nlIdx = stridx(output, "\n", nlIdx+1)
-          if nlIdx != -1
-            let nNLs += 1
-            if nNLs > maxLinesInDlg
-              break
-            endif
-          else
-            break
-          endif
-        endwhile
-        if nNLs > maxLinesInDlg
-          " NOTE: Keep in sync with that at the start of the function.
-          if s:GotoWindow(s:outputType,
-                \ (!s:refreshWindowsAlways && (a:clearBuffer == 1)) ?
-                \  2 : a:clearBuffer, p4OrgFileName, 0) == 0
-            let s:outputType = 0
-          else
-            let s:outputType = 3
-            let echoGrp = 'WarningMsg'
-          endif
-        endif
-      endif
-      " If the output has to be shown in a dialog, bring up a dialog with the
-      "   output, otherwise show it in the current window.
-      if s:outputType == 0 || s:outputType == 1
-        silent! put! =output
-        1
-      elseif s:outputType == 2
-        call s:ConfirmMessage(output, "OK", 1, "Info")
-      elseif s:outputType == 3
-        call s:EchoMessage(output, echoGrp)
-      elseif s:outputType == 4
-        " Do nothing we will just return it.
-      endif
-    endif
-  endif
-  return output
-
-  finally " [+2s]
-    call s:InitWindow(p4Options)
-  endtry
-endfunction " }}}
-
-function! s:NewWindowCreated()
-  if (s:outputType == 0 || s:outputType == 1) && s:errCode == 0 &&
-        \ (s:commandMode ==# s:CM_RUN)
-    return 1
-  else
-    return 0
-  endif
-endfunction
-
-function! s:setBufSetting(opt, set)
-  let optArg = matchstr(b:p4Options, '\%(\S\)\@<!-'.a:opt.'\s\+\S\+')
-  if optArg !~# s:EMPTY_STR
-    let b:p4Options = substitute(b:p4Options, '\V'.optArg, '', '')
-    let b:{a:set} = matchstr(optArg, '-'.a:opt.'\s\+\zs.*')
-  endif
-endfunction
-
-" These p4Options are frozen according to the current s:p4Options.
-function! s:InitWindow(p4Options)
-  if s:NewWindowCreated()
-    let b:p4Command = s:p4Command
-    let b:p4Options = a:p4Options
-    let b:p4CmdOptions = s:p4CmdOptions
-    let b:p4Arguments = s:p4Arguments
-    let b:p4UserArgs = s:userArgs
-    " Separate -p port -c client -u user options and set them individually.
-    " Leave the rest in the b:p4Options variable.
-    call s:setBufSetting('c', 'p4Client')
-    call s:setBufSetting('p', 'p4Port')
-    call s:setBufSetting('u', 'p4User')
-    " Remove any ^M's at the end (for windows), without corrupting the search
-    " register or its history.
-    call genutils#SilentSubstitute("\<CR>$", '%s///e')
-    setlocal nomodifiable
-    setlocal nomodified
-    if s:outputType == 1
-      wincmd p
-    endif
-  endif
-endfunction
-
-" External command execution {{{
-
-function! s:System(fullCmd)
-  return s:ExecCmd(a:fullCmd, 0)
-endfunction
-
-function! s:Filter(fullCmd, mode) range
-  " For command-line, we need to protect '%', '#' and '!' chars, even if they
-  "   are in quotes, to avoid getting expanded by Vim before invoking external
-  "   cmd.
-  let fullCmd = genutils#Escape(a:fullCmd, '%#!')
-  exec a:firstline.",".a:lastline.
-        \ "call s:ExecCmd(fullCmd, a:mode)"
-endfunction
-
-function! s:ExecCmd(fullCmd, mode) range
-  let v:errmsg = ''
-  let output = ''
-  try
-    " Assume the shellredir is set correctly to capture the error messages.
-    if a:mode == 0
-      let output = system(a:fullCmd)
-    elseif a:mode == 1
-      silent! exec a:firstline.",".a:lastline."!".a:fullCmd
-    else
-      silent! exec a:firstline.",".a:lastline."write !".a:fullCmd
-    endif
-
-    call s:CheckShellError(output, s:outputType)
-    return output
-  catch /^Vim\%((\a\+)\)\=:E/ " 48[2-5]
-    let v:errmsg = substitute(v:exception, '^[^:]\+:', '', '')
-    call s:CheckShellError(output, s:outputType)
-  catch /^Vim:Interrupt$/
-    let s:errCode = 1
-    let v:errmsg = 'Interrupted'
-  catch " Ignore.
-  endtry
-endfunction
-
-function! s:EvalExpr(expr, def)
-  let result = a:def
-  if a:expr !~# s:EMPTY_STR
-    exec "let result = " . a:expr
-  endif
-  return result
-endfunction
-
-function! s:GetP4Options()
-  let addOptions = []
-
-  " If there are duplicates, perfore takes the first option, so let
-  "   s:p4Options or b:p4Options come before g:p4DefaultOptions.
-  " LIMITATATION: We choose either s:p4Options or b:p4Options only. But this
-  "   shouldn't be a big issue as this feature is meant for executing more
-  "   commands on the p4 result windows only.
-  if len(s:p4Options) != 0
-    call extend(addOptions, s:p4Options)
-  elseif exists('b:p4Options') && len(b:p4Options) != 0
-    call extend(addOptions, b:p4Options)
-  endif
-
-  " FIXME: avoid split here.
-  call extend(addOptions, split(s:_('DefaultOptions'), ' '))
-
-  let p4Client = s:p4Client
-  let p4User = s:p4User
-  let p4Port = s:p4Port
-  try
-    if s:p4Port !=# 'P4CONFIG'
-      if s:_('CurPresetExpr') !~# s:EMPTY_STR
-        let preset = s:EvalExpr(s:_('CurPresetExpr'), '')
-        if preset ~= s:EMPTY_STR
-          call perforce#PFSwitch(0, preset)
-        endif
-      endif
-
-      if s:_('p4Client') !~# s:EMPTY_STR && index(addOptions, '-c') == -1
-        call add(add(addOptions, '-c'), s:_('p4Client'))
-      endif
-      if s:_('p4User') !~# s:EMPTY_STR && index(addOptions, '-u') == -1
-        call add(add(addOptions, '-u'), s:_('p4User'))
-      endif
-      if s:_('p4Port') !~# s:EMPTY_STR && index(addOptions, '-p') == -1
-        call add(add(addOptions, '-p'), s:_('p4Port'))
-      endif
-      " Don't pass password with '-P' option, it will be too open (ps will show
-      "   it up).
-      let $P4PASSWD = s:p4Password
-    else
-    endif
-  finally
-    let s:p4Client = p4Client
-    let s:p4User = p4User
-    let s:p4Port = p4Port
-  endtry
-  
-  return addOptions
-endfunction
-
-function! s:CreateFullCmd(argList)
-  let fullCmd = genutils#EscapeCommand(s:p4CommandPrefix.s:_('CmdPath'), a:argList,
-        \ s:p4Pipe)
-  let g:p4FullCmd = fullCmd
-  return fullCmd
-endfunction
-
-" Generates a command string as the user typed, using the script variables.
-function! s:MakeP4ArgList(p4Options, useBufLocal)
-  if a:useBufLocal && exists('b:p4Command')
-    let p4Command = b:p4Command
-  else
-    let p4Command = s:p4Command
-  endif
-  if a:useBufLocal && exists('b:p4CmdOptions')
-    let p4CmdOptions = b:p4CmdOptions
-  else
-    let p4CmdOptions = s:p4CmdOptions
-  endif
-  if a:useBufLocal && exists('b:p4Arguments')
-    let p4Arguments = b:p4Arguments
-  else
-    let p4Arguments = s:p4Arguments
-  endif
-  let cmdList = a:p4Options+[p4Command]+p4CmdOptions+p4Arguments
-  " Remove the protection from the characters that we treat specially (Note: #
-  "   and % are treated specially by Vim command-line itself, and the
-  "   back-slashes are removed even before we see them.)
-  call map(cmdList, "genutils#UnEscape(v:val, '&')")
-  return cmdList
-endfunction
-
-" In case of outputType == 4, it assumes the caller wants to see the output as
-" it is, so no error message is given. The caller is expected to check for
-" error code, though.
-function! s:CheckShellError(output, outputType)
-  if (v:shell_error != 0 || v:errmsg != '') && a:outputType != 4
-    let output = "There was an error executing external p4 command.\n"
-    if v:errmsg != ''
-      let output = output . "\n" . "errmsg = " . v:errmsg
-    endif
-    " When commandMode ==# s:CM_RUN, the error message may already be there in
-    "   the current window.
-    if a:output !~# s:EMPTY_STR
-      let output = output . "\n" . a:output
-    elseif a:output =~# s:EMPTY_STR &&
-          \ (s:commandMode ==# s:CM_RUN && line('$') == 1 && col('$') == 1)
-      let output = output . "\n\n" .
-            \ "Check if your 'shellredir' option captures error messages."
-    endif
-    call s:ConfirmMessage(output, "OK", 1, "Error")
-  endif
-  let s:errCode = v:shell_error
-  return v:shell_error
-endfunction
-
-" External command execution }}}
-
-" Push/Pop/Peek context {{{
-function! s:PushP4Context()
-  call add(s:p4Contexts, s:GetP4ContextVars())
-endfunction
-
-function! s:PeekP4Context()
-  return s:PopP4ContextImpl(1, 1)
-endfunction
-
-function! s:PopP4Context(...)
-  " By default carry forward error.
-  return s:PopP4ContextImpl(0, (a:0 ? a:1 : 1))
-endfunction
-
-function! s:NumP4Contexts()
-  return len(s:p4Contexts)
-endfunction
-
-function! s:PopP4ContextImpl(peek, carryFwdErr)
-  let nContexts = len(s:p4Contexts)
-  if nContexts <= 0
-    echoerr "PopP4Context: Contexts stack is empty"
-    return
-  endif
-  let context = s:p4Contexts[-1]
-  if !a:peek
-    call remove(s:p4Contexts, nContexts-1)
-  endif
-
-  call s:SetP4ContextVars(context, a:carryFwdErr)
-  return context
-endfunction
-
-" Serialize p4 context variables.
-function! s:GetP4ContextVars()
-  return [s:p4Options , s:p4Command , s:p4CmdOptions , s:p4Arguments ,
-        \ s:p4Pipe , s:p4WinName , s:commandMode , s:filterRange ,
-        \ s:outputType , s:errCode, s:userArgs]
-endfunction
-
-" De-serialize p4 context variables.
-function! s:SetP4ContextVars(context, ...)
-  let carryFwdErr = 0
-  if a:0 && a:1
-    let carryFwdErr = s:errCode
-  endif
-
-  let [s:p4Options, s:p4Command, s:p4CmdOptions, s:p4Arguments, s:p4Pipe,
-        \ s:p4WinName, s:commandMode, s:filterRange, s:outputType, s:errCode,
-        \ s:userArgs] = a:context
-  let s:errCode = s:errCode + carryFwdErr
-endfunction
-" Push/Pop/Peek context }}}
-
-""" BEGIN: Argument parsing {{{
-function! s:ResetP4ContextVars()
-  " Syntax is:
-  "   PF <p4Options> <p4Command> <p4CmdOptions> <p4Arguments> | <p4Pipe>
-  " Ex: PF -c hari integrate -b branch -s <fromFile> <toFile>
-  let s:p4Options = []
-  let s:p4Command = ""
-  let s:p4CmdOptions = []
-  let s:p4Arguments = []
-  let s:p4Pipe = []
-  let s:p4WinName = ""
-  " commandMode:
-  "   run - Execute p4 using system() or its equivalent.
-  "   filter - Execute p4 as a filter for the current window contents. Use
-  "            commandPrefix to restrict the filter range.
-  "   display - Don't execute p4. The output is already passed in.
-  let s:commandMode = "run"
-  let s:filterRange = ""
-  let s:outputType = 0
-  let s:errCode = 0
-
-  " Special variable to keep track of full user arguments.
-  let s:userArgs = []
-endfunction
-call s:ResetP4ContextVars() " Let them get initialized the first time.
-
-" Parses the arguments into 4 parts, "options to p4", "p4 command",
-" "options to p4 command", "actual arguments". Also generates the window name.
-" outputType (string):
-"   0 - Execute p4 and place the output in a new window.
-"   1 - Same as above, but use preview window.
-"   2 - Execute p4 and show the output in a dialog for confirmation.
-"   3 - Execute p4 and echo the output.
-"   4 - Execute p4 and return the output.
-"   5 - Execute p4 no output expected. Essentially same as 4 when the current
-"       commandMode doesn't produce any output, just for clarification.
-function! s:ParseOptions(fline, lline, outputType, ...) " range
-  call s:ResetP4ContextVars()
-  let s:outputType = a:outputType
-  if a:0 == 0
-    return
-  endif
-
-  let s:filterRange = a:fline . ',' . a:lline
-  let i = 1
-  let prevArg = ""
-  let curArg = ""
-  let s:pendingPipeArg = ''
-  while i <= a:0
-    try " Just for the sake of loop variables. [-2f]
-
-    if s:pendingPipeArg !~# s:EMPTY_STR
-      let curArg = s:pendingPipeArg
-      let s:pendingPipeArg = ''
-    elseif len(s:p4Pipe) == 0
-      let curArg = a:000[i-1]
-      " The user can't specify a null string on the command-line, this is an
-      "   argument originating from the script, so just ignore it (just for
-      "   the sake of convenience, see PChangesDiff for a possibility).
-      if curArg == ''
-        continue
-      endif
-      let pipeIndex = match(curArg, '\\\@<!\%(\\\\\)*\zs|')
-      if pipeIndex != -1
-        let pipePart = strpart(curArg, pipeIndex)
-        let p4Part = strpart(curArg, 0, pipeIndex)
-        if p4Part !~# s:EMPTY_STR
-          let curArg = p4Part
-          let s:pendingPipeArg = pipePart
-        else
-          let curArg = pipePart
-        endif
-      endif
-    else
-      let curArg = a:000[i-1]
-    endif
-
-    if curArg ==# '<pfitem>'
-      let curItem = s:GetCurrentItem()
-      if curItem !~# s:EMPTY_STR
-        let curArg = curItem
-      endif
-    endif
-
-    " As we use custom completion mode, the filename meta-sequences in the
-    "   arguments will not be expanded by Vim automatically, so we need to
-    "   expand them manually here. On the other hand, this provides us control
-    "   on what to expand, so we can avoid expanding perforce file revision
-    "   numbers as buffernames (escaping is no longer required by the user on
-    "   the commandline).
-    let fileRev = ''
-    let fileRevIndex = match(curArg, '#\(-\?\d\+\|none\|head\|have\)$')
-    if fileRevIndex != -1
-      let fileRev = strpart(curArg, fileRevIndex)
-      let curArg = strpart(curArg, 0, fileRevIndex)
-    endif
-    if curArg != '' && (!exists('g:p4EnableUserFileExpand') ||
-          \ g:p4EnableUserFileExpand)
-      let curArg = genutils#UserFileExpand(curArg)
-    endif
-    if fileRev != ''
-      let curArg = curArg.fileRev
-    endif
-
-    if curArg =~# '^|' || len(s:p4Pipe) != 0
-      call add(s:p4Pipe, curArg)
-      continue
-    endif
-
-    if ! s:IsAnOption(curArg) " If not an option.
-      if s:p4Command =~# s:EMPTY_STR &&
-            \ index(s:allCommands, curArg) != -1
-        " If the previous one was an option to p4 that takes in an argument.
-        if prevArg =~# '^-[cCdHLpPux]$' || prevArg =~# '^++o$' " See :PH usage.
-          call add(s:p4Options, curArg)
-          if prevArg ==# '++o' && (curArg == '0' || curArg == 1)
-            let s:outputType = curArg
-          endif
-        else
-          let s:p4Command = curArg
-        endif
-      else " Argument is not a perforce command.
-        if s:p4Command =~# s:EMPTY_STR
-          call add(s:p4Options, curArg)
-        else
-          let optArg = 0
-          " Look for options that have an argument, so we can collect this
-          " into p4CmdOptions instead of p4Arguments.
-          if len(s:p4Arguments) == 0 && s:IsAnOption(prevArg)
-            " We could as well just check for the option here, but combining
-            " this with the command name will increase the accuracy of finding
-            " the starting point for p4Arguments.
-            if (prevArg[0] ==# '-' && has_key(s:p4OptCmdMap, prevArg[1]) &&
-                  \ index(s:p4OptCmdMap[prevArg[1]], s:p4Command) != -1) ||
-             \ (prevArg =~# '^++' && has_key(s:biOptCmdMap, prevArg[2]) &&
-                  \ index(s:biOptCmdMap[prevArg[2]], s:p4Command) != -1)
-              let optArg = 1
-            endif
-          endif
-
-          if optArg
-            call add(s:p4CmdOptions, curArg)
-          else
-            call add(s:p4Arguments, curArg)
-          endif
-        endif
-      endif
-    else
-      if len(s:p4Arguments) == 0
-        if s:p4Command =~# s:EMPTY_STR
-          if curArg =~# '^++[pfdr]$'
-            if curArg ==# '++p'
-              let s:commandMode = s:CM_PIPE
-            elseif curArg ==# '++f'
-              let s:commandMode = s:CM_FILTER
-            elseif curArg ==# '++r'
-              let s:commandMode = s:CM_RUN
-            endif
-            continue
-          endif
-          call add(s:p4Options, curArg)
-        else
-          call add(s:p4CmdOptions, curArg)
-        endif
-      else
-        call add(s:p4Arguments,  curArg)
-      endif
-    endif
-   " The "-x -" option requires it to act like a filter.
-    if s:p4Command =~# s:EMPTY_STR && prevArg ==# '-x' && curArg ==# '-'
-      let s:commandMode = s:CM_FILTER
-    endif
-
-    finally " [+2s]
-      if s:pendingPipeArg =~# s:EMPTY_STR
-        let i = i + 1
-      endif
-      let prevArg = curArg
-    endtry
-  endwhile
-
-  if index(s:p4Options, '-d') == -1
-    let curDir = s:EvalExpr(s:_('CurDirExpr'), '')
-    if curDir !=# ''
-      call add(add(s:p4Options, '-d'), s:EscapeFileName(curDir))
-    endif
-  endif
-  let s:p4WinName = s:MakeWindowName()
-endfunction
-
-function! s:IsAnOption(arg)
-  if a:arg =~# '^-.$' || a:arg =~# '^-d\%([cnsubw]\|\d\+\)*$' ||
-        \ a:arg =~# '^-a[fmsty]$' || a:arg =~# '^-s[ader]$' ||
-        \ a:arg =~# '^-qu$' || a:arg =~# '^+'
-    return 1
-  else
-    return 0
-  endif
-endfunction
-
-function! s:CleanSpaces(str)
-  " Though not complete, it is enough to just say,
-  "   "spaces that are not preceded by \'s".
-  return substitute(substitute(a:str, '^ \+\|\%(\\\@<! \)\+$', '', 'g'),
-        \ '\%(\\\@<! \)\+', ' ', 'g')
-endfunction
-
-function! s:_(set)
-  let set = a:set
-  if set =~# '^\u'
-    let set = 'p4'.set
-  endif
-  if exists('b:'.set)
-    return b:{set}
-  elseif exists('w:'.set)
-    return w:{set}
-  elseif exists('t:'.set)
-    return t:{set}
-  elseif exists('s:'.set)
-    return s:{set}
-  elseif exists('g:'.set)
-    return g:{set}
-  else
-    echoerr 'No setting found for: ' set
-  endif
-endfunction
-
-function! s:indexMatching(list, pat)
-  let i = 0
-  for item in a:list
-    if item =~ a:pat
-      return i
-    endif
-    let i += 1
-  endfor
-  return -1
-endfunction
-""" END: Argument parsing }}}
-
-""" BEGIN: Messages and dialogs {{{
-function! s:SyntaxError(msg)
-  let s:errCode = 1
-  call s:ConfirmMessage("Syntax Error:\n".a:msg, "OK", 1, "Error")
-  return s:errCode
-endfunction
-
-function! s:ShowVimError(errmsg, stack)
-  call s:ConfirmMessage("There was an error executing a Vim command.\n\t" .
-        \ a:errmsg.(a:stack != '' ? "\nCurrent stack: ".a:stack : ''), "OK", 1,
-        \ "Error")
-  echohl ErrorMsg | echomsg a:errmsg | echohl None
-  if a:stack != ''
-    echomsg "Current stack:" a:stack
-  endif
-  redraw " Cls, such that it is only available in the message list.
-  let s:errCode = 1
-  return s:errCode
-endfunction
-
-function! s:EchoMessage(msg, type)
-  let s:lastMsg = a:msg
-  let s:lastMsgGrp = a:type
-  redraw | exec 'echohl' a:type | echo a:msg | echohl NONE
-endfunction
-
-function! s:ConfirmMessage(msg, opts, def, type)
-  let s:lastMsg = a:msg
-  let s:lastMsgGrp = 'None'
-  if a:type ==# 'Error'
-    let s:lastMsgGrp = 'Error'
-  endif
-  return confirm(a:msg, a:opts, a:def, a:type)
-endfunction
-
-function! s:PromptFor(loop, useDialogs, msg, default)
-  let result = ""
-  while result =~# s:EMPTY_STR
-    if a:useDialogs
-      let result = inputdialog(a:msg, a:default)
-    else
-      let result = input(a:msg, a:default)
-    endif
-    if ! a:loop
-      break
-    endif
-  endwhile
-  return result
-endfunction
-
-function! perforce#LastMessage()
-  call s:EchoMessage(s:lastMsg, s:lastMsgGrp)
-endfunction
-""" END: Messages and dialogs }}}
-
-""" BEGIN: Filename handling {{{
-" Escape all the special characters (as the user would if he typed the name
-"   himself).
-function! s:EscapeFileName(fName)
-  " If there is a -d option existing, then it is better to use the full path
-  "   name.
-  if index(s:p4Options, '-d')  != -1
-    let fName = fnamemodify(a:fName, ':p')
-  else
-    let fName = a:fName
-  endif
-  return genutils#Escape(fName, ' &|')
-endfunction
-
-function! s:GetCurFileName()
-  " When the current window itself is a perforce window, then carry over the
-  " existing value.
-  return (exists('b:p4OrgFileName') &&
-        \              b:p4OrgFileName !~# s:EMPTY_STR) ?
-        \             b:p4OrgFileName : expand('%:p')
-endfunction
-
-function! s:GuessFileTypeForCurrentWindow()
-  let fileExt = s:GuessFileType(b:p4OrgFileName)
-  if fileExt =~# s:EMPTY_STR
-    let fileExt = s:GuessFileType(expand("%"))
-  endif
-  return fileExt
-endfunction
-
-function! s:GuessFileType(name)
-  let fileExt = fnamemodify(a:name, ":e")
-  return matchstr(fileExt, '\w\+')
-endfunction
-
-function! s:IsDepotPath(path)
-  if match(a:path, '^//'.s:_('Depot').'/') == 0
-        " \ || match(a:path, '^//'. s:_('p4Client') . '/') == 0
-    return 1
-  else
-    return 0
-  endif
-endfunction
-
-function! s:PathRefersToDepot(path)
-  if s:IsDepotPath(a:path) || s:GetRevisionSpecifier(a:path) !~# s:EMPTY_STR
-    return 1
-  else
-    return 0
-  endif
-endfunction
-
-function! s:GetRevisionSpecifier(fileName)
-  return matchstr(a:fileName,
-        \ '^\(\%(\S\|\\\@<!\%(\\\\\)*\\ \)\+\)[\\]*\zs[#@].*$')
-endfunction
-
-" Removes the //<depot> or //<client> prefix from fileName.
-function! s:StripRemotePath(fileName)
-  "return substitute(a:fileName, '//\%('.s:_('Depot').'\|'.s:_('p4Client').'\)', '', '')
-  return substitute(a:fileName, '//\%('.s:_('Depot').'\)', '', '')
-endfunction
-
-" Client view translation {{{
-" Convert perforce file wildcards ("*", "..." and "%[1-9]") to a Vim string
-"   regex (see |pattern.txt|). Returns patterns that work when "very nomagic"
-"   is set.
-let s:p4Wild = {}
-function! s:TranlsateP4Wild(p4Wild, rhsView)
-  let strRegex = ''
-  if a:rhsView
-    if a:p4Wild[0] ==# '%'
-      let pos = s:p4WildMap[a:p4Wild[1]]
-    else
-      let pos = s:p4WildCount
-    endif
-    let strRegex = '\'.pos
-  else
-    if a:p4Wild ==# '*'
-      let strRegex = '\(\[^/]\*\)'
-    elseif a:p4Wild ==# '...'
-      let strRegex = '\(\.\*\)'
-    elseif a:p4Wild[0] ==# '%'
-      let strRegex = '\(\[^/]\*\)'
-      let s:p4WildMap[a:p4Wild[1]] = s:p4WildCount
-    endif
-  endif
-  let s:p4WildCount = s:p4WildCount + 1
-  return strRegex
-endfunction
-
-" Convert perforce file regex (containing "*", "..." and "%[1-9]") to a Vim
-"   string regex. No error checks for now, for simplicity.
-function! s:TranslateP4FileRegex(p4Regex, rhsView)
-  let s:p4WildCount = 1
-  " Note: We don't expect backslashes in the views, so no special handling.
-  return substitute(a:p4Regex,
-        \ '\(\*\|\%(\.\)\@<!\.\.\.\%(\.\)\@!\|%\([1-9]\)\)',
-        \ '\=s:TranlsateP4Wild(submatch(1), a:rhsView)', 'g')
-endfunction
-
-function! s:CondUpdateViewMappings()
-  if s:_('UseClientViewMap') &&
-        \ (!has_key(s:toDepotMapping, s:_("p4Client")) ||
-        \  (len(s:toDepotMapping[s:_('p4Client')]) < 0))
-    call perforce#UpdateViewMappings()
-  endif
-endfunction
-
-function! perforce#UpdateViewMappings()
-  if s:_('p4Client') =~# s:EMPTY_STR
-    return
-  endif
-  let view = ''
-  call s:PushP4Context()
-  try
-    let view = substitute(perforce#PFIF(1, 4, '-c', s:_('p4Client'), 'client'),
-          \ "\\_.*\nView:\\ze\n", '', 'g')
-    if s:errCode != 0
-      return
-    endif
-  finally
-    call s:PopP4Context(0)
-  endtry
-  let fromDepotMapping = []
-  let toDepotMapping = []
-  for nextMap in reverse(split(view, "\n"))
-    " We need to inverse the order of mapping such that the mappings that come
-    "   later in the view take more priority.
-    " Also, don't care about exclusionary mappings for simplicity (this could
-    "   be considered a feature too).
-    exec substitute(nextMap,
-          \ '\s*-\?//'.s:_('Depot').'/\([^ ]\+\)\s*//'.s:_("p4Client").'/\(.\+\)',
-          \ 'call add(fromDepotMapping, [s:TranslateP4FileRegex('.
-          \ "'".'\1'."'".', 0), s:TranslateP4FileRegex('."'".'\2'."'".
-          \ ', 1)])', '')
-    exec substitute(nextMap,
-          \ '\s*-\?//'.s:_('Depot').'/\([^ ]\+\)\s*//'.s:_("p4Client").'/\(.\+\)',
-          \ 'call add(toDepotMapping, [s:TranslateP4FileRegex('.
-          \ "'".'\2'."'".', 0), s:TranslateP4FileRegex('."'".'\1'."'".
-          \ ', 1)])', '')
-  endfor
-  let s:fromDepotMapping[s:_('p4Client')] = fromDepotMapping
-  let s:toDepotMapping[s:_('p4Client')] = toDepotMapping
-endfunction
-
-function! P4IncludeExpr(path)
-  return s:ConvertToLocalPath(a:path)
-endfunction
-
-function! s:ConvertToLocalPath(path)
-  let fileName = substitute(a:path, '^\s\+\|\s*#[^#]\+$', '', 'g')
-  if s:IsDepotPath(fileName)
-    if s:_('UseClientViewMap')
-      call s:CondUpdateViewMappings()
-      for nextMap in s:fromDepotMapping[s:_('p4Client')]
-        let [lhs, rhs] = nextMap
-        if fileName =~# '\V'.lhs
-          let fileName = substitute(fileName, '\V'.lhs, rhs, '')
-          break
-        endif
-      endfor
-    endif
-    if s:IsDepotPath(fileName)
-      let fileName = s:_('ClientRoot') . s:StripRemotePath(fileName)
-    endif
-  endif
-  return fileName
-endfunction
-
-function! s:ConvertToDepotPath(path)
-  " If already a depot path, just return it without any changes.
-  if s:IsDepotPath(a:path)
-    let fileName = a:path
-  else
-    let fileName = genutils#CleanupFileName(a:path)
-    if s:IsFileUnderDepot(fileName)
-      if s:_('UseClientViewMap')
-        call s:CondUpdateViewMappings()
-        for nextMap in s:toDepotMapping[s:_('p4Client')]
-          let [lhs, rhs] = nextMap
-          if fileName =~# '\V'.lhs
-            let fileName = substitute(fileName, '\V'.lhs, rhs, '')
-            break
-          endif
-        endfor
-      endif
-      if ! s:IsDepotPath(fileName)
-        let fileName = substitute(fileName, '^'.s:_('ClientRoot'),
-              \ '//'.s:_('Depot'), '')
-      endif
-    endif
-  endif
-  return fileName
-endfunction
-" Client view translation }}}
-
-" Requires at least 2 arguments.
-" Returns a List of alternative filenames.
-function! s:PFGetAltFiles(protectedChars, codeline, ...)
-  if a:0 == 0
-    return []
-  endif
-
-  let altCodeLine = a:codeline
-
-  let i = 1
-  let altFiles = []
-  while i <= a:0
-    let fileName = a:000[i-1]
-    let fileName = genutils#CleanupFileName2(fileName, a:protectedChars)
-
-    if altCodeLine ==# 'local' && s:IsDepotPath(fileName)
-      let altFile = s:ConvertToLocalPath(fileName)
-    elseif ! s:IsDepotPath(fileName)
-      let fileName = s:ConvertToDepotPath(fileName)
-
-      if altCodeLine ==# s:_('Depot')
-        " We do nothing, it is already converted to depot path.
-        let altFile = fileName
-      else
-        " FIXME: Assumes that the current branch name has single path component.
-        let altFile = substitute(fileName, '//'.s:_('Depot').'/[^/]\+',
-              \ '//'.s:_('Depot').'/' . altCodeLine, "")
-        let altFile = s:ConvertToLocalPath(altFile)
-      endif
-    endif
-    call add(altFiles, altFile)
-    let i = i + 1
-  endwhile
-  return altFiles
-endfunction
-
-function! s:IsFileUnderDepot(fileName)
-  let fileName = genutils#CleanupFileName(a:fileName)
-  if fileName =~? '^\V'.s:_('ClientRoot')
-    return 1
-  else
-    return 0
-  endif
-endfunction
-
-" This better take the line as argument, but I need the context of current
-"   buffer contents anyway...
-" I don't need to handle other revision specifiers here, as I won't expect to
-"   see them here (perforce converts them to the appropriate revision number). 
-function! s:GetCurrentDepotFile(lineNo)
-  " Local submissions.
-  let fileName = ""
-  let line = getline(a:lineNo)
-  if match(line, '//'.s:_('Depot').'/.*\(#\d\+\)\?') != -1
-        " \ || match(line, '^//'. s:_('p4Client') . '/.*\(#\d\+\)\?') != -1
-    let fileName = matchstr(line, '//[^/]\+/[^#]*\(#\d\+\)\?')
-  elseif match(line, '\.\.\. #\d\+ .*') != -1
-    " Branches, integrations etc.
-    let fileVer = matchstr(line, '\d\+')
-    call genutils#SaveHardPosition('Perforce')
-    exec a:lineNo
-    if search('^//'.s:_('Depot').'/', 'bW') == 0
-      let fileName = ""
-    else
-      let fileName = substitute(s:GetCurrentDepotFile(line(".")), '#\d\+$', '',
-            \ '')
-      let fileName = fileName . "#" . fileVer
-    endif
-    call genutils#RestoreHardPosition('Perforce')
-    call genutils#ResetHardPosition('Perforce')
-  endif
-  return fileName
-endfunction
-""" END: Filename handling }}}
-
-""" BEGIN: Buffer management, etc. {{{
-" Must be followed by a call to s:EndBufSetup()
-function! s:StartBufSetup()
-  " If the command created a new window, then only do setup.
-  if !s:errCode
-    if s:NewWindowCreated()
-      if s:outputType == 1
-        wincmd p
-      endif
-
-      return 1
-    endif
-  endif
-  return 0
-endfunction
-
-function! s:EndBufSetup()
-  if s:NewWindowCreated()
-    if s:outputType == 1
-      wincmd p
-    endif
-  endif
-endfunction
-
-" Goto/Open window for the current command.
-" clearBuffer (number):
-"   0 - clear with undo.
-"   1 - clear with no undo.
-"   2 - don't clear
-function! s:GotoWindow(outputType, clearBuffer, p4OrgFileName, cmdCompleted)
-  let bufNr = genutils#FindBufferForName(s:p4WinName)
-  " NOTE: Precautionary measure to avoid accidentally matching an existing
-  "   buffer and thus overwriting the contents.
-  if bufNr != -1 && getbufvar(bufNr, '&buftype') == ''
-    return s:BufConflictError(a:cmdCompleted)
-  endif
-
-  " If there is a window for this buffer already, then we will just move
-  "   cursor into it.
-  let curBufnr = bufnr('%')
-  let maxBufNr = bufnr('$')
-  let bufWinnr = bufwinnr(bufNr)
-  let nWindows = genutils#NumberOfWindows()
-  let _eventignore = &eventignore
-  try
-    "set eventignore=BufRead,BufReadPre,BufEnter,BufNewFile
-    set eventignore=all
-    if a:outputType == 1 " Preview
-      let alreadyOpen = 0
-      try
-        wincmd P
-        " No exception, meaning preview window is already open.
-        if winnr() == bufWinnr
-          " The buffer is already visible in the preview window. We don't have
-          " to do anything in this case.
-          let alreadyOpen = 1
-        endif
-      catch /^Vim\%((\a\+)\)\=:E441/
-        " Ignore.
-      endtry
-      if !alreadyOpen
-        call s:EditP4WinName(1, nWindows)
-        wincmd P
-      endif
-    elseif bufWinnr != -1
-      call genutils#MoveCursorToWindow(bufWinnr)
-    else
-      exec s:_('SplitCommand')
-      call s:EditP4WinName(0, nWindows)
-    endif
-    if s:errCode == 0
-      " FIXME: If the name didn't originally match with a buffer, we expect
-      "   the s:EditP4WinName() to create a new buffer, but there is a bug in
-      "   Vim, that treats "..." in filenames as ".." resulting in multiple
-      "   names matching the same buffer ( "p4 diff ../.../*.java" and
-      "   "p4 submit ../.../*.java" e.g.). Though I worked around this
-      "   particular bug by avoiding "..." in filenames, this is a good check
-      "   in any case.
-      if bufNr == -1 && bufnr('%') <= maxBufNr
-        return s:BufConflictError(a:cmdCompleted)
-      endif
-      " For navigation.
-      normal! mt
-    endif
-  catch /^Vim\%((\a\+)\)\=:E788/ " Happens during FileChangedRO.
-    return 788 " E788
-  catch
-    return s:ShowVimError("Exception while opening new window.\n" . v:exception,
-          \ v:throwpoint)
-  finally
-    let &eventignore = _eventignore
-  endtry
-  " We now have a new window created, but may be with errors.
-  if s:errCode == 0
-    setlocal noreadonly
-    setlocal modifiable
-    if s:commandMode ==# s:CM_RUN
-      if a:clearBuffer == 1
-        call genutils#OptClearBuffer()
-      elseif a:clearBuffer == 0
-        silent! 0,$delete _
-      endif
-    endif
-
-    let b:p4OrgFileName = a:p4OrgFileName
-    call s:PFSetupBuf(expand('%'))
-  else
-    " Window is created but with an error. We might actually miss the cases
-    "   where a preview operation when the preview window is already open
-    "   fails, and so no additional windows are created, but detecting such
-    "   cases could be error prone, so it is better to leave the buffer in
-    "   this case, rather than making a mistake.
-    if genutils#NumberOfWindows() > nWindows
-      if winbufnr(winnr()) == curBufnr " Error creating buffer itself.
-        close
-      elseif bufname('%') == s:p4WinName
-        " This should even close the window.
-        silent! exec "bwipeout " . bufnr('%')
-      endif
-    endif
-  endif
-  return 0
-endfunction
-
-function! s:BufConflictError(cmdCompleted)
-  return s:ShowVimError('This perforce command resulted in matching an '.
-        \ 'existing buffer. To prevent any demage this could cause '.
-        \ 'the command will be aborted at this point.'.
-        \ (a:cmdCompleted ? ("\nHowever the command completed ".
-        \ (s:errCode ? 'un' : ''). 'successfully.') : ''), '')
-endfunction
-
-function! s:EditP4WinName(preview, nWindows)
-  let fatal = 0
-  let bug = 0
-  let exception = ''
-  let pWindowWasOpen = (genutils#GetPreviewWinnr() != -1)
-  " Some patterns can cause problems.
-  let _wildignore = &wildignore
-  try
-    set wildignore=
-    exec (a:preview?'p':'').'edit' s:p4WinName
-  catch /^Vim\%((\a\+)\)\=:E303/
-    " This is a non-fatal error.
-    let bug = 1 | let exception = v:exception
-    let stack = v:throwpoint
-  catch /^Vim\%((\a\+)\)\=:\%(E77\|E480\)/
-    let bug = 1 | let exception = v:exception | let fatal = 1
-    let stack = v:throwpoint
-  catch
-    let exception = v:exception | let fatal = 1
-    let stack = v:throwpoint
-  finally
-    let &wildignore = _wildignore
-  endtry
-  if fatal
-    call s:ShowVimError(exception, '')
-  endif
-  if bug
-    echohl ERROR
-    echomsg "Please report this error message:"
-    echomsg "\t".exception
-    echomsg
-    echomsg "with the following information:"
-    echomsg "\ts:p4WinName:" s:p4WinName
-    echomsg "\tCurrent stack:" stack
-    echohl NONE
-  endif
-  " For non preview operation, or for preview window operation when the preview
-  "   window is not already visible, we expect the number of windows to go up.
-  if !a:preview || (a:preview && !pWindowWasOpen)
-    if a:nWindows >= genutils#NumberOfWindows()
-      let s:errCode = 1
-    endif
-  endif
-endfunction
-
-function! s:MakeWindowName(...)
-  " Let only the options that are explicitly specified appear in the window
-  "   name.
-  if a:0 > 0
-    let cmdStr = a:1
-  else
-    let cmdStr = 'p4 '.join(s:MakeP4ArgList(s:p4Options, 0), ' ')
-  endif
-  let winName = cmdStr
-  "let winName = genutils#DeEscape(winName)
-  " HACK: Work-around for some weird handling of buffer names that have "..."
-  "   (the perforce wildcard) at the end of the filename or in the middle
-  "   followed by a space. The autocommand is not getting triggered to clean
-  "   the buffer. If we append another character to this, I observed that the
-  "   autocommand gets triggered. Using "/" instead of "'" would probably be
-  "   more appropriate, but this is causing unexpected FileChangedShell
-  "   autocommands on certain filenames (try "PF submit ../..." e.g.). There
-  "   is also another issue with "..." (anywhere) getting treated as ".."
-  "   resulting in two names matching the same buffer(
-  "     "p4 diff ../.../*.java" and "p4 submit ../.../*.java" e.g.). This
-  "   could also change the name of the buffer during the :cd operations
-  "   (though applies only to spec buffers).
-  "let winName = substitute(winName, '\.\.\%( \|$\)\@=', '&/', 'g')
-  "let winName = substitute(winName, '\.\.\%( \|$\)\@=', "&'", 'g')
-  let winName = substitute(winName, '\.\.\.', '..,', 'g')
-  " The intention is to do the substitute only on systems like windoze that
-  "   don't allow all characters in the filename, but I can't generalize it
-  "   enough, so as a workaround I a just assuming any system supporting
-  "   'shellslash' option to be a windoze like system. In addition, cygwin
-  "   vim thinks that it is on Unix and tries to allow all characters, but
-  "   since the underlying OS doesn't support it, we need the same treatment
-  "   here also.
-  if exists('+shellslash') || has('win32unix')
-    " Some characters are not allowed in a filename on windows so substitute
-    " them with something else.
-    let winName = substitute(winName, s:specialChars,
-          \ '\="[" . s:specialCharsMap[submatch(1)] . "]"', 'g')
-    "let winName = substitute(winName, s:specialChars, '\\\1', 'g')
-  endif
-  " Finally escape some characters again.
-  let winName = genutils#Escape(winName, " #%\t")
-  if ! exists('+shellslash') " Assuming UNIX environment.
-    let winName = substitute(winName, '\\\@<!\(\%(\\\\\)*\\[^ ]\)', '\\\1', 'g')
-    let winName = escape(winName, "'~$`{\"")
-  endif
-  return winName
-endfunction
-
-function! s:PFSetupBuf(bufName)
-  call genutils#SetupScratchBuffer()
-  let &l:bufhidden=s:_('BufHidden')
-endfunction
-
-function! s:PFSetupForSpec()
-  setlocal modifiable
-  setlocal buftype=
-  exec 'aug Perforce'.bufnr('%')
-    au!
-    au BufWriteCmd <buffer> nested :W
-  aug END
-endfunction
-
-function! perforce#WipeoutP4Buffers(...)
-  let testMode = 1
-  if a:0 > 0 && a:1 ==# '++y'
-    let testMode = 0
-  endif
-  let i = 1
-  let lastBuf = bufnr('$')
-  let cleanedBufs = ''
-  while i <= lastBuf
-    if bufexists(i) && expand('#'.i) =~# '\<p4 ' && bufwinnr(i) == -1
-      if testMode
-        let cleanedBufs = cleanedBufs . ', ' . expand('#'.i)
-      else
-        silent! exec 'bwipeout' i
-        let cleanedBufs = cleanedBufs + 1
-      endif
-    endif
-    let i = i + 1
-  endwhile
-  if testMode
-    echo "Buffers that will be wipedout (Use ++y to perform action):" .
-          \ cleanedBufs
-  else
-    echo "Total Perforce buffers wipedout (start with 'p4 '): " . cleanedBufs
-  endif
-endfunction
-
-function! perforce#PFRefreshActivePane()
-  if exists("b:p4UserArgs")
-    call genutils#SaveSoftPosition('Perforce')
-
-    try
-      silent! undo
-      call call('perforce#PFrangeIF', b:p4UserArgs)
-    catch
-      call s:ShowVimError(v:exception, v:throwpoint)
-    endtry
-
-    call genutils#RestoreSoftPosition('Perforce')
-    call genutils#ResetSoftPosition('Perforce')
-  endif
-endfunction
-""" END: Buffer management, etc. }}}
-
-""" BEGIN: Testing {{{
-" Ex: PFTestCmdParse -c client -u user integrate -b branch -s source target1 target2
-command! -nargs=* -range=% -complete=file PFTestCmdParse
-      \ :call <SID>TestParseOptions(<f-args>)
-function! s:TestParseOptions(commandName, ...) range
-  call call('s:ParseOptionsIF', [a:firstline, a:lastline, 0, 0, a:commandName]+
-        \ a:000)
-  call s:DebugP4Status()
-endfunction
-
-function! s:DebugP4Status()
-  echo "p4Options :" . join(s:p4Options, ' ') . ":"
-  echo "p4Command :" . s:p4Command . ":"
-  echo "p4CmdOptions :" . join(s:p4CmdOptions, ' ') . ":"
-  echo "p4Arguments :" . join(s:p4Arguments, ' ') . ":"
-  echo "p4Pipe :" . join(s:p4Pipe, ' ') . ":"
-  echo "p4WinName :" . s:p4WinName . ":"
-  echo "outputType :" . s:outputType . ":"
-  echo "errCode :" . s:errCode . ":"
-  echo "commandMode :" . s:commandMode . ":"
-  echo "filterRange :" . s:filterRange . ":"
-  echo "Cmd :" . s:CreateFullCmd(s:MakeP4ArgList([''], 0)) . ":"
-endfunction
-
-"function! s:TestPushPopContexts()
-"  let s:p4Options = ["options1"]
-"  let s:p4Command = "command1"
-"  let s:p4CmdOptions = ["cmdOptions1"]
-"  let s:p4Arguments = ["arguments1"]
-"  let s:p4WinName = "winname1"
-"  call s:PushP4Context()
-"
-"  let s:p4Options = ["options2"]
-"  let s:p4Command = "command2"
-"  let s:p4CmdOptions = ["cmdOptions2"]
-"  let s:p4Arguments = ["arguments2"]
-"  let s:p4WinName = "winname2"
-"  call s:PushP4Context()
-"
-"  call s:ResetP4ContextVars()
-"  echo "After reset: " . s:CreateFullCmd(s:MakeP4ArgList([''], 0))
-"  call s:PopP4Context()
-"  echo "After pop1: " . s:CreateFullCmd(s:MakeP4ArgList([''], 0))
-"  call s:PopP4Context()
-"  echo "After pop2: " . s:CreateFullCmd(s:MakeP4ArgList([''], 0))
-"endfunction
-
-""" END: Testing }}}
-
-""" BEGIN: Experimental API {{{
-
-function! perforce#PFGet(var)
-  return {a:var}
-endfunction
-
-function! perforce#PFSet(var, val)
-  let {a:var} = a:val
-endfunction
-
-function! perforce#PFCall(func, ...)
-  let result = call(a:func, a:000)
-  return result
-endfunction
-
-function! perforce#PFEval(expr)
-  exec "let result = ".a:expr
-  return result
-endfunction
-
-""" END: Experimental API }}}
-
-function! perforce#Initialize(initMenu) " {{{
-
-" User Options {{{
-
-if g:p4ClientRoot != ''
-  let g:p4ClientRoot = genutils#CleanupFileName(g:p4ClientRoot)
-endif
-if type(g:p4DefaultListSize) == 0
-  let g:p4DefaultListSize = string(g:p4DefaultListSize)
-endif
-if g:p4FileLauncher == '' && genutils#OnMS()
-  let g:p4FileLauncher = "start rundll32 SHELL32.DLL,ShellExec_RunDLL"
-endif
-if g:p4DefaultPreset != -1 &&
-      \ g:p4DefaultPreset.'' !~# s:EMPTY_STR
-  call perforce#PFSwitch(1, g:p4DefaultPreset)
-endif
-
-
-" Assume the user already has the preferred rulerformat set (which is anyway
-"   going to be done through the .vimrc file which should have been sourced by
-"   now).
-if g:p4EnableRuler
-  " Take care of rerunning this code, as the reinitialization can happen any
-  "   time.
-  if !exists("s:orgRulerFormat")
-    let s:orgRulerFormat = &rulerformat
-  else
-    let &rulerformat = s:orgRulerFormat
-  endif
-
-  if &rulerformat != ""
-    if match(&rulerformat, '^%\d\+') == 0
-      let orgWidth = substitute(&rulerformat, '^%\(\d\+\)(.*$',
-            \ '\1', '')
-      let orgRuler = substitute(&rulerformat, '^%\d\+(\(.*\)%)$', '\1', '')
-    else
-      let orgWidth = strlen(&rulerformat) " Approximate.
-      let orgRuler = &rulerformat
-    endif
-  else
-    let orgWidth = 20
-    let orgRuler = '%l,%c%V%=%5(%p%%%)'
-  endif
-  let &rulerformat = '%' . (orgWidth + g:p4RulerWidth) .  '(%{' .
-        \ 'perforce#RulerStatus()}%=' . orgRuler . '%)'
-else
-  if exists("s:orgRulerFormat")
-    let &rulerformat = s:orgRulerFormat
-  else
-    set rulerformat&
-  endif
-endif
-
-aug P4Active
-  au!
-  if g:p4EnableActiveStatus
-    au BufRead * call perforce#GetFileStatus(expand('<abuf>') + 0, 0)
-  endif
-aug END
-
-" User Options }}}
-
-if a:initMenu
-runtime! perforce/perforcemenu.vim
-let v:errmsg = ''
-endif
-
-let g:p4PromptToCheckout = ! g:p4PromptToCheckout
-call perforce#ToggleCheckOutPrompt(0)
-
-endfunction " s:Initialize }}}
-
-""" END: Infrastructure }}}
-" Do some initializations.
-if g:p4DefaultPreset != -1 &&
-      \ g:p4DefaultPreset.'' !~# s:EMPTY_STR
-  call perforce#PFSwitch(0, g:p4DefaultPreset)
-endif
-
-aug P4ClientRoot
-  au!
-  if g:p4ClientRoot =~# s:EMPTY_STR || s:p4Client =~# s:EMPTY_STR ||
-        \ s:p4User =~# s:EMPTY_STR
-    if s:_('EnableActiveStatus')
-      " If Vim is still starting up (construct suggested by Eric Arnold).
-      if bufnr("$") == 1 && !bufloaded(1)
-        au VimEnter * call <SID>GetClientInfo() | au! P4ClientRoot
-      else
-        call s:GetClientInfo()
-      endif
-    else
-      let g:p4ClientRoot = fnamemodify(".", ":p")
-    endif
-  endif
-aug END
-
-call perforce#Initialize(0)
-
-" WORKAROUND for :redir broken, when called from completion function... just
-" make sure this is initialized early.
-call genutils#MakeArgumentString()
-
-" Restore cpo.
-let &cpo = s:save_cpo
-unlet s:save_cpo
-
-" vim6:fdm=marker et sw=2