Set TERMINFO before calling tput.
[profile.git] / .vim / plugin / genutils.vim
1 " genutils: Useful buffer, file and window related functions.
2 " Author: Hari Krishna Dara (hari_vim at yahoo dot com)
3 " Last Change: 08-Jun-2007 @ 17:36
4 " Requires: Vim-7.0
5 " Version: 2.4.0
6 " Licence: This program is free software; you can redistribute it and/or
7 "          modify it under the terms of the GNU General Public License.
8 "          See http://www.gnu.org/copyleft/gpl.txt 
9 " Acknowledgements:
10 "     - The genutils#GetNextWinnrInStack() function is based on the WinStackMv()
11 "       function posted by Charles E. Campbell, Jr. on vim mailing list on Jul
12 "       14, 2004.
13 "     - The genutils#CommonPath() function is based on the thread,
14 "       "computing relative path" on Jul 29, 2002.
15 "     - The genutils#ShowLinesWithSyntax() function is based on a posting by
16 "       Gary Holloway (gary at castandcrew dot com) on Jan, 16 2002.
17 "     - Robert Webb for the original "quick sort" algorithm from eval.txt.
18 "     - Peit Delport's (pjd at 303 dot za dot net) for his original BISort()
19 "       algorithm on which the genutils#BinInsertSort() and
20 "       genutils#BinInsertSort2() functions are based on.
21 " Download From:
22 "     http://www.vim.org/script.php?script_id=197
23 " See Also: autoload/genutils.vim
24 "
25 " Description:
26 "   - Read the "Documentation With Function Prototypes" section below.
27 "   - Misc. window/buffer related functions, genutils#NumberOfWindows(),
28 "     genutils#FindBufferForName(), genutils#MoveCursorToWindow(),
29 "     genutils#MoveCurLineToWinLine(), genutils#SetupScratchBuffer(),
30 "     genutils#MapAppendCascaded()
31 "   - Save/Restore all the window height/width settings to be restored later.
32 "   - Save/Restore position in the buffer to be restored later. Works like the
33 "     built-in marks feature, but has more to it.
34 "   - genutils#AddNotifyWindowClose() to get notifications *after* a window
35 "     with the specified buffer has been closed or the buffer is unloaded. The
36 "     built-in autocommands can only notify you *before* the window is closed.
37 "     You can use this with the Save/Restore window settings feature to
38 "     restore the dimensions of existing windows, after your window is closed
39 "     (just like how Vim does while closing help windows). See selectbuf.vim
40 "     or perforce.vim for examples.
41 "     There is also a test function called RunNotifyWindowCloseTest() that
42 "     demos the usage (you need to uncomment RunNotifyWindowCloseTest and
43 "     NotifyWindowCloseF functions).
44 "   - genutils#ShowLinesWithSyntax() function to echo lines with syntax coloring.
45 "   - genutils#ShiftWordInSpace(), genutils#CenterWordInSpace() and
46 "     genutils#AlignWordWithWordInPreviousLine() utility functions to move
47 "     words in the space without changing the width of the field. A
48 "     genutils#GetSpacer() function to return a spacer of specified width.
49 "   - Binary search function genutils#BinSearchList() for sorted lists, to
50 "     find the index after which a given item can be inserted to keep the list
51 "     in sorted order. You can also use these functions to just search for
52 "     boundaries.
53 "     There are also a couple of functions genutils#BinSearchForInsert() and
54 "     genutils#BinSearchForInsert2() to find the location for a newline to be
55 "     inserted in an already sorted buffer or arbitrary data.
56 "     There are also a few comparison functions that can be used with sort() or
57 "     the above functions.
58 "   - ExecMap function has now been separated as a plugin called execmap.vim.
59 "   - New genutils#CommonPath() function to extract the common part of two
60 "     paths, and genutils#RelPathFromFile() and genutils#RelPathFromDir() to
61 "     find relative paths (useful HTML href's). A side effect is the
62 "     genutils#CommonString() function to find the common string of two
63 "     strings.
64 "   - genutils#UnEscape() and genutils#DeEscape() functions to reverse and
65 "     genutils#Escape() to compliment what built-in escape() does. There is
66 "     also an genutils#EscapeCommand() function to escape external command
67 "     strings.
68 "   - Utility functions genutils#CurLineHasSign() and genutils#ClearAllSigns()
69 "     to fill in the gaps left by Vim.
70 "   - genutils#GetVimCmdOutput() function to capture the output of Vim built-in
71 "     commands, in a safe manner.
72 "   - genutils#OptClearBuffer() function to clear the contents and undo
73 "     history of the current buffer in an optimal manner. Ideal to be used
74 "     when plugins need to refresh their windows and don't care about
75 "     preserving the current contents (which is the most usual case).
76 "   - genutils#GetPreviewWinnr() function.
77 "   - Functions to have persistent data, genutils#PutPersistentVar() and
78 "     genutils#GetPersistentVar(). You don't need to worry about saving in
79 "     files and reading them back. To disable, set g:genutilsNoPersist in your
80 "     vimrc.
81 "   - A function to emulate the default Vim behavior for |timestamp| changes.
82 "     It also provides hooks to get call backs before and after handling the
83 "     default FileChangedShell autocommand (effectively splitting it into a
84 "     Pre and a Post event). Suggested usage is to use
85 "     genutils#AddToFCShellPre() and either install a default event handling
86 "     mechanism for all files by calling genutils#DefFCShellInstall() or
87 "     create your own autocommand on a matching pattern to call
88 "     genutils#DefFileChangedShell() function. Most useful for the source
89 "     control plugins to conditionally reload a file, while being able to
90 "     default to the Vim's standard behavior of asking the user. See
91 "     perforce.vim for usage examples.
92 "   - Utility function genutils#ExtractFuncListing() that is useful to to
93 "     create snippets (see breakpts.vim, ntservices.vim and ntprocesses.vim
94 "     for interesting ideas on how to use this function).
95 "
96 "   Function Prototypes:
97 "       The types in prototypes of the functions mimic Java.
98 "       This is just a full list for a quick reference, see
99 "         "Documentation With Function Prototypes" for more information on the
100 "         functions.
101 "
102 "   void    genutils#DebugShowArgs(...)
103 "   String  genutils#ExtractFuncListing(String funcName, String hLines, String tLines)
104 "   int     genutils#NumberOfWindows()
105 "   int     genutils#FindBufferForName(String fileName)
106 "   String  genutils#GetBufNameForAu(String bufName)
107 "   void    genutils#MoveCursorToWindow(int winno)
108 "   void    genutils#MoveCurLineToWinLine(int winLine)
109 "   void    genutils#CloseWindow(int winnr, boolean force)
110 "   void    genutils#MarkActiveWindow()
111 "   void    genutils#RestoreActiveWindow()
112 "   void    genutils#IsOnlyVerticalWindow()
113 "   void    genutils#IsOnlyHorizontalWindow()
114 "   int     genutils#GetNextWinnrInStack(char dir)
115 "   int     genutils#GetLastWinnrInStack(char dir)
116 "   void    genutils#MoveCursorToNextInWinStack(char dir)
117 "   void    genutils#MoveCursorToLastInWinStack(char dir)
118 "   void    genutils#OpenWinNoEa(String openWinCmd)
119 "   void    genutils#CloseWinNoEa(int winnr, boolean force)
120 "   void    genutils#SetupScratchBuffer()
121 "   void    genutils#CleanDiffOptions()
122 "   boolean genutils#ArrayVarExists(String varName, int index)
123 "   void    genutils#MapAppendCascaded(String lhs, String rhs, String mapMode)
124 "   void    genutils#SaveWindowSettings()
125 "   void    genutils#RestoreWindowSettings()
126 "   void    genutils#ResetWindowSettings()
127 "   void    genutils#SaveWindowSettings2(String id, boolean overwrite)
128 "   void    genutils#RestoreWindowSettings2(String id)
129 "   void    genutils#ResetWindowSettings2(String id)
130 "   void    genutils#SaveVisualSelection(String id)
131 "   void    genutils#RestoreVisualSelection(String id)
132 "   void    genutils#SaveSoftPosition(String id)
133 "   void    genutils#RestoreSoftPosition(String id)
134 "   void    genutils#ResetSoftPosition(String id)
135 "   void    genutils#SaveHardPosition(String id)
136 "   void    genutils#RestoreHardPosition(String id)
137 "   void    genutils#ResetHardPosition(String id)
138 "   int     genutils#GetLinePosition(String id)
139 "   int     genutils#GetColPosition(String id)
140 "   boolean genutils#IsPositionSet(String id)
141 "   String  genutils#CleanupFileName(String fileName)
142 "   String  genutils#CleanupFileName2(String fileName, String win32ProtectedChars)
143 "   boolean genutils#OnMS()
144 "   boolean genutils#PathIsAbsolute(String path)
145 "   boolean genutils#PathIsFileNameOnly(String path)
146 "   void    genutils#AddNotifyWindowClose(String windowTitle, String functionName)
147 "   void    genutils#RemoveNotifyWindowClose(String windowTitle)
148 "   void    genutils#CheckWindowClose()
149 "   void    genutils#ShowLinesWithSyntax() range
150 "   void    genutils#ShiftWordInSpace(int direction)
151 "   void    genutils#CenterWordInSpace()
152 "   int     genutils#BinSearchList(List list, int start, int end, Object item,
153 "                              [Funcref|String] cmp, int direction)
154 "   int     genutils#BinSearchForInsert(int start, int end, String line,
155 "                              String cmp, int direction)
156 "   int     genutils#BinSearchForInsert2(int start, int end, line, String cmp,
157 "                               int direction, String accessor, String context)
158 "   String  genutils#CommonPath(String path1, String path2)
159 "   String  genutils#CommonString(String str1, String str2)
160 "   String  genutils#RelPathFromFile(String srcFile, String tgtFile)
161 "   String  genutils#RelPathFromDir(String srcDir, String tgtFile)
162 "   String  genutils#Roman2Decimal(String str)
163 "   String  genutils#Escape(String str, String chars)
164 "   String  genutils#UnEscape(String str, String chars)
165 "   String  genutils#DeEscape(String str)
166 "   String  genutils#CrUnProtectedCharsPattern(String chars)
167 "   String  genutils#EscapeCommand(String cmd, List/String args, List/String pipe)
168 "   int     genutils#GetShellEnvType()
169 "   String  genutils#ExpandStr(String str)
170 "   String  genutils#QuoteStr(String str)
171 "   boolean genutils#CurLineHasSign()
172 "   void    genutils#ClearAllSigns()
173 "   String  genutils#UserFileComplete(String ArgLead, String CmdLine,
174 "                  String CursorPos, String smartSlash, String searchPath)
175 "   String  genutils#UserFileExpand(String fileArgs)
176 "   String  genutils#GetVimCmdOutput(String cmd)
177 "   void    genutils#OptClearBuffer()
178 "   int     genutils#GetPreviewWinnr()
179 "   void    genutils#PutPersistentVar(String pluginName, String persistentVar,
180 "                  String value)
181 "   void    genutils#GetPersistentVar(String pluginName, String persistentVar,
182 "                  String default)
183 "   void    genutils#AddToFCShellPre(String funcName)
184 "   void    genutils#RemoveFromFCShellPre(String funcName)
185 "   void    genutils#DefFCShellInstall()
186 "   void    genutils#DefFCShellUninstall()
187 "   boolean genutils#DefFileChangedShell()
188 "   void    genutils#SilentSubstitute(String pat, String cmd)
189 "   void    genutils#SilentDelete(String pat)
190 "   void    genutils#SilentDelete(String range, String pat)
191 "   String  genutils#GetSpacer(int width)
192 "   String  genutils#PromptForElement(List array,
193 "                  [String defaultValue | int defaultIndex], String msg,
194 "                  String skip, boolean useDialog, int nCols)
195 "   int     genutils#GetSelectedIndex()
196 "
197 " Documentation With Function Prototypes:
198 " -----------------------
199 " Useful function to debug passing arguments to functions. See exactly what
200 "   you would receive on the other side.
201 " Ex: :exec 'call genutils#DebugShowArgs('. genutils#CreateArgString("a 'b' c", ' ') . ')' 
202 "
203 " void    genutils#DebugShowArgs(...)
204 " -----------------------
205 " This function returns the body of the specified function ( the name should be
206 "   complete, including any scriptid prefix in case of a script local
207 "   function), without the function header and tail. You can also pass in the
208 "   number of additional lines to be removed from the head and or tail of the
209 "   function.
210 "
211 " String  genutils#ExtractFuncListing(String funcName, String hLines, String tLines)
212 " -----------------------
213 " -----------------------
214 " Return the number of windows open currently.
215 "
216 " int     genutils#NumberOfWindows()
217 " -----------------------
218 " Returns the buffer number of the given fileName if it is already loaded.
219 " The fileName argument is treated literally, unlike the bufnr() which treats
220 "   the argument as a filename-pattern. The function first escape all the
221 "   |filename-pattern| characters before passing it to bufnr(). It should work
222 "   in most of the cases, except when backslashes are used in non-windows
223 "   platforms, when the result could be unpredictable.
224 "
225 " Note: The function removes protections for "#%" characters because, these
226 "   are special characters on Vim commandline, and so are usually escaped
227 "   themselves, but bufnr() wouldn't like them.
228 "
229 " int     genutils#FindBufferForName(String fileName)
230 " -----------------------
231 " Returns the transformed buffer name that is suitable to be used in
232 "   autocommands.
233 "
234 " String  genutils#GetBufNameForAu(String bufName)
235 " -----------------------
236 " Given the window number, moves the cursor to that window.
237 "
238 " void    genutils#MoveCursorToWindow(int winno)
239 " -----------------------
240 " Moves the current line such that it is going to be the nth line in the window
241 "   without changing the column position.
242 "
243 " void    genutils#MoveCurLineToWinLine(int winLine)
244 " -----------------------
245 " Closes the given window and returns to the original window. It the simplest,
246 " this is equivalent to:
247 "
248 "   let curWin = winnr()
249 "   exec winnr 'wincmd w'
250 "   close
251 "   exec curWin 'wincmd w'
252 "
253 " But the function keeps track of the change in window numbers and restores
254 " the current window correctly. It also restores the previous window (the
255 " window that the cursor would jump to when executing "wincmd p" command).
256 " This is something that all plugins should do while moving around in the
257 " windows, behind the scenes.
258 "
259 " Pass 1 to force closing the window (:close!).
260 "
261 " void    genutils#CloseWindow(int winnr, boolean force)
262 " -----------------------
263 " Remembers the number of the current window as well as the previous-window
264 " (the one the cursor would jump to when executing "wincmd p" command). To
265 " determine the window number of the previous-window, the function temporarily
266 " jumps to the previous-window, so if your script intends to avoid generating
267 " unnecessary window events, consider disabling window events before calling
268 " this function (see :h 'eventignore').
269 "
270 " void    genutils#MarkActiveWindow()
271 " -----------------------
272 " Restore the cursor to the window that was previously marked as "active", as
273 " well as its previous-window (the one the cursor would jump to when executing
274 " "wincmd p" command). To restore the window number of the previous-window,
275 " the function temporarily jumps to the previous-window, so if your script
276 " intends to avoid generating unnecessary window events, consider disabling
277 " window events before calling this function (see :h 'eventignore').
278 "
279 " void    genutils#RestoreActiveWindow()
280 " -----------------------
281 " Returns 1 if the current window is the only window vertically.
282 "
283 " void    genutils#IsOnlyVerticalWindow()
284 " -----------------------
285 " Returns 1 if the current window is the only window horizontally.
286 "
287 " void    genutils#IsOnlyHorizontalWindow()
288 " -----------------------
289 " Returns the window number of the next window while remaining in the same
290 "   horizontal or vertical window stack (or 0 when there are no more). Pass
291 "   hjkl characters to indicate direction.
292 "   Usage:
293 "     let wn = genutils#GetNextWinnrInStack('h') left  window number in stack.
294 "     let wn = genutils#GetNextWinnrInStack('l') right window number in stack.
295 "     let wn = genutils#GetNextWinnrInStack('j') upper window number in stack.
296 "     let wn = genutils#GetNextWinnrInStack('k') lower window number in stack.
297 "
298 " int     genutils#GetNextWinnrInStack(char dir)
299 " -----------------------
300 " Returns the window number of the last window while remaining in the same
301 "   horizontal or vertical window stack (or 0 when there are no more, or it is
302 "   already the last window). Pass hjkl characters to indicate direction.
303 "   Usage:
304 "     let wn = genutils#GetLastWinnrInStack('h') leftmost  window number in stack.
305 "     let wn = genutils#GetLastWinnrInStack('l') rightmost window number in stack.
306 "     let wn = genutils#GetLastWinnrInStack('j') top       window number in stack.
307 "     let wn = genutils#GetLastWinnrInStack('k') bottom    window number in stack.
308 "
309 " int     genutils#GetLastWinnrInStack(char dir)
310 " -----------------------
311 " Move cursor to the next window in stack. See genutils#GetNextWinnrInStack()
312 "   for more information.
313 "
314 " void    genutils#MoveCursorToNextInWinStack(char dir)
315 " -----------------------
316 " Move cursor to the last window in stack. See genutils#GetLastWinnrInStack()
317 "   for more information.
318 "
319 " void    genutils#MoveCursorToLastInWinStack(char dir)
320 " -----------------------
321 " This function, which stands for "execute the given command that creates a
322 "   window, while disabling the 'equalalways' setting", is a means for plugins
323 "   to create new windows without disturbing the existing window dimensions as
324 "   much as possible. This function would not be required if 'equalalways' is
325 "   not set by the user. Even if set, the below code, though intuitive,
326 "   wouldn't work:
327 "       let _equalalways = &equalalways
328 "       set noequalalways
329 "       " open window now.
330 "       let &equalalways = _equalalways
331 "
332 " The problem is that while restoring the value of equalalways, if the user
333 "   originally had it set, Vim would immediately try to equalize all the
334 "   window dimensions, which is exactly what we tried to avoid by setting
335 "   'noequalalways'. The function works around the problem by temporarily
336 "   setting 'winfixheight' in all the existing windows and restoring them
337 "   after done.
338 "   Usage:
339 "     call genutils#OpenWinNoEa('sb ' pluginBuf)
340 "
341 " Note: The function doesn't catch any exceptions that are generated by the
342 "   operations, so it is advisable to catch them by the caller itself.
343 "
344 " void    genutils#OpenWinNoEa(String openWinCmd)
345 " -----------------------
346 " This is for the same purpose as described for genutils#OpenWinNoEa()
347 "   function, except that it is used to close a given window. This is just a
348 "   convenience function.
349 "
350 " void    genutils#CloseWinNoEa(int winnr, boolean force)
351 " -----------------------
352 " Turn on some buffer settings that make it suitable to be a scratch buffer.
353 "
354 " void    genutils#SetupScratchBuffer()
355 " -----------------------
356 " Turns off those options that are set by diff to the current window.
357 "   Also removes the 'hor' option from scrollopt (which is a global option).
358 " Better alternative would be to close the window and reopen the buffer in a
359 "   new window. 
360 "
361 " void    genutils#CleanDiffOptions()
362 " -----------------------
363 " This function is an alternative to exists() function, for those odd array
364 "   index names for which the built-in function fails. The var should be
365 "   accessible to this functions, so it shouldn't be a local or script local
366 "   variable.
367 "     if genutils#ArrayVarExists("array", id)
368 "       let val = array{id}
369 "     endif
370 "
371 " boolean genutils#ArrayVarExists(String varName, int index)
372 " -----------------------
373 " If lhs is already mapped, this function makes sure rhs is appended to it
374 "   instead of overwriting it. If you are rhs has any script local functions,
375 "   make sure you use the <SNR>\d\+_ prefix instead of the <SID> prefix (or the
376 "   <SID> will be replaced by the SNR number of genutils script, instead of
377 "   yours).
378 " mapMode is used to prefix to "oremap" and used as the map command. E.g., if
379 "   mapMode is 'n', then the function call results in the execution of noremap
380 "   command.
381 "
382 " void    genutils#MapAppendCascaded(String lhs, String rhs, String mapMode)
383 " -----------------------
384 " -----------------------
385 " Saves the heights and widths of the currently open windows for restoring
386 "   later.
387 "
388 " void    genutils#SaveWindowSettings()
389 " -----------------------
390 " Restores the heights of the windows from the information that is saved by
391 "  genutils#SaveWindowSettings(). Works only when the number of windows
392 "  haven't changed since the genutils#SaveWindowSettings is called.
393 "
394 " void    genutils#RestoreWindowSettings()
395 " -----------------------
396 " Reset the previously saved window settings using genutils#SaveWindowSettings.
397 "
398 " void    genutils#ResetWindowSettings()
399 " -----------------------
400 " Same as genutils#SaveWindowSettings, but uses the passed in id to create a
401 "   private copy for the calling script. Pass in a unique id to avoid
402 "   conflicting with other callers. If overwrite is zero and if the settings
403 "   are already stored for the passed in id, it will overwrite previously
404 "   saved settings.
405 "
406 " void    genutils#SaveWindowSettings2(String id, boolean overwrite)
407 " -----------------------
408 " Same as genutils#RestoreWindowSettings, but uses the passed in id to get the
409 "   settings. The settings must have been previously saved using this
410 "   id. Call genutils#ResetWindowSettings2() to explicitly reset the saved
411 "   settings.
412 "
413 " void    genutils#RestoreWindowSettings2(String id)
414 " -----------------------
415 " Reset the previously saved window settings using genutils#SaveWindowSettings2.
416 "   Releases the variables.
417 "
418 " void    genutils#ResetWindowSettings2(String id)
419 " -----------------------
420 " -----------------------
421 " Save the current/last visual selection such that it can be later restored
422 "   using genutils#RestoreVisualSelection(). Pass a unique id such that it will
423 "   not interfere with the other callers to this function. Saved selections
424 "   are not associated with the window so you can later restore the selection
425 "   in any window, provided there are enough lines/columns.
426 "
427 " void    genutils#SaveVisualSelection(String id)
428 " -----------------------
429 " Restore the visual selection that was previuosly saved using
430 "   genutils#SaveVisualSelection().
431 "
432 " void    genutils#RestoreVisualSelection(String id)
433 " -----------------------
434 " -----------------------
435 " This method tries to save the hard position along with the line context This
436 "   is like the vim builtin marker. Pass in a unique id to avoid
437 "   conflicting with other callers.
438 "
439 " void    genutils#SaveSoftPosition(String id)
440 " -----------------------
441 " Restore the cursor position using the information saved by the previous call
442 "   to genutils#SaveSoftPosition. This first calls
443 "   genutils#RestoreHardPosition() and then searches for the original line
444 "   first in the forward direction and then in the backward and positions the
445 "   cursor on the line if found. If the original line is not found it still
446 "   behaves like a call to genutils#RestoreHardPosition. This is similar to
447 "   the functionality of the built-in marker, as Vim is capable of maintaining
448 "   the marker even when the line is moved up or down. However, if there are
449 "   identical lines in the buffer and the original line has moved, this
450 "   function might get confused.
451 "
452 " void    genutils#RestoreSoftPosition(String id)
453 " -----------------------
454 " Reset the previously cursor position using genutils#SaveSoftPosition.
455 "   Releases the variables.
456 "
457 " void    genutils#ResetSoftPosition(String id)
458 " -----------------------
459 " Useful when you want to go to the exact (line, col), but marking will not
460 "   work, or if you simply don't want to disturb the marks. Pass in a unique
461 "   id.
462 "
463 " void    genutils#SaveHardPosition(String id)
464 " -----------------------
465 " Restore the cursor position using the information saved by the previous call
466 "   to genutils#SaveHardPosition. 
467 "
468 " void    genutils#RestoreHardPosition(String id)
469 " -----------------------
470 " Reset the previously cursor position using genutils#SaveHardPosition.
471 "   Releases the variables.
472 "
473 " void    genutils#ResetHardPosition(String id)
474 " -----------------------
475 " Return the line number of the previously saved position for the id.
476 "   This is like calling line() builtin function for a mark.
477 "
478 " int     genutils#GetLinePosition(String id)
479 " -----------------------
480 " Return the column number of the previously saved position for the id.
481 "   This is like calling col() builtin function for a mark.
482 "
483 " int     genutils#GetColPosition(String id)
484 " -----------------------
485 " A convenience function to check if a position has been saved (and not reset)
486 "   using the id given.
487 "
488 " boolean genutils#IsPositionSet(String id)
489 " -----------------------
490 " -----------------------
491 " Cleanup file name such that two *cleaned up* file names are easy to be
492 "   compared. This probably works only on windows and unix platforms. Also
493 "   recognizes UNC paths. Always returns paths with forward slashes only,
494 "   irrespective of what your 'shellslash' setting is. The return path will
495 "   always be a valid path for use in Vim, provided the original path itself
496 "   was valid for the platform (a valid cygwin path after the cleanup will
497 "   still be valid in a cygwin vim). The CleanupFileName2() variant is meant
498 "   for win32, to avoid translating some backslash protections to be treated
499 "   as regular path separators. Pass the characters that are protected, and
500 "   the backslashes infront of them are preserved.
501 "
502 " String  genutils#CleanupFileName(String fileName)
503 " String  genutils#CleanupFileName2(String fileName, String win32ProtectedChars)
504 " -----------------------
505 " Returns true if the current OS is any of the Microsoft OSes. Most useful to
506 "   know if the path separator is "\".
507 "
508 " boolean genutils#OnMS()
509 " -----------------------
510 " Returns true if the given path could be an absolute path. Probably works
511 "   only on Unix and Windows platforms.
512 "
513 " boolean genutils#PathIsAbsolute(String path)
514 " -----------------------
515 " Returns true if the given path doesn't have any directory components.
516 "   Probably works only on Unix and Windows platforms.
517 "
518 " boolean genutils#PathIsFileNameOnly(String path)
519 " -----------------------
520 " -----------------------
521 " Add a notification to know when a buffer with the given name (referred to as
522 "   windowTitle) is no longer visible in any window. This by functionality is
523 "   like a BufWinLeavePost event. The function functionName is called back
524 "   with the title (buffer name) as an argument. The notification gets removed
525 "   after excuting it, so for future notifications, you need to reregister
526 "   your function. You can only have one notification for any buffer. The
527 "   function should be accessible from the script's local context.
528 "
529 " void    genutils#AddNotifyWindowClose(String windowTitle, String functionName)
530 " -----------------------
531 " Remove the notification previously added using genutils#AddNotifyWindowClose
532 "   function.
533 "
534 " void    genutils#RemoveNotifyWindowClose(String windowTitle)
535 " -----------------------
536 " Normally the plugin checks for closed windows for every WinEnter event, but
537 "   you can force a check at anytime by calling this function.
538 "
539 " void    genutils#CheckWindowClose()
540 " -----------------------
541 " -----------------------
542 " Displays the given line(s) from the current file in the command area (i.e.,
543 "   echo), using that line's syntax highlighting (i.e., WYSIWYG).  If no line
544 "   number is given, display the current line.
545 " Originally,
546 "   From: Gary Holloway "gary at castandcrew dot com"
547 "   Date: Wed, 16 Jan 2002 14:31:56 -0800
548 "
549 " void    genutils#ShowLinesWithSyntax() range
550 " -----------------------
551 " This function shifts the current word in the space without changing the
552 "   column position of the next word. Doesn't work for tabs.
553 "
554 " void    genutils#ShiftWordInSpace(int direction)
555 " -----------------------
556 " This function centers the current word in the space without changing the
557 "   column position of the next word. Doesn't work for tabs.
558
559 " void    genutils#CenterWordInSpace()
560 " -----------------------
561 " -----------------------
562 " Find common path component of two filenames.
563 "   Based on the thread, "computing relative path".
564 "   Date: Mon, 29 Jul 2002 21:30:56 +0200 (CEST)
565 " The last two arguments are optional and default to 0 (false), but you can
566 "   pass a value of 1 (true) to indicate that the path represents a directory.
567 " Ex:
568 "   genutils#CommonPath('/a/b/c/d.e', '/a/b/f/g/h.i') => '/a/b/'
569 "   genutils#CommonPath('/a/b/c/d.e', '/a/b/') => '/a/b'
570 "   genutils#CommonPath('/a/b/c/d.e', '/a/b/', 0, 1) => '/a/b/'
571 "
572 " String  genutils#CommonPath(String path1, String path2 [, boolean path1IsDir, boolean path2IsDir])
573 " -----------------------
574 " Find common string component of two strings.
575 "   Based on the tread, "computing relative path".
576 "   Date: Mon, 29 Jul 2002 21:30:56 +0200 (CEST)
577 " Ex:
578 "   genutils#CommonString('abcde', 'abfghi') => 'ab'
579 "
580 " String  genutils#CommonString(String str1, String str2)
581 " -----------------------
582 " Find the relative path of tgtFile from the directory of srcFile.
583 "   Based on the tread, "computing relative path".
584 "   Date: Mon, 29 Jul 2002 21:30:56 +0200 (CEST)
585 " Ex:
586 "   genutils#RelPathFromFile('/a/b/c/d.html', '/a/b/e/f.html') => '../f/g.html'
587 "
588 " String  genutils#RelPathFromFile(String srcFile, String tgtFile)
589 " -----------------------
590 " Find the relative path of tgtFile from the srcDir.
591 "   Based on the tread, "computing relative path".
592 "   Date: Mon, 29 Jul 2002 21:30:56 +0200 (CEST)
593 " Ex:
594 "   genutils#RelPathFromDir('/a/b/c/d', '/a/b/e/f/g.html') => '../../e/f/g.html'
595 "
596 " String  genutils#RelPathFromDir(String srcDir, String tgtFile)
597 " -----------------------
598 " -----------------------
599 " Convert Roman numerals to decimal. Doesn't detect format errors.
600 " Originally,
601 "   From: "Preben Peppe Guldberg" <c928400@student.dtu.dk>
602 "   Date: Fri, 10 May 2002 14:28:19 +0200
603 "
604 " String  genutils#Roman2Decimal(String str)
605 " -----------------------
606 " -----------------------
607 " Works like the built-in escape(), except that it escapes the specified
608 "   characters only if they are not already escaped, so something like
609 "   genutils#Escape('a\bc\\bd', 'b') would give 'a\bc\\\bd'. The chars value
610 "   directly goes into the [] collection, so it can be anything that is
611 "   accepted in [].
612 "
613 " String  genutils#Escape(String str, String chars)
614 " -----------------------
615 " Works like the reverse of the builtin escape() function, but un-escapes the
616 "   specified characters only if they are already escaped (essentially the
617 "   opposite of genutils#Escape()). The chars value directly goes into the []
618 "   collection, so it can be anything that is acceptable to [].
619 "
620 " String  genutils#UnEscape(String str, String chars)
621 " -----------------------
622 " Works like the reverse of the built-in escape() function. De-escapes all the
623 "   escaped characters. Essentially removes one level of escaping from the
624 "   string, so something like: 'a\b\\\\c\\d' would become 'ab\\c\d'.
625 "
626 " String  genutils#DeEscape(String str)
627 " ----------------------- 
628 " This function creates a pattern that avoids the given protected characters'
629 "   from getting treated as separators, when used with split(). The argument
630 "   goes directly into the [] atom, so make sure you pass in a valid string.
631 "   When optional argument capture is true, the characters are placed in a
632 "   capturing group.
633 " Ex:
634 "   let paths = split(&path, genutils#CrUnProtectedCharsPattern(','))
635 "
636 " String  genutils#CrUnProtectedCharsPattern(String chars, [boolean capture = false])
637 " ----------------------- 
638 " genutils#Escape the passed in shell command with quotes and backslashes such
639 "   a way that the arguments reach the command literally (avoids shell
640 "   interpretations). See the function header for the kind of escapings that
641 "   are done. The first argument is the actual command name, the second
642 "   argument is the arguments to the command and third argument is any pipe
643 "   command that should be appended to the command. The reason the function
644 "   requires them to be passed separately is that the escaping is minimized
645 "   for the first and third arguments. It is preferable to pass args as a Vim7
646 "   List, but it can be passed as a single string with spaces separating the
647 "   arguments (spaces in side each argument then needs to be protected)
648 "   Usage:
649 "     let fullCmd = genutils#EscapeCommand('ls', ['-u', expand('%:h')], ['|', 'grep', 'xxx'])
650 "   Note:
651 "     If the escaped command is used on Vim command-line (such as with ":w !",
652 "     ":r !" and ":!"), you need to further protect '%', '#' and '!' chars,
653 "     even if they are in quotes, to avoid getting expanded by Vim before
654 "     invoking external cmd. However this is not required for using it with
655 "     system() function. The easiest way to escape them is by using the
656 "     genutils#Escape() function as in "Escape(fullCmd, '%#!')".
657 " String  genutils#EscapeCommand(String cmd, List/String args, List/String pipe)
658 " -----------------------
659 " Returns the global ST_* constants (g:ST_WIN_CMD, g:ST_WIN_SH, g:ST_UNIX)
660 " based on the values of shell related settings and the OS on which Vim is
661 " running.
662 "
663 " int     genutils#GetShellEnvType()
664 " -----------------------
665 "
666 " Expands the string for the special characters. The return value should
667 "   essentially be what you would see if it was a string constant with
668 "   double-quotes.
669 " Ex:
670 "   genutils#ExpandStr('a\tA') => 'a     A'
671 " String  genutils#ExpandStr(String str)
672 " -----------------------
673 " Quotes the passed in string such that it can be used as a string expression
674 " in :execute. It sorrounds the passed in string with single-quotes while
675 " escaping any existing single-quotes in the string.
676 "
677 " String  genutils#QuoteStr(String str)
678 " -----------------------
679 " -----------------------
680 " Returns true if the current line has a sign placed.
681 "
682 " boolean genutils#CurLineHasSign()
683 " -----------------------
684 " Clears all signs in the current buffer.
685 "
686 " void    genutils#ClearAllSigns()
687 " -----------------------
688 " -----------------------
689 " This function is suitable to be used by custom command completion functions
690 "   for expanding filenames conditionally. The function could based on the
691 "   context, decide whether to do a file completion or a different custom
692 "   completion. See breakpts.vim and perforce.vim for examples.
693 " If you pass non-zero value to smartSlash, the function decides to use
694 "   backslash or forwardslash as the path separator based on the user settings
695 "   and the ArgLead, but if you always want to use only forwardslash as the
696 "   path separator, then pass 0. If you pass in a comma separated list of
697 "   directories as searchPath, then the file expansion is limited to the files
698 "   under these directories. This means, you can implement your own commands
699 "   that don't expect the user to type in the full path name to the file
700 "   (e.g., if the user types in the command while in the explorer window, you
701 "   could assume that the path is relative to the directory being viewed). Most
702 "   useful with a single directory, but also useful in combination with vim
703 "   'runtimepath' in loading scripts etc. (see Runtime command in
704 "   breakpts.vim).
705 "
706 " String  genutils#UserFileComplete(String ArgLead, String CmdLine, String
707 "                          CursorPos, String smartSlash, String searchPath)
708 " -----------------------
709 " This is a convenience function to expand filename meta-sequences in the
710 "   given arguments just as Vim would have if given to a user-defined command
711 "   as arguments with completion mode set to "file". Useful
712 "   if you set the completion mode of your command to anything
713 "   other than the "file", and later conditionally expand arguments (for
714 "   characters such as % and # and other sequences such as #10 and <cword>)
715 "   after deciding which arguments represent filenames/patterns.
716 "
717 " String  genutils#UserFileExpand(String fileArgs)
718 " -----------------------
719 " This returns the output of the vim command as a string, without corrupting
720 "   any registers. Returns empty string on errors. Check for v:errmsg after
721 "   calling this function for any error messages.
722 "
723 " String  genutils#GetVimCmdOutput(String cmd)
724 " -----------------------
725 " Clear the contents of the current buffer in an optimum manner. For plugins
726 " that keep redrawing the contents of its buffer, executing "1,$d" or its
727 " equivalents result in overloading Vim's undo mechanism. Using this function
728 " avoids that problem.
729 "
730 " void    genutils#OptClearBuffer()
731 " -----------------------
732 " Returns the window number of the preview window if open or -1 if not.
733 " int     genutils#GetPreviewWinnr()
734 " -----------------------
735 " -----------------------
736 " These functions provide a persistent storage mechanism.
737 "
738 "     Example: Put the following in a file called t.vim in your plugin
739 "     directory and watch the magic. You can set new value using SetVar() and
740 "     see that it returns the same value across session when GetVar() is
741 "     called.
742 "     >>>>t.vim<<<<
743 "       au VimEnter * call LoadSettings()
744 "       au VimLeavePre * call SaveSettings()
745 "       
746 "       function! LoadSettings()
747 "         let s:tVar = genutils#GetPersistentVar("T", "tVar", "defVal")
748 "       endfunction
749 "       
750 "       function! SaveSettings()
751 "         call genutils#PutPersistentVar("T", "tVar", s:tVar)
752 "       endfunction
753 "       
754 "       function! SetVar(val)
755 "         let s:tVar = a:val
756 "       endfunction
757 "       
758 "       function! GetVar()
759 "         return s:tVar
760 "       endfunction
761 "     <<<<t.vim>>>>
762 "
763 " The pluginName and persistentVar have to be unique and are case insensitive.
764 "   Ideally called from your VimLeavePre autocommand handler of your plugin.
765 "   This simply creates a global variable which will be persisted by Vim
766 "   through viminfo. The variable can be read back in the next session by the
767 "   plugin using genutils#GetPersistentVar() function, ideally from your
768 "   VimEnter autocommand handler. The pluginName is to provide a name space
769 "   for different plugins, and avoid conflicts in using the same persistentVar
770 "   name.
771 " This feature uses the '!' option of viminfo, to avoid storing all the
772 "   temporary and other plugin specific global variables getting saved.
773 "
774 " void    genutils#PutPersistentVar(String pluginName, String persistentVar,
775 "                          String value)
776 " -----------------------
777 " Ideally called from VimEnter, this simply reads the value of the global
778 "   variable for the persistentVar that is saved in the viminfo in a previous
779 "   session using genutils#PutPersistentVar() and returns it (and default if
780 "   the variable is not found). It removes the variable from global space
781 "   before returning the value, so can be called only once. It also means that
782 "   genutils#PutPersistentVar should be called again in the next VimLeavePre
783 "   if the variable continues to be persisted.
784 "
785 " void    genutils#GetPersistentVar(String pluginName, String persistentVar,
786 "                          String default)
787 " -----------------------
788 " -----------------------
789 " These functions channel the FileChangedShell autocommand and extend it to
790 " create an additional fictitious FileChangedShellPre and FileChangedShellPost
791 " events.
792 "
793 " Add the given noarg function to the list of functions that need to be
794 "   notified before processing the FileChangedShell event. The function when
795 "   called can expand "<abuf>" or "<afile>" to get the details of the buffer
796 "   for which this autocommand got executed. It should return 0 to mean
797 "   noautoread and 1 to mean autoread the current buffer. It can also return
798 "   -1 to make its return value ignored and use default autoread mechanism
799 "   (which could still be overridden by the return value of other functions).
800 "   The return value of all the functions is ORed to determine the effective
801 "   autoread value.
802 "
803 " void    genutils#AddToFCShellPre(String funcName)
804 " -----------------------
805 " Remove the given function previously added by calling
806 "   genutils#AddToFCShellPre.
807 "
808 " void    genutils#RemoveFromFCShellPre(String funcName)
809 " -----------------------
810 " Same as genutils#AddToFCShellPre except that the function is called after
811 "   the event is processed, so this is like a fictitious FileChangedShellPost
812 "   event.
813
814 " void    genutils#DefFCShellInstall()
815 " -----------------------
816 " Uninstall the default autocommand handler that was previously installed
817 "   using genutils#DefFCShellInstall. Calling this function may not actually
818 "   result in removing the handler, in case there are other callers still
819 "   dependent on it (which is kept track of by the number of times
820 "   genutils#DefFCShellInstall has been called).
821 "
822 " void    genutils#DefFCShellUninstall()
823 " -----------------------
824 " This function emulates the Vim's default behavior when a |timestamp| change
825 "   is detected. Register your functions by calling genutils#AddToFCShellPre
826 "   and have this function called during the FileChangedShell event (or just
827 "   install the default handler by calling genutils#DefFCShellInstall).  From
828 "   your callbacks, return 1 to mean autoread, 0 to mean noautoread and -1 to
829 "   mean system default (or ignore).  The return value of this method is 1 if
830 "   the file was reloaded and 0 otherwise. The return value of all the
831 "   functions is ORed to determine the effective autoread value. See my
832 "   perforce plugin for usage example.
833 "
834 " boolean genutils#DefFileChangedShell()
835 " -----------------------
836 " Execute a substitute command silently and without corrupting the search
837 "   register. It also preserves the cursor position.
838 " Ex:
839 "   To insert a tab infrontof all lines:
840 "         call genutils#SilentSubstitute('^', '%s//\t/e')
841 "   To remote all carriage returns at the line ending:
842 "         call genutils#SilentSubstitute("\<CR>$", '%s///e')
843 "
844 " void    genutils#SilentSubstitute(String pat, String cmd)
845 " -----------------------
846 " Delete all lines matching the given pattern silently and without corrupting
847 "   the search register. The range argument if passed should be a valid prefix
848 "   for the :global command. It also preserves the cursor position.
849 " Ex:
850 "   To delete all lines that are empty:
851 "         call genutils#SilentDelete('^\s*$')
852 "   To delete all lines that are empty only in the range 10 to 100:
853 "         call genutils#SilentDelete('10,100', '^\s*$')
854 "
855 " void    genutils#SilentDelete(String pat)
856 " void    genutils#SilentDelete(String range, String pat)
857 " -----------------------
858 " Can return a spacer from 0 to 80 characters width.
859 "
860 " String  genutils#GetSpacer(int width)
861 " -----------------------
862 " Function to prompt user for an element out of the passed in array. The
863 "   user will be prompted with a list of choices to make. The elements will be
864 "   formatted in to the given number of columns. Each element will be given a
865 "   number that the user can enter to indicate the selection. This is very
866 "   much like the inputlist() method, but better for a large number of options
867 "   formatted into multiple columns (instead of one per row). However, if the
868 "   formatted options run for multiple pages, no special handling is done.
869 " Params:
870 "   default - The default value for the selection. Default can be the
871 "               element-index or the element itself. If number (type() returns
872 "               0), it is treated as an index.
873 "   msg - The message that should appear in the prompt (passed to input()).
874 "   skip - The element that needs to be skipped from selection (pass a
875 "            non-existent element to disable this, such as an empty value '').
876 "   useDialog - if true, uses dialogs for prompts, instead of the command-line(
877 "                 inputdialog() instead of input()). But personally, I don't
878 "                 like this because the power user then can't use the
879 "                 expression register.
880 "   nCols - Number of columns to use for formatting the options. Using "1"
881 "           will make the output look very like that of inputlist()
882 " Returns:
883 "   the selected element or empty string, "" if nothing is selected. Call
884 "   genutils#GetSelectedIndex() for the index entered by the user.
885 "
886 " Ex:
887 "   echo genutils#PromptForElement(map(range(0,25),
888 "         \ "nr2char(char2nr('a')+v:val)") , 'd', 'Enter: ', 'x', 1, 5)
889 " String  genutils#PromptForElement(List array,
890 "          [String defaultValue | int defaultIndex], String msg,
891 "          String skip, boolean useDialog, int nCols)
892 "
893 " Returns the index of the element selected by the user in the previous
894 "   genutils#PromptForElement call. Returns -1 when the user didn't select
895 "   any element (aborted the selection). This function is useful if there are
896 "   empty or duplicate elements in the selection.
897 " int     genutils#GetSelectedIndex()
898 " -----------------------
899 " Deprecations:
900 "   - CleanDiffOptions() is deprecated as Vim now has the :diffoff command.
901 "   - MakeArgumentString, MakeArgumentList and CreateArgString are deprecated.
902 "     Vim7 now includes call() function to receive and pass argument lists
903 "     around.
904 "   - The g:makeArgumentString and g:makeArgumentList are obsolete and are
905 "     deprecated, please use MakeArgumentString() and MakeArgumentList()
906 "     instead.
907 "   - FindWindowForBuffer() function is now deprecated, as the corresponding
908 "     Vim bugs are fixed. Use the below expr instead:
909 "       bufwinnr(genutils#FindBufferForName(fileName))
910 "   - QSort(), QSort2(), BinInsertSort() and BinInsertSort2() functions are
911 "     now deprecated in favor of sort() function.
912 "       
913 "
914 " Sample Usages Or Tips:
915 "   - Add the following commands to create simple sort commands.
916 "       command! -nargs=0 -range=% SortByLength <line1>,<line2>call
917 "           \ genutils#QSort('genutils#CmpByLineLengthNname', 1)
918 "       command! -nargs=0 -range=% RSortByLength <line1>,<line2>call
919 "           \ genutils#QSort('genutils#CmpByLineLengthNname', -1)
920 "       command! -nargs=0 -range=% SortJavaImports <line1>,<line2>call
921 "           \ genutils#QSort('genutils#CmpJavaImports', 1)
922 "
923 "   - You might like the following mappings to adjust spacing:
924 "       nnoremap <silent> <C-Space> :call genutils#ShiftWordInSpace(1)<CR>
925 "       nnoremap <silent> <C-BS> :call genutils#ShiftWordInSpace(-1)<CR>
926 "       nnoremap <silent> \cw :call genutils#CenterWordInSpace()<CR>
927 "       nnoremap <silent> \va :call
928 "           \ genutils#AlignWordWithWordInPreviousLine()<CR>
929 "
930 "   - The :find command is very useful to search for a file in path, but it
931 "     doesn't support file completion. Add the following command in your vimrc
932 "     to add this functionality:
933 "       command! -nargs=1 -bang -complete=custom,<SID>PathComplete FindInPath
934 "             \ :find<bang> <args>
935 "       function! s:PathComplete(ArgLead, CmdLine, CursorPos)
936 "         return genutils#UserFileComplete(a:ArgLead, a:CmdLine, a:CursorPos, 1,
937 "             \ &path)
938 "       endfunction
939 "
940 "   - If you are running commands that generate multiple pages of output, you
941 "     might find it useful to redirect the output to a new buffer. Put the
942 "     following command in your vimrc:
943 "       command! -nargs=* -complete=command Redir
944 "             \ :new | put! =genutils#GetVimCmdOutput('<args>') |
945 "             \ setl bufhidden=wipe | setl nomodified
946 "
947 " Changes in 2.4:
948 "   - Fixed some corner cases in RelPathFromDir()/RelPathFromFile().
949 "   - Made the default comparators sort() function friendly.
950 " Changes in 2.3:
951 "   - SilentSubstitute() and SilentDelete() should preserve cursor position.
952 "   - CleanupFileName() should also remove any leading or trailing whitespace.
953 " Changes in 2.2:
954 "   - EscapeCommand() now supports Lists as arguments.
955 "   - CrUnProtectedCharsPattern() now accepts an optional "capture" argument.
956 "   - Renamed PromptForElement2 to PromptForElement. It was a typo.
957 " Changes in 2.1:
958 "   - Fixed a typo in AddNotifyWindowClose() in the previous release.
959 "   - Added BinSearchList() function.
960 " Changes in 2.0:
961 "   - Converted to Vim7 autoload script. Since there is no common prefix to
962 "     find all the usages of genutils functions in your script, Use the
963 "     pattern \<\(:\|>\|#\)\@<!\zs\u\w\+( to find all the global functions and
964 "     prefix the ones from genutils with genutils#.
965 "   - The new version is not backwards compatible with prior versions. If you
966 "     have plugins that depend on the older versions of genutils, you should try
967 "     to request the author to port their plugin to use the new genutils. If
968 "     having them to coexist is a must, then use the below trick:
969 "       - Install the latest version of genutils first. Overwriting all existing
970 "         files.
971 "       - Open the plugin/genutils.vim file and note the value set to
972 "         loaded_genutils variable.
973 "       - Install the older version of genutils (non autoload version) in to
974 "         plugin directory, overwriting the existing file.
975 "       - Open the plugin/genutils.vim again and change the value of
976 "         loaded_genutils variable to the value you noted before and save it.
977 "   - Fix for Save/RestoreHardPosition() not working right when there are
978 "     wrapped lines in the window.
979 "   - Dropped the AddToFCShell and RemoveFromFCShell functions as these can't be
980 "     implemented in Vim7 because of new restrictions on FileChangedShell
981 "     autocommand. Use AddToFcShellPre and RemoveFromFCShellPre functions
982 "     instead.
983 "   - No longer depends on multvals plugin. Inherits some useful functions from
984 "     multvals to make way for it to be retired. New functions are:
985 "     genutils#CrUnProtectedCharsPattern
986 "     PromptForElement/GetSelectedIndex
987
988 if exists('loaded_genutils')
989   finish
990 endif
991 if v:version < 700
992   "echomsg 'genutils: You need at least Vim 7.0'
993   finish
994 endif
995
996 let loaded_genutils = 204