Use a darker shade of blue for listchars characters.
[profile.git] / .vim / plugin / perforce.vim
1 " perforce.vim: Interface with perforce SCM through p4.
2 " Author: Hari Krishna (hari_vim at yahoo dot com)
3 " Last Change: 02-Sep-2006 @ 19:56
4 " Created:     Sometime before 20-Apr-2001
5 " Requires:    Vim-7.0, genutils.vim(2.3)
6 " Version:     4.1.3
7 " Licence: This program is free software; you can redistribute it and/or
8 "          modify it under the terms of the GNU General Public License.
9 "          See http://www.gnu.org/copyleft/gpl.txt 
10 " Acknowledgements:
11 "     See ":help perforce-acknowledgements".
12 " Download From:
13 "     http://www.vim.org//script.php?script_id=240
14 " Usage:
15 "     For detailed help, see ":help perforce" or read doc/perforce.txt. 
16 "
17 " TODO: {{{
18 "   - Launch from describe window is not using the local path.
19 "
20 "   - I need a test suite to stop things from breaking.
21 "   - Should the client returned by g:p4CurPresetExpr be made permanent?
22 "   - curPresetExpr can't support password, so how is the expression going to
23 "     change password?
24 "   - If you actually use python to execute, you may be able to display the
25 "     output incrementally.
26 "   - There seems to be a problem with 'autoread' change leaking. Not sure if
27 "     we explicitly set it somewhere, check if we are using try block.
28 "   - Buffer local autocommads are pretty useful for perforce plugin, send
29 "     feedback.
30 "   - Verify that the buffers/autocommands are not leaking.
31 " TODO }}}
32 "
33 " BEGIN NOTES {{{
34 "   - Now that we increase the level of escaping in the ParseOptions(), we
35 "     need to be careful in reparsing the options (by not using
36 "     scriptOrigin=2). When you CreateArgString() using these escaped
37 "     arguments as if they were typed in by user, they get sent to p4 as they
38 "     are, with incorrect number of back-slashes.
39 "   - When issuing sub-commands, we should remember to use the s:p4Options
40 "     that was passed to the main command (unless the main command already
41 "     generated a new window, in which case the original s:p4Options are
42 "     remembered through b:p4Options and automatically reused for the
43 "     subcommands), or the user will see incorrect behavior or at the worst,
44 "     errors.
45 "   - The p4FullCmd now can have double-quotes surrounding each of the
46 "     individual arguments if the shell is cmd.exe or command.com, so while
47 "     manipulating it directly, we need to use "\?.
48 "   - With the new mode of scriptOrigin=2, the changes done to the s:p4*
49 "     variables will not get reflected in the s:p4WinName, unless there is
50 "     some other relevant processing done in PFIF.
51 "   - With the new mode of scriptOrigin=2, there is no reason to use
52 "     scriptOrigin=1 in most of the calls from handlers.
53 "   - The s:PFSetupBufAutoCommand and its cousines expect the buffer name to
54 "     be plain with no escaping, as they do their own escaping.
55 "   - Wherever we normally expect a depot name, we should use the s:p4Depot
56 "     instead of hardcoded 'depot'. We should also consider the client name
57 "     here.
58 "   - Eventhough DefFileChangedShell event handling is now localized, we still
59 "     need to depend on s:currentCommand to determine the 'autoread' value,
60 "     this is because some other plugin might have already installed a
61 "     FileChangedShell event to DefFileChangedShell, resulting in us receiving
62 "     callbacks anytime, so we need a variable that has a lifespace only for
63 "     the duration of the execution of p4 commands?
64 "   - We need to pass special characters such as <space>, *, ?, [, (, &, |, ', $
65 "     and " to p4 without getting interpreted by the shell. We may have to use
66 "     appropriate quotes around the characters when the shell treats them
67 "     specially. Windows+native is the least bothersome of all as it doesn't
68 "     treat most of the characters specially and the arguments can be
69 "     sorrounded in double-quotes and embedded double-quotes can be easily
70 "     passed in by just doubling them.
71 "   - I am aware of the following unique ways in which external commands are
72 "     executed (not sure if this is same for all of the variations possible: 
73 "     ":[{range}][read|write]!cmd | filter" and "system()"):
74 "     For :! command 
75 "       On Windoze+native:
76 "         cmd /c <command>
77 "       On Windoze+sh:
78 "         sh -c "<command>"
79 "       On Unix+sh:
80 "         sh -c (<command>) 
81 "   - By the time we parse arguments, we protect all the back-slashes, which
82 "     means that we would never see a single-back-slash.
83 "   - Using back-slashes on Cygwin vim is unique and causes E303. This is
84 "     because it thinks it is on UNIX where it is not a special character, but
85 "     underlying Windows obviously treats it special and so it bails out.
86 "   - Using back-slashes on Windows+sh also seems to be different. Somewhere in
87 "     the execution line (most probably the path from CreateProcess() to sh,
88 "     as it doesn't happen in all other types of interfaces) consumes one
89 "     level of extra back-slashes. If it is even number it becomes half, and
90 "     if it is odd then the last unpaired back-slash is left as it is.
91 "   - Some test cases for special character handling:
92 "     - PF fstat a\b
93 "     - PF fstat a\ b
94 "     - PF fstat a&b
95 "     - PF fstat a\&b
96 "     - PF fstat a\#b
97 "     - PF fstat a\|b
98 "   - Careful using s:PFIF(1) from within script, as it doesn't redirect the
99 "     call to the corresponding handler (if any).
100 "   - Careful using ":PF" command from within handlers, especially if you are
101 "     executing the same s:p4Command again as it will result in a recursion.
102 "   - The outputType's -2 and -1 are local to the s:PFrangeIF() interface, the
103 "     actual s:PFImpl() or any other methods shouldn't know anything about it.
104 "     Which is why this outputType should be used only for those commands that
105 "     don't have a handler. Besides this scheme will not even work if a
106 "     handler exists, as the outputType will get permanently set to 4 by the
107 "     time it gets redirected back to s:PFrangeIF() through the handler. (If
108 "     this should ever be a requirement, we will need another state variable
109 "     called s:orgOutputType.)
110 "   - Be careful to pass argument 0 to s:PopP4Context() whenever the logical
111 "     p4 operation ends, to avoid getting the s:errCode carried over. This is
112 "     currently taken care of for all the known recursive or ignorable error
113 "     cases.
114 "   - We need to use s:outputType as much as possible, not a:outputType, which
115 "     is there only to pass it on to s:ParseOptions(). After calling s:PFIF()
116 "     the outputType is established in s:outputType.
117 "   - s:errCode is reset by ParseOptions(). For cases that Push and Pop context
118 "     even before the first call to ParseOptions() (such as the
119 "     s:GetClientInfo() function), we have to check for s:errCode before we
120 "     pop context, or we will just carry on an error code from a previous bad
121 "     run (applies to mostly utility functions).
122 " END NOTES }}}
123
124 if exists('loaded_perforce')
125   finish
126 endif
127 if v:version < 700
128   "echomsg 'Perforce: You need at least Vim 7.0'
129   finish
130 endif
131
132
133 " We need these scripts at the time of initialization itself.
134 if !exists('loaded_genutils')
135   runtime plugin/genutils.vim
136 endif
137 if !exists('loaded_genutils') || loaded_genutils < 203
138   echomsg 'perforce: You need a newer version of genutils.vim plugin'
139   finish
140 endif
141 let loaded_perforce=400
142
143 " Make sure line-continuations won't cause any problem. This will be restored
144 "   at the end
145 let s:save_cpo = &cpo
146 set cpo&vim
147
148 " User option initialization {{{
149 function! s:CondDefSetting(settingName, def)
150   if !exists(a:settingName)
151     let {a:settingName} = a:def
152   endif
153 endfunction
154  
155 call s:CondDefSetting('g:p4CmdPath', 'p4')
156 call s:CondDefSetting('g:p4ClientRoot', '')
157 call s:CondDefSetting('g:p4DefaultListSize', '100')
158 call s:CondDefSetting('g:p4DefaultDiffOptions', '')
159 call s:CondDefSetting('g:p4DefaultPreset', -1)
160 call s:CondDefSetting('g:p4Depot', 'depot')
161 call s:CondDefSetting('g:p4Presets', '')
162 call s:CondDefSetting('g:p4DefaultOptions', '')
163 call s:CondDefSetting('g:p4UseGUIDialogs', 0)
164 call s:CondDefSetting('g:p4PromptToCheckout', 1)
165 call s:CondDefSetting('g:p4MaxLinesInDialog', 1)
166 call s:CondDefSetting('g:p4EnableActiveStatus', 1)
167 call s:CondDefSetting('g:p4ASIgnoreDefPattern',
168       \'\c\%(\<t\%(e\)\?mp\/.*\|^.*\.tmp$\|^.*\.log$\|^.*\.diff\?$\|^.*\.out$\|^.*\.buf$\|^.*\.bak$\)\C')
169 call s:CondDefSetting('g:p4ASIgnoreUsrPattern', '')
170 call s:CondDefSetting('g:p4OptimizeActiveStatus', 1)
171 call s:CondDefSetting('g:p4EnableRuler', 1)
172 call s:CondDefSetting('g:p4RulerWidth', 25)
173 call s:CondDefSetting('g:p4EnableMenu', 0)
174 call s:CondDefSetting('g:p4EnablePopupMenu', 0)
175 call s:CondDefSetting('g:p4UseExpandedMenu', 1)
176 call s:CondDefSetting('g:p4UseExpandedPopupMenu', 0)
177 call s:CondDefSetting('g:p4CheckOutDefault', 3)
178 call s:CondDefSetting('g:p4SortSettings', 1)
179 " Probably safer than reading $TEMP.
180 call s:CondDefSetting('g:p4TempDir', fnamemodify(tempname(), ':h'))
181 call s:CondDefSetting('g:p4SplitCommand', 'split')
182 call s:CondDefSetting('g:p4EnableFileChangedShell', 1)
183 call s:CondDefSetting('g:p4UseVimDiff2', 0)
184 call s:CondDefSetting('g:p4BufHidden', 'wipe')
185 call s:CondDefSetting('g:p4Autoread', 1)
186 call s:CondDefSetting('g:p4FileLauncher', '')
187 call s:CondDefSetting('g:p4CurPresetExpr', '')
188 call s:CondDefSetting('g:p4CurDirExpr', '')
189 call s:CondDefSetting('g:p4UseClientViewMap', 1)
190 delfunction s:CondDefSetting
191 " }}}
192
193
194 " Call this any time to reconfigure the environment. This re-performs the same
195 "   initializations that the script does during the vim startup, without
196 "   loosing what is already configured.
197 command! -nargs=0 PFInitialize :call perforce#Initialize(0)
198
199 """ The following are some shortcut commands. Some of them are enhanced such
200 """   as the help window or the filelog window.
201
202 " Command definitions {{{
203
204 command! -nargs=* -complete=custom,perforce#PFComplete PP
205       \ :call perforce#PFIF(0, 0, 'print', <f-args>)
206 command! -nargs=* -complete=custom,perforce#PFComplete PPrint
207       \ :call perforce#PFIF(0, 0, 'print', <f-args>)
208 command! -nargs=* -complete=custom,perforce#PFComplete PDiff
209       \ :call perforce#PFIF(0, 0, 'diff', <f-args>)
210 command! -nargs=* -complete=custom,perforce#PFComplete PD
211       \ :PDiff <args>
212 command! -nargs=* -complete=custom,perforce#PFComplete PEdit
213       \ :call perforce#PFIF(0, 2, 'edit', <f-args>)
214 command! -nargs=* -complete=custom,perforce#PFComplete PE
215       \ :PEdit <args>
216 command! -nargs=* -complete=custom,perforce#PFComplete PReopen
217       \ :call perforce#PFIF(0, 2, 'reopen', <f-args>)
218 command! -nargs=* -complete=custom,perforce#PFComplete PAdd
219       \ :call perforce#PFIF(0, 2, 'add', <f-args>)
220 command! -nargs=* -complete=custom,perforce#PFComplete PA
221       \ :PAdd <args>
222 command! -nargs=* -complete=custom,perforce#PFComplete PDelete
223       \ :call perforce#PFIF(0, 2, 'delete', <f-args>)
224 command! -nargs=* -complete=custom,perforce#PFComplete PLock
225       \ :call perforce#PFIF(0, 2, 'lock', <f-args>)
226 command! -nargs=* -complete=custom,perforce#PFComplete PUnlock
227       \ :call perforce#PFIF(0, 2, 'unlock', <f-args>)
228 command! -nargs=* -complete=custom,perforce#PFComplete PRevert
229       \ :call perforce#PFIF(0, 2, 'revert', <f-args>)
230 command! -nargs=* -complete=custom,perforce#PFComplete PR
231       \ :PRevert <args>
232 command! -nargs=* -complete=custom,perforce#PFComplete PSync
233       \ :call perforce#PFIF(0, 2, 'sync', <f-args>)
234 command! -nargs=* -complete=custom,perforce#PFComplete PG
235       \ :PSync <args>
236 command! -nargs=* -complete=custom,perforce#PFComplete PGet
237       \ :call perforce#PFIF(0, 2, 'get', <f-args>)
238 command! -nargs=* -complete=custom,perforce#PFComplete POpened
239       \ :call perforce#PFIF(0, 0, 'opened', <f-args>)
240 command! -nargs=* -complete=custom,perforce#PFComplete PO
241       \ :POpened <args>
242 command! -nargs=* -complete=custom,perforce#PFComplete PHave
243       \ :call perforce#PFIF(0, 0, 'have', <f-args>)
244 command! -nargs=* -complete=custom,perforce#PFComplete PWhere
245       \ :call perforce#PFIF(0, 0, 'where', <f-args>)
246 command! -nargs=* -complete=custom,perforce#PFComplete PDescribe
247       \ :call perforce#PFIF(0, 0, 'describe', <f-args>)
248 command! -nargs=* -complete=custom,perforce#PFComplete PFiles
249       \ :call perforce#PFIF(0, 0, 'files', <f-args>)
250 command! -nargs=* -complete=custom,perforce#PFComplete PLabelsync
251       \ :call perforce#PFIF(0, 0, 'labelsync', <f-args>)
252 command! -nargs=* -complete=custom,perforce#PFComplete PFilelog
253       \ :call perforce#PFIF(0, 0, 'filelog', <f-args>)
254 command! -nargs=* -complete=custom,perforce#PFComplete PIntegrate
255       \ :call perforce#PFIF(0, 0, 'integrate', <f-args>)
256 command! -nargs=* -complete=custom,perforce#PFComplete PDiff2
257       \ :call perforce#PFIF(0, 0, 'diff2', <f-args>)
258 command! -nargs=* -complete=custom,perforce#PFComplete PD2
259       \ :PDiff2 <args>
260 command! -nargs=* -complete=custom,perforce#PFComplete PFstat
261       \ :call perforce#PFIF(0, 0, 'fstat', <f-args>)
262 command! -nargs=* -complete=custom,perforce#PFComplete PHelp
263       \ :call perforce#PFIF(0, 0, 'help', <f-args>)
264 command! -nargs=* -complete=custom,perforce#PFComplete PH
265       \ :PHelp <args>
266 command! -nargs=* PPasswd
267       \ :call perforce#PFIF(0, 2, 'passwd', <f-args>)
268
269
270 """ Some list view commands.
271 command! -nargs=* -complete=custom,perforce#PFComplete PChanges
272       \ :call perforce#PFIF(0, 0, 'changes', <f-args>)
273 command! -nargs=* -complete=custom,perforce#PFComplete PBranches
274       \ :call perforce#PFIF(0, 0, 'branches', <f-args>)
275 command! -nargs=* -complete=custom,perforce#PFComplete PLabels
276       \ :call perforce#PFIF(0, 0, 'labels', <f-args>)
277 command! -nargs=* -complete=custom,perforce#PFComplete PClients
278       \ :call perforce#PFIF(0, 0, 'clients', <f-args>)
279 command! -nargs=* -complete=custom,perforce#PFComplete PUsers
280       \ :call perforce#PFIF(0, 0, 'users', <f-args>)
281 command! -nargs=* -complete=custom,perforce#PFComplete PJobs
282       \ :call perforce#PFIF(0, 0, 'jobs', <f-args>)
283 command! -nargs=* -complete=custom,perforce#PFComplete PDepots
284       \ :call perforce#PFIF(0, 0, 'depots', <f-args>)
285 command! -nargs=* -complete=custom,perforce#PFComplete PGroups
286       \ :call perforce#PFIF(0, 0, 'groups', <f-args>)
287
288
289 """ The following support some p4 operations that normally involve some
290 """   interaction with the user (they are more than just shortcuts).
291
292 command! -nargs=* -complete=custom,perforce#PFComplete PChange
293       \ :call perforce#PFIF(0, 0, 'change', <f-args>)
294 command! -nargs=* -complete=custom,perforce#PFComplete PBranch
295       \ :call perforce#PFIF(0, 0, 'branch', <f-args>)
296 command! -nargs=* -complete=custom,perforce#PFComplete PLabel
297       \ :call perforce#PFIF(0, 0, 'label', <f-args>)
298 command! -nargs=* -complete=custom,perforce#PFComplete PClient
299       \ :call perforce#PFIF(0, 0, 'client', <f-args>)
300 command! -nargs=* -complete=custom,perforce#PFComplete PUser
301       \ :call perforce#PFIF(0, 0, 'user', <f-args>)
302 command! -nargs=* -complete=custom,perforce#PFComplete PJob
303       \ :call perforce#PFIF(0, 0, 'job', <f-args>)
304 command! -nargs=* -complete=custom,perforce#PFComplete PJobspec
305       \ :call perforce#PFIF(0, 0, 'jobspec', <f-args>)
306 command! -nargs=* -complete=custom,perforce#PFComplete PDepot
307       \ :call perforce#PFIF(0, 0, 'depot', <f-args>)
308 command! -nargs=* -complete=custom,perforce#PFComplete PGroup
309       \ :call perforce#PFIF(0, 0, 'group', <f-args>)
310 command! -nargs=* -complete=custom,perforce#PFComplete PSubmit
311       \ :call perforce#PFIF(0, 0, 'submit', <f-args>)
312 command! -nargs=* -complete=custom,perforce#PFComplete PResolve
313       \ :call perforce#PFIF(0, 0, 'resolve', <f-args>)
314
315 " Some built-in commands.
316 command! -nargs=* -complete=custom,perforce#PFComplete PVDiff
317       \ :call perforce#PFIF(0, 0, 'vdiff', <f-args>)
318 command! -nargs=* -complete=custom,perforce#PFComplete PVDiff2
319       \ :call perforce#PFIF(0, 0, 'vdiff2', <f-args>)
320 command! -nargs=* -complete=custom,perforce#PFComplete PExec
321       \ :call perforce#PFIF(0, 5, 'exec', <f-args>)
322
323 """ Other utility commands.
324
325 command! -nargs=* -complete=file E :call perforce#PFOpenAltFile(0, <f-args>)
326 command! -nargs=* -complete=file ES :call perforce#PFOpenAltFile(2, <f-args>)
327 command! -nargs=* -complete=custom,perforce#PFSwitchComplete PFSwitch
328       \ :call perforce#PFSwitch(1, <f-args>)
329 command! -nargs=* PFSwitchPortClientUser :call perforce#SwitchPortClientUser()
330 command! -nargs=0 PFRefreshActivePane :call perforce#PFRefreshActivePane()
331 command! -nargs=0 PFRefreshFileStatus :call perforce#GetFileStatus(0, 1)
332 command! -nargs=0 PFToggleCkOut :call perforce#ToggleCheckOutPrompt(1)
333 command! -nargs=* -complete=custom,perforce#PFSettingsComplete PFS
334       \ :PFSettings <args>
335 command! -nargs=* -complete=custom,perforce#PFSettingsComplete PFSettings
336       \ :call perforce#PFSettings(<f-args>)
337 command! -nargs=0 PFDiffOff :call perforce#PFDiffOff(
338       \ exists('w:p4VDiffWindow') ? w:p4VDiffWindow : -1)
339 command! -nargs=? PFWipeoutBufs :call perforce#WipeoutP4Buffers(<f-args>)
340 "command! -nargs=* -complete=file -range=% PF
341 command! -nargs=* -complete=custom,perforce#PFComplete -range=% PF
342       \ :call perforce#PFrangeIF(<line1>, <line2>, 0, 0, <f-args>)
343 command! -nargs=* -complete=file PFRaw :call perforce#PFRaw(<f-args>)
344 command! -nargs=* -complete=custom,perforce#PFComplete -range=% PW
345       \ :call perforce#PW(<line1>, <line2>, 0, <f-args>)
346 command! -nargs=0 PFLastMessage :call perforce#LastMessage()
347 command! -nargs=0 PFBugReport :runtime perforce/perforcebugrep.vim
348 command! -nargs=0 PFUpdateViews :call perforce#UpdateViewMappings()
349
350 " New normal mode mappings.
351 if (! exists('no_plugin_maps') || ! no_plugin_maps) &&
352       \ (! exists('no_perforce_maps') || ! no_execmap_maps)
353   nnoremap <silent> <Leader>prap :PFRefreshActivePane<cr>
354   nnoremap <silent> <Leader>prfs :PFRefreshFileStatus<cr>
355
356   " Some generic mappings.
357   if maparg('<C-X><C-P>', 'c') == ""
358     cnoremap <C-X><C-P> <C-R>=perforce#PFOpenAltFile(1)<CR>
359   endif
360 endif
361
362 " Command definitions }}}
363
364 if exists('g:p4EnableActiveStatus') && g:p4EnableActiveStatus
365   aug P4Init
366     au!
367     au BufRead * exec 'au! P4Init' | exec 'PFInitialize' | PFRefreshFileStatus
368   aug END
369 endif
370
371 " Restore cpo.
372 let &cpo = s:save_cpo
373 unlet s:save_cpo
374
375 " vim6:fdm=marker et sw=2