Browse Source
git-svn-id: file:///usr/local/svn/util/trunk@12 29942e26-f7dc-dc11-b955-0002b3153201master
leto
16 years ago
10 changed files with 13132 additions and 0 deletions
File diff suppressed because it is too large
@ -0,0 +1,407 @@ |
|||
*bufexplorer.txt* Buffer Explorer Last Change: 21 Dec 2007 |
|||
|
|||
Buffer Explorer *buffer-explorer* *bufexplorer* |
|||
Version 7.1.7 |
|||
|
|||
Plugin for easily exploring (or browsing) Vim |:buffers|. |
|||
|
|||
|bufexplorer-usage| Usage |
|||
|bufexplorer-installation| Installation |
|||
|bufexplorer-customization| Customization |
|||
|bufexplorer-changelog| Change Log |
|||
|bufexplorer-todo| Todo |
|||
|bufexplorer-credits| Credits |
|||
|
|||
For Vim version 7.0 and above. |
|||
This plugin is only available if 'compatible' is not set. |
|||
|
|||
{Vi does not have any of this} |
|||
|
|||
============================================================================== |
|||
INSTALLATION *bufexplorer-installation* |
|||
|
|||
To install: |
|||
- Download the bufexplorer.zip. |
|||
- Extract the zip archive into your runtime directory. |
|||
The archive contains plugin/bufexplorer.vim, and doc/bufexplorer.txt. |
|||
- Start Vim or goto an existing instance of Vim. |
|||
- Execute the following command: |
|||
> |
|||
:helptag <your runtime directory/doc |
|||
< |
|||
This will generate all the help tags for any file located in the doc |
|||
directory. |
|||
|
|||
============================================================================== |
|||
USAGE *bufexplorer-usage* |
|||
|
|||
To start exploring in the current window, use: > |
|||
|
|||
\be OR :BufExplorer |
|||
|
|||
If you would like to use something other than '\', you may simply change the |
|||
leader (see |mapleader|). |
|||
|
|||
Note: If the current buffer is modified when bufexplorer started, the current |
|||
window is always split and the new bufexplorer is displayed in that new |
|||
window. |
|||
|
|||
Commands to use once exploring: |
|||
|
|||
<enter> Opens the buffer that is under the cursor into the current |
|||
window. |
|||
<F1> Toggle help information. |
|||
<leftmouse> Opens the buffer that is under the cursor into the current |
|||
window. |
|||
<shift-enter> Opens the buffer that is under the cursor in another tab. |
|||
d |:wipeout| the buffer under the cursor from the list. |
|||
When a buffers is wiped, it will not be shown when unlisted |
|||
buffer are displayed. |
|||
D |:delete| the buffer under the cursor from the list. |
|||
The buffer's 'buflisted' is cleared. This allows for the buffer |
|||
to be displayed again using the 'show unlisted' command. |
|||
f Toggles whether you are taken to the active window when |
|||
selecting a buffer or not. |
|||
p Toggles the showing of a split filename/pathname. |
|||
q Quit exploring. |
|||
r Reverses the order the buffers are listed in. |
|||
R Toggles relative path/absolute path. |
|||
s Selects the order the buffers are listed in. Either by buffer |
|||
number, file name, file extension, most recently used (MRU), or |
|||
full path. |
|||
t Opens the buffer that is under the cursor in another tab. |
|||
u Toggles the showing of "unlisted" buffers. |
|||
|
|||
Once invoked, Buffer Explorer displays a sorted list (MRU is the default |
|||
sort method) of all the buffers that are currently opened. You are then |
|||
able to move the cursor to the line containing the buffer's name you are |
|||
wanting to act upon. Once you have selected the buffer you would like, |
|||
you can then either open it, close it(delete), resort the list, reverse |
|||
the sort, quit exploring and so on... |
|||
|
|||
=============================================================================== |
|||
CUSTOMIZATION *bufexplorer-customization* |
|||
|
|||
*g:bufExplorerDefaultHelp* |
|||
To control whether the default help is displayed or not, use: > |
|||
let g:bufExplorerDefaultHelp=0 " Do not show default help. |
|||
let g:bufExplorerDefaultHelp=1 " Show default help. |
|||
The default is to show the default help. |
|||
|
|||
*g:bufExplorerDetailedHelp* |
|||
To control whether detailed help is display by, use: > |
|||
let g:bufExplorerDetailedHelp=0 " Do not show detailed help. |
|||
let g:bufExplorerDetailedHelp=1 " Show detailed help. |
|||
The default is NOT to show detailed help. |
|||
|
|||
*g:bufExplorerFindActive* |
|||
To control whether you are taken to the active window when selecting a buffer, |
|||
use: > |
|||
let g:bufExplorerFindActive=0 " Do not go to active window. |
|||
let g:bufExplorerFindActive=1 " Go to active window. |
|||
The default is to be taken to the active window. |
|||
|
|||
*g:bufExplorerReverseSort* |
|||
To control whether to sort the buffer in reverse order or not, use: > |
|||
let g:bufExplorerReverseSort=0 " Do not sort in reverse order. |
|||
let g:bufExplorerReverseSort=1 " Sort in reverse order. |
|||
The default is NOT to sort in reverse order. |
|||
|
|||
*g:bufExplorerShowDirectories* |
|||
Directories usually show up in the list from using a command like ":e .". |
|||
To control whether to show directories in the buffer list or not, use: > |
|||
let g:bufExplorerShowDirectories=1 " Show directories. |
|||
let g:bufExplorerShowDirectories=0 " Don't show directories. |
|||
The default is to show directories. |
|||
|
|||
*g:bufExplorerShowRelativePath* |
|||
To control whether to show absolute paths or relative to the current |
|||
directory, use: > |
|||
let g:bufExplorerShowRelativePath=0 " Show absolute paths. |
|||
let g:bufExplorerShowRelativePath=1 " Show relative paths. |
|||
The default is to show absolute paths. |
|||
|
|||
*g:bufExplorerShowUnlisted* |
|||
To control whether to show unlisted buffer or not, use: > |
|||
let g:bufExplorerShowUnlisted=0 " Do not show unlisted buffers. |
|||
let g:bufExplorerShowUnlisted=1 " Show unlisted buffers. |
|||
The default is to NOT show unlisted buffers. |
|||
|
|||
*g:bufExplorerSortBy* |
|||
To control what field the buffers are sorted by, use: > |
|||
let g:bufExplorerSortBy='extension' " Sort by file extension. |
|||
let g:bufExplorerSortBy='fullpath' " Sort by full file path name. |
|||
let g:bufExplorerSortBy='mru' " Sort by most recently used. |
|||
let g:bufExplorerSortBy='name' " Sort by the buffer's name. |
|||
let g:bufExplorerSortBy='number' " Sort by the buffer's number. |
|||
The default is to sort by mru. |
|||
|
|||
*g:bufExplorerSplitOutPathName* |
|||
To control whether to split out the path and file name or not, use: > |
|||
let g:bufExplorerSplitOutPathName=1 " Split the path and file name. |
|||
let g:bufExplorerSplitOutPathName=0 " Don't split the path and file |
|||
" name. |
|||
The default is to split the path and file name. |
|||
|
|||
=============================================================================== |
|||
CHANGE LOG *bufexplorer-changelog* |
|||
|
|||
7.1.7 - Fixes: |
|||
* TaCahiroy fixed several issues related to opening a buffer in a |
|||
tab. |
|||
7.1.6 - Fixes: |
|||
* Removed ff=unix from modeline in bufexplorer.txt. Found by Bill |
|||
McCarthy. |
|||
7.1.5 - Fixes: |
|||
* Could not open unnamed buffers. Fixed by TaCahiroy. |
|||
7.1.4 - Fixes: |
|||
* Sometimes when a file's path has 'white space' in it, extra buffers |
|||
would be created containing each piece of the path. i.e: |
|||
opening c:\document and settings\test.txt would create a buffer |
|||
named "and" and a buffer named "Documents". This was reported and |
|||
fixed by TaCa Yoss. |
|||
7.1.3 - Fixes: |
|||
* Added code to allow only one instance of the plugin to run at a |
|||
time. Thanks Dennis Hostetler. |
|||
7.1.2 - Fixes: |
|||
* Fixed a jumplist issue spotted by JiangJun. I overlooked the |
|||
'jumplist' and with a couple calls to 'keepjumps', everything is |
|||
fine again. |
|||
* Went back to just having a plugin file, no autoload file. By having |
|||
the autoload, WinManager was no longer working and without really |
|||
digging into the cause, it was easier to go back to using just a |
|||
plugin file. |
|||
7.1.1 - Fixes: |
|||
* A problem spotted by Thomas Arendsen Hein. |
|||
When running Vim (7.1.94), error E493 was being thrown. |
|||
Enhancements: |
|||
* Added 'D' for 'delete' buffer as the 'd' command was a 'wipe' |
|||
buffer. |
|||
7.1.0 - Another 'major' update, some by Dave Larson, some by me. |
|||
* Making use of 'autoload' now to make the plugin load quicker. |
|||
* Removed '\bs' and '\bv'. These are now controlled by the user. The |
|||
user can issue a ':sp' or ':vs' to create a horizontal or vertical |
|||
split window and then issue a '\be' |
|||
* Added handling of tabs. |
|||
7.0.17 - Fixed issue with 'drop' command. |
|||
Various enhancements and improvements. |
|||
7.0.16 - Fixed issue reported by Liu Jiaping on non Windows systems, which was |
|||
... |
|||
Open file1, open file2, modify file1, open bufexplorer, you get the |
|||
following error: |
|||
|
|||
--------8<-------- |
|||
Error detected while processing function |
|||
<SNR>14_StartBufExplorer..<SNR>14_SplitOpen: |
|||
line 4: |
|||
E37: No write since last change (add ! to override) |
|||
|
|||
But the worse thing is, when I want to save the current buffer and |
|||
type ':w', I get another error message: |
|||
E382: Cannot write, 'buftype' option is set |
|||
--------8<-------- |
|||
|
|||
7.0.15 - Thanks to Mark Smithfield for suggesting bufexplorer needed to handle |
|||
the ':args' command. |
|||
7.0.14 - Thanks to Randall Hansen for removing the requirement of terminal |
|||
versions to be recompiled with 'gui' support so the 'drop' command |
|||
would work. The 'drop' command is really not needed in terminal |
|||
versions. |
|||
7.0.13 - Fixed integration with WinManager. |
|||
Thanks to Dave Eggum for another update. |
|||
- Fix: The detailed help didn't display the mapping for toggling |
|||
the split type, even though the split type is displayed. |
|||
- Fixed incorrect description in the detailed help for toggling |
|||
relative or full paths. |
|||
- Deprecated s:ExtractBufferNbr(). Vim's str2nr() does the same |
|||
thing. |
|||
- Created a s:Set() function that sets a variable only if it hasn't |
|||
already been defined. It's useful for initializing all those |
|||
default settings. |
|||
- Removed checks for repetitive command definitions. They were |
|||
unnecessary. |
|||
- Made the help highlighting a little more fancy. |
|||
- Minor reverse compatibility issue: Changed ambiguous setting |
|||
names to be more descriptive of what they do (also makes the code |
|||
easier to follow): |
|||
Changed bufExplorerSortDirection to bufExplorerReverseSort |
|||
Changed bufExplorerSplitType to bufExplorerSplitVertical |
|||
Changed bufExplorerOpenMode to bufExplorerUseCurrentWindow |
|||
- When the BufExplorer window closes, all the file-local marks are |
|||
now deleted. This may have the benefit of cleaning up some of the |
|||
jumplist. |
|||
- Changed the name of the parameter for StartBufExplorer from |
|||
"split" to "open". The parameter is a string which specifies how |
|||
the buffer will be open, not if it is split or not. |
|||
- Deprecated DoAnyMoreBuffersExist() - it is a one line function |
|||
only used in one spot. |
|||
- Created four functions (SplitOpen(), RebuildBufferList(), |
|||
UpdateHelpStatus() and ReSortListing()) all with one purpose - to |
|||
reduce repeated code. |
|||
- Changed the name of AddHeader() to CreateHelp() to be more |
|||
descriptive of what it does. It now returns an array instead of |
|||
updating the window directly. This has the benefit of making the |
|||
code more efficient since the text the function returns is used a |
|||
little differently in the two places the function is called. |
|||
- Other minor simplifications. |
|||
7.0.12 - MAJOR Update. |
|||
This version will ONLY run with Vim version 7.0 or greater. |
|||
Dave Eggum has made some 'significant' updates to this latest |
|||
version: |
|||
- Added BufExplorerGetAltBuf() global function to be used in the |
|||
user’s rulerformat. |
|||
- Added g:bufExplorerSplitRight option. |
|||
- Added g:bufExplorerShowRelativePath option with mapping. |
|||
- Added current line highlighting. |
|||
- The split type can now be changed whether bufexplorer is opened |
|||
in split mode or not. |
|||
- Various major and minor bug fixes and speed improvements. |
|||
- Sort by extension. |
|||
Other improvements/changes: |
|||
- Changed the help key from '?' to <F1> to be more 'standard'. |
|||
- Fixed splitting of vertical bufexplorer window. |
|||
Hopefully I have not forgot something :) |
|||
7.0.11 - Fixed a couple of highlighting bugs, reported by David Eggum. He also |
|||
changed passive voice to active on a couple of warning messages. |
|||
7.0.10 - Fixed bug report by Xiangjiang Ma. If the 'ssl' option is set, |
|||
the slash character used when displaying the path was incorrect. |
|||
7.0.9 - Martin Grenfell found and eliminated an annoying bug in the |
|||
bufexplorer/winmanager integration. The bug was were an |
|||
annoying message would be displayed when a window was split or |
|||
a new file was opened in a new window. Thanks Martin! |
|||
7.0.8 - Thanks to Mike Li for catching a bug in the WinManager integration. |
|||
The bug was related to the incorrect displaying of the buffer |
|||
explorer's window title. |
|||
7.0.7 - Thanks to Jeremy Cowgar for adding a new enhancement. This |
|||
enhancement allows the user to press 'S', that is capital S, which |
|||
will open the buffer under the cursor in a newly created split |
|||
window. |
|||
7.0.6 - Thanks to Larry Zhang for finding a bug in the "split" buffer code. |
|||
If you force set g:bufExplorerSplitType='v' in your vimrc, and if you |
|||
tried to do a \bs to split the bufexplorer window, it would always |
|||
split horizontal, not vertical. He also found that I had a typeo in |
|||
that the variable g:bufExplorerSplitVertSize was all lower case in |
|||
the documentation which was incorrect. |
|||
7.0.5 - Thanks to Mun Johl for pointing out a bug that if a buffer was |
|||
modified, the '+' was not showing up correctly. |
|||
7.0.4 - Fixed a problem discovered first by Xiangjiang Ma. Well since I've |
|||
been using vim 7.0 and not 6.3, I started using a function (getftype) |
|||
that is not in 6.3. So for backward compatibility, I conditionaly use |
|||
this function now. Thus, the g:bufExplorerShowDirectories feature is |
|||
only available when using vim 7.0 and above. |
|||
7.0.3 - Thanks to Erwin Waterlander for finding a problem when the last |
|||
buffer was deleted. This issue got me to rewrite the buffer display |
|||
logic (which I've wanted to do for sometime now). |
|||
Also great thanks to Dave Eggum for coming up with idea for |
|||
g:bufExplorerShowDirectories. Read the above information about this |
|||
feature. |
|||
7.0.2 - Thanks to Thomas Arendsen Hein for finding a problem when a user |
|||
has the default help turned off and then brought up the explorer. An |
|||
E493 would be displayed. |
|||
7.0.1 - Thanks to Erwin Waterlander for finding a couple problems. |
|||
The first problem allowed a modified buffer to be deleted. Opps! The |
|||
second problem occurred when several files were opened, BufExplorer |
|||
was started, the current buffer was deleted using the 'd' option, and |
|||
then BufExplorer was exited. The deleted buffer was still visible |
|||
while it is not in the buffers list. Opps again! |
|||
7.0.0 - Thanks to Shankar R. for suggesting to add the ability to set |
|||
the fixed width (g:bufExplorerSplitVertSize) of a new window |
|||
when opening bufexplorer vertically and fixed height |
|||
(g:bufExplorerSplitHorzSize) of a new window when opening |
|||
bufexplorer horizontally. By default, the windows are normally |
|||
split to use half the existing width or height. |
|||
6.3.0 - Added keepjumps so that the jumps list would not get cluttered with |
|||
bufexplorer related stuff. |
|||
6.2.3 - Thanks to Jay Logan for finding a bug in the vertical split position |
|||
of the code. When selecting that the window was to be split |
|||
vertically by doing a '\bv', from then on, all splits, i.e. '\bs', |
|||
were split vertically, even though g:bufExplorerSplitType was not set |
|||
to 'v'. |
|||
6.2.2 - Thanks to Patrik Modesto for adding a small improvement. For some |
|||
reason his bufexplorer window was always showing up folded. He added |
|||
'setlocal nofoldenable' and it was fixed. |
|||
6.2.1 - Thanks goes out to Takashi Matsuo for added the 'fullPath' sorting |
|||
logic and option. |
|||
6.2.0 - Thanks goes out to Simon Johann-Ganter for spotting and fixing a |
|||
problem in that the last search pattern is overridden by the search |
|||
pattern for blank lines. |
|||
6.1.6 - Thanks to Artem Chuprina for finding a pesky bug that has been around |
|||
for sometime now. The <esc> key mapping was causing the buffer |
|||
explored to close prematurely when vim was run in an xterm. The <esc> |
|||
key mapping is now removed. |
|||
6.1.5 - Thanks to Khorev Sergey. Added option to show default help or not. |
|||
6.1.4 - Thanks goes out to Valery Kondakoff for suggesting the addition of |
|||
setlocal nonumber and foldcolumn=0. This allows for line numbering |
|||
and folding to be turned off temporarily while in the explorer. |
|||
6.1.3 - Added folding. Did some code cleanup. Added the ability to force the |
|||
newly split window to be temporarily vertical, which was suggested by |
|||
Thomas Glanzmann. |
|||
6.1.2 - Now pressing the <esc> key will quit, just like 'q'. |
|||
Added folds to hide winmanager configuration. |
|||
If anyone had the 'C' option in their cpoptions they would receive |
|||
a E10 error on startup of BufExplorer. cpo is now saved, updated and |
|||
restored. Thanks to Charles E Campbell, Jr. |
|||
Attempted to make sure there can only be one BufExplorer window open |
|||
at a time. |
|||
6.1.1 - Thanks to Brian D. Goodwin for adding toupper to FileNameCmp. This |
|||
way buffers sorted by name will be in the correct order regardless of |
|||
case. |
|||
6.0.16 - Thanks to Andre Pang for the original patch/idea to get bufexplorer |
|||
to work in insertmode/modeless mode (evim). Added Initialize |
|||
and Cleanup autocommands to handle commands that need to be |
|||
performed when starting or leaving bufexplorer. |
|||
6.0.15 - Srinath Avadhanulax added a patch for winmanager.vim. |
|||
6.0.14 - Fix a few more bug that I thought I already had fixed. Thanks |
|||
to Eric Bloodworth for adding 'Open Mode/Edit in Place'. Added |
|||
vertical splitting. |
|||
6.0.13 - Thanks to Charles E Campbell, Jr. for pointing out some embarrassing |
|||
typos that I had in the documentation. I guess I need to run |
|||
the spell checker more :o) |
|||
6.0.12 - Thanks to Madoka Machitani, for the tip on adding the augroup command |
|||
around the MRUList autocommands. |
|||
6.0.11 - Fixed bug report by Xiangjiang Ma. '"=' was being added to the |
|||
search history which messed up hlsearch. |
|||
6.0.10 - Added the necessary hooks so that the Srinath Avadhanula's |
|||
winmanager.vim script could more easily integrate with this script. |
|||
Tried to improve performance. |
|||
6.0.9 - Added MRU (Most Recently Used) sort ordering. |
|||
6.0.8 - Was not resetting the showcmd command correctly. |
|||
Added nifty help file. |
|||
6.0.7 - Thanks to Brett Carlane for some great enhancements. Some are added, |
|||
some are not, yet. Added highlighting of current and alternate |
|||
filenames. Added splitting of path/filename toggle. Reworked |
|||
ShowBuffers(). |
|||
Changed my email address. |
|||
6.0.6 - Copyright notice added. Needed this so that it could be distributed |
|||
with Debian Linux. Fixed problem with the SortListing() function |
|||
failing when there was only one buffer to display. |
|||
6.0.5 - Fixed problems reported by David Pascoe, in that you where unable to |
|||
hit 'd' on a buffer that belonged to a files that no longer existed |
|||
and that the 'yank' buffer was being overridden by the help text when |
|||
the bufexplorer was opened. |
|||
6.0.4 - Thanks to Charles Campbell, Jr. for making this plugin more plugin |
|||
*compliant*, adding default keymappings of <Leader>be and <Leader>bs |
|||
as well as fixing the 'w:sortDirLabel not being defined' bug. |
|||
6.0.3 - Added sorting capabilities. Sort taken from explorer.vim. |
|||
6.0.2 - Can't remember. |
|||
6.0.1 - Initial release. |
|||
|
|||
=============================================================================== |
|||
TODO *bufexplorer-todo* |
|||
|
|||
- The issuing of a ':bd' command does not always remove the buffer number from |
|||
the MRU list. |
|||
- Look into adding '\bs' (buffer split) command back into the code. |
|||
|
|||
=============================================================================== |
|||
CREDITS *bufexplorer-credits* |
|||
|
|||
Author: Jeff Lanzarotta <delux256-vim at yahoo dot com> |
|||
|
|||
Credit must go out to Bram Moolenaar and all the Vim developers for |
|||
making the world's best editor (IMHO). I also want to thank everyone who |
|||
helped and gave me suggestions. I wouldn't want to leave anyone out so I |
|||
won't list names. |
|||
|
|||
=============================================================================== |
|||
vim:tw=78:noet:wrap:ts=8:ft=help:norl: |
@ -0,0 +1,406 @@ |
|||
*matchit.txt* Extended "%" matching |
|||
|
|||
For instructions on installing this file, type |
|||
:help matchit-install |
|||
inside Vim. |
|||
|
|||
For Vim version 6.3. Last change: 2007 Aug 29 |
|||
|
|||
|
|||
VIM REFERENCE MANUAL by Benji Fisher |
|||
|
|||
*matchit* *matchit.vim* |
|||
|
|||
1. Extended matching with "%" |matchit-intro| |
|||
2. Activation |matchit-activate| |
|||
3. Configuration |matchit-configure| |
|||
4. Supporting a New Language |matchit-newlang| |
|||
5. Known Bugs and Limitations |matchit-bugs| |
|||
|
|||
The functionality mentioned here is a plugin, see |add-plugin|. |
|||
This plugin is only available if 'compatible' is not set. |
|||
You can avoid loading this plugin by setting the "loaded_matchit" variable |
|||
in your |vimrc| file: > |
|||
:let loaded_matchit = 1 |
|||
|
|||
{Vi does not have any of this} |
|||
|
|||
============================================================================== |
|||
1. Extended matching with "%" *matchit-intro* |
|||
|
|||
*matchit-%* |
|||
% Cycle forward through matching groups, such as "if", "else", "endif", |
|||
as specified by |b:match_words|. |
|||
|
|||
*g%* *v_g%* *o_g%* |
|||
g% Cycle backwards through matching groups, as specified by |
|||
|b:match_words|. For example, go from "if" to "endif" to "else". |
|||
|
|||
*[%* *v_[%* *o_[%* |
|||
[% Go to [count] previous unmatched group, as specified by |
|||
|b:match_words|. Similar to |[{|. |
|||
|
|||
*]%* *v_]%* *o_]%* |
|||
]% Go to [count] next unmatched group, as specified by |
|||
|b:match_words|. Similar to |]}|. |
|||
|
|||
*v_a%* |
|||
a% In Visual mode, select the matching group, as specified by |
|||
|b:match_words|, containing the cursor. Similar to |v_a[|. |
|||
A [count] is ignored, and only the first character of the closing |
|||
pattern is selected. |
|||
|
|||
In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, |
|||
bracket, or paren to its match. This can be configured with the 'matchpairs' |
|||
option. The matchit plugin extends this in several ways: |
|||
|
|||
You can match whole words, such as "if" and "endif", not just |
|||
single characters. You can also specify a |regular-expression|. |
|||
You can define groups with more than two words, such as "if", |
|||
"else", "endif". Banging on the "%" key will cycle from the "if" to |
|||
the first "else", the next "else", ..., the closing "endif", and back |
|||
to the opening "if". Nested structures are skipped. Using |g%| goes |
|||
in the reverse direction. |
|||
By default, words inside comments and strings are ignored, unless |
|||
the cursor is inside a comment or string when you type "%". If the |
|||
only thing you want to do is modify the behavior of "%" so that it |
|||
behaves this way, you do not have to define |b:match_words|, since the |
|||
script uses the 'matchpairs' option as well as this variable. |
|||
|
|||
See |matchit-details| for details on what the script does, and |b:match_words| |
|||
for how to specify matching patterns. |
|||
|
|||
MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* |
|||
|
|||
Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in |
|||
|motion| commands in |Operator-pending| and |Visual| modes. However, you |
|||
cannot make these motions |linewise| or |characterwise|, since the |:omap|s |
|||
that define them start with "v" in order to make the default behavior |
|||
inclusive. (See |o_v|.) In other words, "dV%" will not work. The |
|||
work-around is to go through Visual mode: "V%d" will work. |
|||
|
|||
LANGUAGES: *matchit-languages* |
|||
|
|||
Currently, the following languages are supported: Ada, ASP with VBS, Csh, |
|||
DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, |
|||
SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via |
|||
the default |filetype-plugin|s in the standard vim distribution. |
|||
|
|||
To support a new language, see |matchit-newlang| below. |
|||
|
|||
DETAILS: *matchit-details* *matchit-parse* |
|||
|
|||
Here is an outline of what matchit.vim does each time you hit the "%" key. If |
|||
there are |backref|s in |b:match_words| then the first step is to produce a |
|||
version in which these back references have been eliminated; if there are no |
|||
|backref|s then this step is skipped. This step is called parsing. For |
|||
example, "\(foo\|bar\):end\1" is parsed to yield |
|||
"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are |
|||
nested groups. If debugging is turned on, the parsed version is saved as |
|||
|b:match_pat|. |
|||
|
|||
*matchit-choose* |
|||
Next, the script looks for a word on the current line that matches the pattern |
|||
just constructed. It includes the patterns from the 'matchpairs' option. |
|||
The goal is to do what you expect, which turns out to be a little complicated. |
|||
The script follows these rules: |
|||
|
|||
Insist on a match that ends on or after the cursor. |
|||
Prefer a match that includes the cursor position (that is, one that |
|||
starts on or before the cursor). |
|||
Prefer a match that starts as close to the cursor as possible. |
|||
If more than one pattern in |b:match_words| matches, choose the one |
|||
that is listed first. |
|||
|
|||
Examples: |
|||
|
|||
Suppose you > |
|||
:let b:match_words = '<:>,<tag>:</tag>' |
|||
< and hit "%" with the cursor on or before the "<" in "a <tag> is born". |
|||
The pattern '<' comes first, so it is preferred over '<tag>', which |
|||
also matches. If the cursor is on the "t", however, then '<tag>' is |
|||
preferred, because this matches a bit of text containing the cursor. |
|||
If the two groups of patterns were reversed then '<' would never be |
|||
preferred. |
|||
|
|||
Suppose you > |
|||
:let b:match_words = 'if:end if' |
|||
< (Note the space!) and hit "%" with the cursor at the end of "end if". |
|||
Then "if" matches, which is probably not what you want, but if the |
|||
cursor starts on the "end " then "end if" is chosen. (You can avoid |
|||
this problem by using a more complicated pattern.) |
|||
|
|||
If there is no match, the cursor does not move. (Before version 1.13 of the |
|||
script, it would fall back on the usual behavior of |%|). If debugging is |
|||
turned on, the matched bit of text is saved as |b:match_match| and the cursor |
|||
column of the start of the match is saved as |b:match_col|. |
|||
|
|||
Next, the script looks through |b:match_words| (original and parsed versions) |
|||
for the group and pattern that match. If debugging is turned on, the group is |
|||
saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If |
|||
there are |backref|s then, in addition, the matching pattern is saved as |
|||
|b:match_word| and a table of translations is saved as |b:match_table|. If |
|||
there are |backref|s, these are determined from the matching pattern and |
|||
|b:match_match| and substituted into each pattern in the matching group. |
|||
|
|||
The script decides whether to search forwards or backwards and chooses |
|||
arguments for the |searchpair()| function. Then, the cursor is moved to the |
|||
start of the match, and |searchpair()| is called. By default, matching |
|||
structures inside strings and comments are ignored. This can be changed by |
|||
setting |b:match_skip|. |
|||
|
|||
============================================================================== |
|||
2. Activation *matchit-activate* |
|||
|
|||
You can use this script as a plugin, by copying it to your plugin directory. |
|||
See |add-global-plugin| for instructions. You can also add a line to your |
|||
|vimrc| file, such as > |
|||
:source $VIMRUNTIME/macros/matchit.vim |
|||
or > |
|||
:runtime macros/matchit.vim |
|||
Either way, the script should start working the next time you start up Vim. |
|||
|
|||
(Earlier versions of the script did nothing unless a |buffer-variable| named |
|||
|b:match_words| was defined. Even earlier versions contained autocommands |
|||
that set this variable for various file types. Now, |b:match_words| is |
|||
defined in many of the default |filetype-plugin|s instead.) |
|||
|
|||
For a new language, you can add autocommands to the script or to your vimrc |
|||
file, but the recommended method is to add a line such as > |
|||
let b:match_words = '\<foo\>:\<bar\>' |
|||
to the |filetype-plugin| for your language. See |b:match_words| below for how |
|||
this variable is interpreted. |
|||
|
|||
TROUBLESHOOTING *matchit-troubleshoot* |
|||
|
|||
The script should work in most installations of Vim. It may not work if Vim |
|||
was compiled with a minimal feature set, for example if the |+syntax| option |
|||
was not enabled. If your Vim has support for syntax compiled in, but you do |
|||
not have |syntax| highlighting turned on, matchit.vim should work, but it may |
|||
fail to skip matching groups in comments and strings. If the |filetype| |
|||
mechanism is turned off, the |b:match_words| variable will probably not be |
|||
defined automatically. |
|||
|
|||
============================================================================== |
|||
3. Configuration *matchit-configure* |
|||
|
|||
There are several variables that govern the behavior of matchit.vim. Note |
|||
that these are variables local to the buffer, not options, so use |:let| to |
|||
define them, not |:set|. Some of these variables have values that matter; for |
|||
others, it only matters whether the variable has been defined. All of these |
|||
can be defined in the |filetype-plugin| or autocommand that defines |
|||
|b:match_words| or "on the fly." |
|||
|
|||
The main variable is |b:match_words|. It is described in the section below on |
|||
supporting a new language. |
|||
|
|||
*MatchError* *matchit-hl* *matchit-highlight* |
|||
MatchError is the highlight group for error messages from the script. By |
|||
default, it is linked to WarningMsg. If you do not want to be bothered by |
|||
error messages, you can define this to be something invisible. For example, |
|||
if you use the GUI version of Vim and your command line is normally white, you |
|||
can do > |
|||
:hi MatchError guifg=white guibg=white |
|||
< |
|||
*b:match_ignorecase* |
|||
If you > |
|||
:let b:match_ignorecase = 1 |
|||
then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" |
|||
are equivalent. If you > |
|||
:let b:match_ignorecase = 0 |
|||
then matchit.vim treats "end" and "END" differently. (There will be no |
|||
b:match_infercase option unless someone requests it.) |
|||
|
|||
*b:match_debug* |
|||
Define b:match_debug if you want debugging information to be saved. See |
|||
|matchit-debug|, below. |
|||
|
|||
*b:match_skip* |
|||
If b:match_skip is defined, it is passed as the skip argument to |
|||
|searchpair()|. This controls when matching structures are skipped, or |
|||
ignored. By default, they are ignored inside comments and strings, as |
|||
determined by the |syntax| mechanism. (If syntax highlighting is turned off, |
|||
nothing is skipped.) You can set b:match_skip to a string, which evaluates to |
|||
a non-zero, numerical value if the match is to be skipped or zero if the match |
|||
should not be skipped. In addition, the following special values are |
|||
supported by matchit.vim: |
|||
s:foo becomes (current syntax item) =~ foo |
|||
S:foo becomes (current syntax item) !~ foo |
|||
r:foo becomes (line before cursor) =~ foo |
|||
R:foo becomes (line before cursor) !~ foo |
|||
(The "s" is meant to suggest "syntax", and the "r" is meant to suggest |
|||
"regular expression".) |
|||
|
|||
Examples: |
|||
|
|||
You can get the default behavior with > |
|||
:let b:match_skip = 's:comment\|string' |
|||
< |
|||
If you want to skip matching structures unless they are at the start |
|||
of the line (ignoring whitespace) then you can > |
|||
:let b:match_skip = 'R:^\s*' |
|||
< Do not do this if strings or comments can span several lines, since |
|||
the normal syntax checking will not be done if you set b:match_skip. |
|||
|
|||
In LaTeX, since "%" is used as the comment character, you can > |
|||
:let b:match_skip = 'r:%' |
|||
< Unfortunately, this will skip anything after "\%", an escaped "%". To |
|||
allow for this, and also "\\%" (an excaped backslash followed by the |
|||
comment character) you can > |
|||
:let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' |
|||
< |
|||
See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both |
|||
syntax and a regular expression. |
|||
|
|||
============================================================================== |
|||
4. Supporting a New Language *matchit-newlang* |
|||
*b:match_words* |
|||
In order for matchit.vim to support a new language, you must define a suitable |
|||
pattern for |b:match_words|. You may also want to set some of the |
|||
|matchit-configure| variables, as described above. If your language has a |
|||
complicated syntax, or many keywords, you will need to know something about |
|||
Vim's |regular-expression|s. |
|||
|
|||
The format for |b:match_words| is similar to that of the 'matchpairs' option: |
|||
it is a comma (,)-separated list of groups; each group is a colon(:)-separated |
|||
list of patterns (regular expressions). Commas and backslashes that are part |
|||
of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to |
|||
have only one group; the effect is undefined if a group has only one pattern. |
|||
A simple example is > |
|||
:let b:match_words = '\<if\>:\<endif\>,' |
|||
\ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>' |
|||
(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" |
|||
matches the end of "endif" but "\<if\>" does not.) Then banging on the "%" |
|||
key will bounce the cursor between "if" and the matching "endif"; and from |
|||
"while" to any matching "continue" or "break", then to the matching "endwhile" |
|||
and back to the "while". It is almost always easier to use |literal-string|s |
|||
(single quotes) as above: '\<if\>' rather than "\\<if\\>" and so on. |
|||
|
|||
Exception: If the ":" character does not appear in b:match_words, then it is |
|||
treated as an expression to be evaluated. For example, > |
|||
:let b:match_words = 'GetMatchWords()' |
|||
allows you to define a function. This can return a different string depending |
|||
on the current syntax, for example. |
|||
|
|||
Once you have defined the appropriate value of |b:match_words|, you will |
|||
probably want to have this set automatically each time you edit the |
|||
appropriate file type. The recommended way to do this is by adding the |
|||
definition to a |filetype-plugin| file. |
|||
|
|||
Tips: Be careful that your initial pattern does not match your final pattern. |
|||
See the example above for the use of word-boundary expressions. It is usually |
|||
better to use ".\{-}" (as many as necessary) instead of ".*" (as many as |
|||
possible). See |\{-|. For example, in the string "<tag>label</tag>", "<.*>" |
|||
matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and |
|||
"</tag>". |
|||
|
|||
*matchit-spaces* *matchit-s:notend* |
|||
If "if" is to be paired with "end if" (Note the space!) then word boundaries |
|||
are not enough. Instead, define a regular expression s:notend that will match |
|||
anything but "end" and use it as follows: > |
|||
:let s:notend = '\%(\<end\s\+\)\@<!' |
|||
:let b:match_words = s:notend . '\<if\>:\<end\s\+if\>' |
|||
< *matchit-s:sol* |
|||
This is a simplified version of what is done for Ada. The s:notend is a |
|||
|script-variable|. Similarly, you may want to define a start-of-line regular |
|||
expression > |
|||
:let s:sol = '\%(^\|;\)\s*' |
|||
if keywords are only recognized after the start of a line or after a |
|||
semicolon (;), with optional white space. |
|||
|
|||
*matchit-backref* *matchit-\1* |
|||
In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the |
|||
INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred |
|||
to as back references, or backrefs. For example, > |
|||
:let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>' |
|||
means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note |
|||
that "\1" does not refer to the "\(h\)" in this example. If you have |
|||
"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything |
|||
up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" |
|||
refers to everything and "\2" refers to "\(parentheses\)". If you use a |
|||
variable such as |s:notend| or |s:sol| in the previous paragraph then remember |
|||
to count any "\(" patterns in this variable. You do not have to count groups |
|||
defined by |\%(\)|. |
|||
|
|||
It should be possible to resolve back references from any pattern in the |
|||
group. For example, > |
|||
:let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' |
|||
would not work because "\2" cannot be determined from "morefoo" and "\1" |
|||
cannot be determined from "andbar". On the other hand, > |
|||
:let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' |
|||
should work (and have the same effect as "foobar:barfoo:endfoobar"), although |
|||
this has not been thoroughly tested. |
|||
|
|||
You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has |
|||
not been thouroughly tested in matchit.vim.) For example, if the keyword "if" |
|||
must occur at the start of the line, with optional white space, you might use |
|||
the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of |
|||
at the start of the line. For another example, if HTML had only one tag then |
|||
one could > |
|||
:let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' |
|||
so that "%" can bounce between matching "<" and ">" pairs or (starting on |
|||
"tag" or "/tag") between matching tags. Without the |\@<=|, the script would |
|||
bounce from "tag" to the "<" in "</tag>", and another "%" would not take you |
|||
back to where you started. |
|||
|
|||
DEBUGGING *matchit-debug* *:MatchDebug* |
|||
|
|||
If you are having trouble figuring out the appropriate definition of |
|||
|b:match_words| then you can take advantage of the same information I use when |
|||
debugging the script. This is especially true if you are not sure whether |
|||
your patterns or my script are at fault! To make this more convenient, I have |
|||
made the command :MatchDebug, which defines the variable |b:match_debug| and |
|||
creates a Matchit menu. This menu makes it convenient to check the values of |
|||
the variables described below. You will probably also want to read |
|||
|matchit-details| above. |
|||
|
|||
Defining the variable |b:match_debug| causes the script to set the following |
|||
variables, each time you hit the "%" key. Several of these are only defined |
|||
if |b:match_words| includes |backref|s. |
|||
|
|||
*b:match_pat* |
|||
The b:match_pat variable is set to |b:match_words| with |backref|s parsed. |
|||
*b:match_match* |
|||
The b:match_match variable is set to the bit of text that is recognized as a |
|||
match. |
|||
*b:match_col* |
|||
The b:match_col variable is set to the cursor column of the start of the |
|||
matching text. |
|||
*b:match_wholeBR* |
|||
The b:match_wholeBR variable is set to the comma-separated group of patterns |
|||
that matches, with |backref|s unparsed. |
|||
*b:match_iniBR* |
|||
The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. |
|||
*b:match_ini* |
|||
The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, |
|||
with |backref|s resolved from |b:match_match|. |
|||
*b:match_tail* |
|||
The b:match_tail variable is set to the remaining patterns in |
|||
|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. |
|||
*b:match_word* |
|||
The b:match_word variable is set to the pattern from |b:match_wholeBR| that |
|||
matches |b:match_match|. |
|||
*b:match_table* |
|||
The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in |
|||
|b:match_word|. |
|||
|
|||
============================================================================== |
|||
5. Known Bugs and Limitations *matchit-bugs* |
|||
|
|||
Just because I know about a bug does not mean that it is on my todo list. I |
|||
try to respond to reports of bugs that cause real problems. If it does not |
|||
cause serious problems, or if there is a work-around, a bug may sit there for |
|||
a while. Moral: if a bug (known or not) bothers you, let me know. |
|||
|
|||
The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may |
|||
have undesired effects in Select mode |Select-mode-mapping|. At least, if you |
|||
want to replace the selection with any character in "ag%[]" there will be a |
|||
pause of |'updatetime'| first. |
|||
|
|||
It would be nice if "\0" were recognized as the entire pattern. That is, it |
|||
would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may |
|||
try to implement this in a future version. (This is not so easy to arrange as |
|||
you might think!) |
|||
|
|||
============================================================================== |
|||
vim:tw=78:fo=tcq2: |
File diff suppressed because it is too large
@ -0,0 +1,112 @@ |
|||
'Tlist_Auto_Highlight_Tag' taglist.txt /*'Tlist_Auto_Highlight_Tag'* |
|||
'Tlist_Auto_Open' taglist.txt /*'Tlist_Auto_Open'* |
|||
'Tlist_Auto_Update' taglist.txt /*'Tlist_Auto_Update'* |
|||
'Tlist_Close_On_Select' taglist.txt /*'Tlist_Close_On_Select'* |
|||
'Tlist_Compact_Format' taglist.txt /*'Tlist_Compact_Format'* |
|||
'Tlist_Ctags_Cmd' taglist.txt /*'Tlist_Ctags_Cmd'* |
|||
'Tlist_Display_Prototype' taglist.txt /*'Tlist_Display_Prototype'* |
|||
'Tlist_Display_Tag_Scope' taglist.txt /*'Tlist_Display_Tag_Scope'* |
|||
'Tlist_Enable_Fold_Column' taglist.txt /*'Tlist_Enable_Fold_Column'* |
|||
'Tlist_Exit_OnlyWindow' taglist.txt /*'Tlist_Exit_OnlyWindow'* |
|||
'Tlist_File_Fold_Auto_Close' taglist.txt /*'Tlist_File_Fold_Auto_Close'* |
|||
'Tlist_GainFocus_On_ToggleOpen' taglist.txt /*'Tlist_GainFocus_On_ToggleOpen'* |
|||
'Tlist_Highlight_Tag_On_BufEnter' taglist.txt /*'Tlist_Highlight_Tag_On_BufEnter'* |
|||
'Tlist_Inc_Winwidth' taglist.txt /*'Tlist_Inc_Winwidth'* |
|||
'Tlist_Max_Submenu_Items' taglist.txt /*'Tlist_Max_Submenu_Items'* |
|||
'Tlist_Max_Tag_Length' taglist.txt /*'Tlist_Max_Tag_Length'* |
|||
'Tlist_Process_File_Always' taglist.txt /*'Tlist_Process_File_Always'* |
|||
'Tlist_Show_Menu' taglist.txt /*'Tlist_Show_Menu'* |
|||
'Tlist_Show_One_File' taglist.txt /*'Tlist_Show_One_File'* |
|||
'Tlist_Sort_Type' taglist.txt /*'Tlist_Sort_Type'* |
|||
'Tlist_Use_Horiz_Window' taglist.txt /*'Tlist_Use_Horiz_Window'* |
|||
'Tlist_Use_Right_Window' taglist.txt /*'Tlist_Use_Right_Window'* |
|||
'Tlist_Use_SingleClick' taglist.txt /*'Tlist_Use_SingleClick'* |
|||
'Tlist_WinHeight' taglist.txt /*'Tlist_WinHeight'* |
|||
'Tlist_WinWidth' taglist.txt /*'Tlist_WinWidth'* |
|||
:TlistAddFiles taglist.txt /*:TlistAddFiles* |
|||
:TlistAddFilesRecursive taglist.txt /*:TlistAddFilesRecursive* |
|||
:TlistClose taglist.txt /*:TlistClose* |
|||
:TlistDebug taglist.txt /*:TlistDebug* |
|||
:TlistHighlightTag taglist.txt /*:TlistHighlightTag* |
|||
:TlistLock taglist.txt /*:TlistLock* |
|||
:TlistMessages taglist.txt /*:TlistMessages* |
|||
:TlistOpen taglist.txt /*:TlistOpen* |
|||
:TlistSessionLoad taglist.txt /*:TlistSessionLoad* |
|||
:TlistSessionSave taglist.txt /*:TlistSessionSave* |
|||
:TlistShowPrototype taglist.txt /*:TlistShowPrototype* |
|||
:TlistShowTag taglist.txt /*:TlistShowTag* |
|||
:TlistToggle taglist.txt /*:TlistToggle* |
|||
:TlistUndebug taglist.txt /*:TlistUndebug* |
|||
:TlistUnlock taglist.txt /*:TlistUnlock* |
|||
:TlistUpdate taglist.txt /*:TlistUpdate* |
|||
NERDAllowAnyVisualDelims NERD_commenter.txt /*NERDAllowAnyVisualDelims* |
|||
NERDBlockComIgnoreEmpty NERD_commenter.txt /*NERDBlockComIgnoreEmpty* |
|||
NERDComAlignedComment NERD_commenter.txt /*NERDComAlignedComment* |
|||
NERDComAltDelim NERD_commenter.txt /*NERDComAltDelim* |
|||
NERDComAppendComment NERD_commenter.txt /*NERDComAppendComment* |
|||
NERDComAuthor NERD_commenter.txt /*NERDComAuthor* |
|||
NERDComChangelog NERD_commenter.txt /*NERDComChangelog* |
|||
NERDComComment NERD_commenter.txt /*NERDComComment* |
|||
NERDComCredits NERD_commenter.txt /*NERDComCredits* |
|||
NERDComDefaultDelims NERD_commenter.txt /*NERDComDefaultDelims* |
|||
NERDComEOLComment NERD_commenter.txt /*NERDComEOLComment* |
|||
NERDComFiletypes NERD_commenter.txt /*NERDComFiletypes* |
|||
NERDComFunctionality NERD_commenter.txt /*NERDComFunctionality* |
|||
NERDComFunctionalityDetails NERD_commenter.txt /*NERDComFunctionalityDetails* |
|||
NERDComFunctionalitySummary NERD_commenter.txt /*NERDComFunctionalitySummary* |
|||
NERDComHeuristics NERD_commenter.txt /*NERDComHeuristics* |
|||
NERDComInsertComment NERD_commenter.txt /*NERDComInsertComment* |
|||
NERDComInvertComment NERD_commenter.txt /*NERDComInvertComment* |
|||
NERDComIssues NERD_commenter.txt /*NERDComIssues* |
|||
NERDComMappings NERD_commenter.txt /*NERDComMappings* |
|||
NERDComMinimalComment NERD_commenter.txt /*NERDComMinimalComment* |
|||
NERDComNERDComment NERD_commenter.txt /*NERDComNERDComment* |
|||
NERDComNestedComment NERD_commenter.txt /*NERDComNestedComment* |
|||
NERDComNesting NERD_commenter.txt /*NERDComNesting* |
|||
NERDComOptions NERD_commenter.txt /*NERDComOptions* |
|||
NERDComOptionsDetails NERD_commenter.txt /*NERDComOptionsDetails* |
|||
NERDComOptionsSummary NERD_commenter.txt /*NERDComOptionsSummary* |
|||
NERDComPrependComment NERD_commenter.txt /*NERDComPrependComment* |
|||
NERDComSexyComment NERD_commenter.txt /*NERDComSexyComment* |
|||
NERDComSexyComments NERD_commenter.txt /*NERDComSexyComments* |
|||
NERDComTodo NERD_commenter.txt /*NERDComTodo* |
|||
NERDComToggleComment NERD_commenter.txt /*NERDComToggleComment* |
|||
NERDComUncommentLine NERD_commenter.txt /*NERDComUncommentLine* |
|||
NERDComYankComment NERD_commenter.txt /*NERDComYankComment* |
|||
NERDCommentWholeLinesInVMode NERD_commenter.txt /*NERDCommentWholeLinesInVMode* |
|||
NERDCommenter NERD_commenter.txt /*NERDCommenter* |
|||
NERDCommenterContents NERD_commenter.txt /*NERDCommenterContents* |
|||
NERDCompactSexyComs NERD_commenter.txt /*NERDCompactSexyComs* |
|||
NERDDefaultNesting NERD_commenter.txt /*NERDDefaultNesting* |
|||
NERDLPlace NERD_commenter.txt /*NERDLPlace* |
|||
NERDMapleader NERD_commenter.txt /*NERDMapleader* |
|||
NERDMenuMode NERD_commenter.txt /*NERDMenuMode* |
|||
NERDRPlace NERD_commenter.txt /*NERDRPlace* |
|||
NERDRemoveAltComs NERD_commenter.txt /*NERDRemoveAltComs* |
|||
NERDRemoveExtraSpaces NERD_commenter.txt /*NERDRemoveExtraSpaces* |
|||
NERDShutUp NERD_commenter.txt /*NERDShutUp* |
|||
NERDSpaceDelims NERD_commenter.txt /*NERDSpaceDelims* |
|||
NERDUsePlaceHolders NERD_commenter.txt /*NERDUsePlaceHolders* |
|||
NERD_commenter.txt NERD_commenter.txt /*NERD_commenter.txt* |
|||
Tlist_Get_Tag_Prototype_By_Line() taglist.txt /*Tlist_Get_Tag_Prototype_By_Line()* |
|||
Tlist_Get_Tagname_By_Line() taglist.txt /*Tlist_Get_Tagname_By_Line()* |
|||
Tlist_Set_App() taglist.txt /*Tlist_Set_App()* |
|||
Tlist_Update_File_Tags() taglist.txt /*Tlist_Update_File_Tags()* |
|||
loaded_nerd_comments NERD_commenter.txt /*loaded_nerd_comments* |
|||
taglist-commands taglist.txt /*taglist-commands* |
|||
taglist-debug taglist.txt /*taglist-debug* |
|||
taglist-extend taglist.txt /*taglist-extend* |
|||
taglist-faq taglist.txt /*taglist-faq* |
|||
taglist-functions taglist.txt /*taglist-functions* |
|||
taglist-install taglist.txt /*taglist-install* |
|||
taglist-internet taglist.txt /*taglist-internet* |
|||
taglist-intro taglist.txt /*taglist-intro* |
|||
taglist-keys taglist.txt /*taglist-keys* |
|||
taglist-license taglist.txt /*taglist-license* |
|||
taglist-menu taglist.txt /*taglist-menu* |
|||
taglist-options taglist.txt /*taglist-options* |
|||
taglist-requirements taglist.txt /*taglist-requirements* |
|||
taglist-session taglist.txt /*taglist-session* |
|||
taglist-todo taglist.txt /*taglist-todo* |
|||
taglist-using taglist.txt /*taglist-using* |
|||
taglist.txt taglist.txt /*taglist.txt* |
File diff suppressed because it is too large
@ -0,0 +1,825 @@ |
|||
"============================================================================= |
|||
" Copyright: Copyright (C) 2001-2007 Jeff Lanzarotta |
|||
" Permission is hereby granted to use and distribute this code, |
|||
" with or without modifications, provided that this copyright |
|||
" notice is copied with it. Like anything else that's free, |
|||
" bufexplorer.vim is provided *as is* and comes with no |
|||
" warranty of any kind, either expressed or implied. In no |
|||
" event will the copyright holder be liable for any damages |
|||
" resulting from the use of this software. |
|||
" Name Of File: bufexplorer.vim |
|||
" Description: Buffer Explorer Vim Plugin |
|||
" Maintainer: Jeff Lanzarotta (delux256-vim at yahoo dot com) |
|||
" Last Changed: Friday, 21 December 2007 |
|||
" Version: See g:bufexplorer_version for version number. |
|||
" Usage: This file should reside in the plugin directory and be |
|||
" automatically sourced. |
|||
" |
|||
" You may use the default keymappings of |
|||
" |
|||
" <Leader>be - Opens BufExplorer |
|||
" |
|||
" Or you can use |
|||
" |
|||
" ":BufExplorer" - Opens BufExplorer |
|||
" |
|||
" For more help see supplied documentation. |
|||
" History: See supplied documentation. |
|||
"============================================================================= |
|||
|
|||
" Exit quickly if already running or when 'compatible' is set. {{{1 |
|||
if exists("g:bufexplorer_version") || &cp |
|||
finish |
|||
endif |
|||
"1}}} |
|||
|
|||
" Version number |
|||
let g:bufexplorer_version = "7.1.7" |
|||
|
|||
" Check for Vim version 700 or greater {{{1 |
|||
if v:version < 700 |
|||
echo "Sorry, bufexplorer ".g:bufexplorer_version."\nONLY runs with Vim 7.0 and greater." |
|||
finish |
|||
endif |
|||
|
|||
" Public Interface {{{1 |
|||
nmap <silent> <unique> <Leader>bx :BufExplorer<CR> |
|||
|
|||
" Create commands {{{1 |
|||
command BufExplorer :call StartBufExplorer(has ("gui") ? "drop" : "hide edit") |
|||
|
|||
" Set {{{1 |
|||
function s:Set(var, default) |
|||
if !exists(a:var) |
|||
if type(a:default) |
|||
exec "let" a:var "=" string(a:default) |
|||
else |
|||
exec "let" a:var "=" a:default |
|||
endif |
|||
|
|||
return 1 |
|||
endif |
|||
|
|||
return 0 |
|||
endfunction |
|||
|
|||
" Default values {{{1 |
|||
call s:Set("g:bufExplorerDefaultHelp", 1) " Show default help? |
|||
call s:Set("g:bufExplorerDetailedHelp", 0) " Show detailed help? |
|||
call s:Set("g:bufExplorerFindActive", 1) " When selecting an active buffer, take you to the window where it is active? |
|||
call s:Set("g:bufExplorerReverseSort", 0) " sort reverse? |
|||
call s:Set("g:bufExplorerShowDirectories", 1) " (Dir's are added by commands like ':e .') |
|||
call s:Set("g:bufExplorerShowRelativePath", 0) " Show listings with relative or absolute paths? |
|||
call s:Set("g:bufExplorerShowUnlisted", 0) " Show unlisted buffers? |
|||
call s:Set("g:bufExplorerSortBy", "mru") " Sorting methods are in s:sort_by: |
|||
call s:Set("g:bufExplorerSplitOutPathName", 1) " Split out path and file name? |
|||
|
|||
" Global variables {{{1 |
|||
let s:MRUList = [] |
|||
let s:running = 0 |
|||
let s:sort_by = ["number", "name", "fullpath", "mru", "extension"] |
|||
let s:tabSpace = [] |
|||
let s:types = {"fullname": ':p', "path": ':p:h', "relativename": ':~:.', "relativepath": ':~:.:h', "shortname": ':t'} |
|||
let s:originBuffer = 0 |
|||
|
|||
" Setup the autocommands that handle the MRUList and other stuff. {{{1 |
|||
autocmd VimEnter * call s:Setup() |
|||
|
|||
" Setup {{{1 |
|||
function s:Setup() |
|||
" Build initial MRUList. |
|||
let s:MRUList = range(1, bufnr('$')) |
|||
let s:tabSpace = [] |
|||
|
|||
" Now that the MRUList is created, add the other autocmds. |
|||
autocmd BufEnter,BufNew * call s:ActivateBuffer() |
|||
autocmd BufWipeOut * call s:DeactivateBuffer(1) |
|||
autocmd BufDelete * call s:DeactivateBuffer(0) |
|||
|
|||
autocmd BufWinEnter \[BufExplorer\] call s:Initialize() |
|||
autocmd BufWinLeave \[BufExplorer\] call s:Cleanup() |
|||
endfunction |
|||
|
|||
" ActivateBuffer {{{1 |
|||
function s:ActivateBuffer() |
|||
let b = bufnr("%") |
|||
let l = get(s:tabSpace, tabpagenr(), []) |
|||
|
|||
if empty(l) || index(l, b) == -1 |
|||
call add(l, b) |
|||
let s:tabSpace[tabpagenr()] = l |
|||
endif |
|||
|
|||
call s:MRUPush(b) |
|||
endfunction |
|||
|
|||
" DeactivateBuffer {{{1 |
|||
function s:DeactivateBuffer(remove) |
|||
"echom "afile:" expand("<afile>") |
|||
"echom "bufnr, afile:" bufnr(expand("<afile>")) |
|||
"echom "buffers:" string(tabpagebuflist()) |
|||
"echom "MRU before:" string(s:MRUList) |
|||
|
|||
if a:remove |
|||
call s:MRUPop(bufnr(expand("<afile>"))) |
|||
end |
|||
|
|||
"echom "MRU after:" string(s:MRUList) |
|||
endfunction |
|||
|
|||
" MRUPop {{{1 |
|||
function s:MRUPop(buf) |
|||
call filter(s:MRUList, 'v:val != '.a:buf) |
|||
endfunction |
|||
|
|||
" MRUPush {{{1 |
|||
function s:MRUPush(buf) |
|||
" Skip temporary buffer with buftype set. |
|||
" Don't add the BufExplorer window to the list. |
|||
if !empty(getbufvar(a:buf, "&buftype")) || |
|||
\ !buflisted(a:buf) || empty(bufname(a:buf)) || |
|||
\ fnamemodify(bufname(a:buf), ":t") == "[BufExplorer]" |
|||
return |
|||
end |
|||
|
|||
call s:MRUPop(a:buf) |
|||
call insert(s:MRUList,a:buf) |
|||
endfunction |
|||
|
|||
" Initialize {{{1 |
|||
function s:Initialize() |
|||
let s:_insertmode = &insertmode |
|||
set noinsertmode |
|||
|
|||
let s:_showcmd = &showcmd |
|||
set noshowcmd |
|||
|
|||
let s:_cpo = &cpo |
|||
set cpo&vim |
|||
|
|||
let s:_report = &report |
|||
let &report = 10000 |
|||
|
|||
let s:_list = &list |
|||
set nolist |
|||
|
|||
setlocal nonumber |
|||
setlocal foldcolumn=0 |
|||
setlocal nofoldenable |
|||
setlocal cursorline |
|||
setlocal nospell |
|||
|
|||
set nobuflisted |
|||
|
|||
let s:running = 1 |
|||
endfunction |
|||
|
|||
" Cleanup {{{1 |
|||
function s:Cleanup() |
|||
let &insertmode = s:_insertmode |
|||
let &showcmd = s:_showcmd |
|||
let &cpo = s:_cpo |
|||
let &report = s:_report |
|||
let &list = s:_list |
|||
let s:running = 0 |
|||
|
|||
delmarks! |
|||
endfunction |
|||
|
|||
" StartBufExplorer {{{1 |
|||
function StartBufExplorer(open) |
|||
let name = '[BufExplorer]' |
|||
|
|||
if !has("win32") |
|||
" On non-Windows boxes, escape the name so that is shows up correctly. |
|||
let name = escape(name, "[]") |
|||
endif |
|||
|
|||
" Make sure there is only one explorer open at a time. |
|||
if s:running == 1 |
|||
" Go to the open buffer. |
|||
if has("gui") |
|||
exec "drop" name |
|||
endif |
|||
|
|||
return |
|||
endif |
|||
|
|||
let s:originBuffer = bufnr("%") |
|||
silent let s:raw_buffer_listing = s:GetBufferInfo() |
|||
|
|||
let copy = copy(s:raw_buffer_listing) |
|||
|
|||
if (g:bufExplorerShowUnlisted == 0) |
|||
call filter(copy, 'v:val.attributes !~ "u"') |
|||
endif |
|||
|
|||
if (!empty(copy)) |
|||
call filter(copy, 'v:val.shortname !~ "\\\[No Name\\\]"') |
|||
endif |
|||
|
|||
if len(copy) <= 1 |
|||
echo "\r" |
|||
call s:Warn("Sorry, there are no more buffers to explore") |
|||
|
|||
return |
|||
endif |
|||
|
|||
if !exists("b:displayMode") || b:displayMode != "winmanager" |
|||
" Do not use keepalt when opening bufexplorer to allow the buffer that we |
|||
" are leaving to become the new alternate buffer |
|||
exec "silent keepjumps ".a:open." ".name |
|||
endif |
|||
|
|||
call s:DisplayBufferList() |
|||
endfunction |
|||
|
|||
" DisplayBufferList {{{1 |
|||
function s:DisplayBufferList() |
|||
setlocal bufhidden=delete |
|||
setlocal buftype=nofile |
|||
setlocal modifiable |
|||
setlocal noswapfile |
|||
setlocal nowrap |
|||
|
|||
call s:SetupSyntax() |
|||
call s:MapKeys() |
|||
call setline(1, s:CreateHelp()) |
|||
call s:BuildBufferList() |
|||
call cursor(s:firstBufferLine, 1) |
|||
|
|||
if !g:bufExplorerResize |
|||
normal! zz |
|||
endif |
|||
|
|||
setlocal nomodifiable |
|||
endfunction |
|||
|
|||
" MapKeys {{{1 |
|||
function s:MapKeys() |
|||
if exists("b:displayMode") && b:displayMode == "winmanager" |
|||
nnoremap <buffer> <silent> <tab> :call <SID>SelectBuffer()<cr> |
|||
endif |
|||
|
|||
nnoremap <buffer> <silent> <F1> :call <SID>ToggleHelp()<cr> |
|||
nnoremap <buffer> <silent> <2-leftmouse> :call <SID>SelectBuffer()<cr> |
|||
nnoremap <buffer> <silent> <cr> :call <SID>SelectBuffer()<cr> |
|||
nnoremap <buffer> <silent> t :call <SID>SelectBuffer("tab")<cr> |
|||
nnoremap <buffer> <silent> <s-cr> :call <SID>SelectBuffer("tab")<cr> |
|||
nnoremap <buffer> <silent> d :call <SID>RemoveBuffer("wipe")<cr> |
|||
nnoremap <buffer> <silent> D :call <SID>RemoveBuffer("delete")<cr> |
|||
nnoremap <buffer> <silent> m :call <SID>MRUListShow()<cr> |
|||
nnoremap <buffer> <silent> p :call <SID>ToggleSplitOutPathName()<cr> |
|||
nnoremap <buffer> <silent> q :call <SID>Close()<cr> |
|||
nnoremap <buffer> <silent> r :call <SID>SortReverse()<cr> |
|||
nnoremap <buffer> <silent> R :call <SID>ToggleShowRelativePath()<cr> |
|||
nnoremap <buffer> <silent> s :call <SID>SortSelect()<cr> |
|||
nnoremap <buffer> <silent> u :call <SID>ToggleShowUnlisted()<cr> |
|||
nnoremap <buffer> <silent> f :call <SID>ToggleFindActive()<cr> |
|||
|
|||
for k in ["G", "n", "N", "L", "M", "H"] |
|||
exec "nnoremap <buffer> <silent>" k ":keepjumps normal!" k."<cr>" |
|||
endfor |
|||
endfunction |
|||
|
|||
" SetupSyntax {{{1 |
|||
function s:SetupSyntax() |
|||
if has("syntax") |
|||
syn match bufExplorerHelp "^\".*" contains=bufExplorerSortBy,bufExplorerMapping,bufExplorerTitle,bufExplorerSortType,bufExplorerToggleSplit,bufExplorerToggleOpen |
|||
syn match bufExplorerOpenIn "Open in \w\+ window" contained |
|||
syn match bufExplorerSplit "\w\+ split" contained |
|||
syn match bufExplorerSortBy "Sorted by .*" contained contains=bufExplorerOpenIn,bufExplorerSplit |
|||
syn match bufExplorerMapping "\" \zs.\+\ze :" contained |
|||
syn match bufExplorerTitle "Buffer Explorer.*" contained |
|||
syn match bufExplorerSortType "'\w\{-}'" contained |
|||
syn match bufExplorerBufNbr /^\s*\d\+/ |
|||
syn match bufExplorerToggleSplit "toggle split type" contained |
|||
syn match bufExplorerToggleOpen "toggle open mode" contained |
|||
|
|||
syn match bufExplorerModBuf /^\s*\d\+.\{4}+.*/ |
|||
syn match bufExplorerLockedBuf /^\s*\d\+.\{3}[\-=].*/ |
|||
syn match bufExplorerHidBuf /^\s*\d\+.\{2}h.*/ |
|||
syn match bufExplorerActBuf /^\s*\d\+.\{2}a.*/ |
|||
syn match bufExplorerCurBuf /^\s*\d\+.%.*/ |
|||
syn match bufExplorerAltBuf /^\s*\d\+.#.*/ |
|||
syn match bufExplorerUnlBuf /^\s*\d\+u.*/ |
|||
|
|||
hi def link bufExplorerBufNbr Number |
|||
hi def link bufExplorerMapping NonText |
|||
hi def link bufExplorerHelp Special |
|||
hi def link bufExplorerOpenIn Identifier |
|||
hi def link bufExplorerSortBy String |
|||
hi def link bufExplorerSplit NonText |
|||
hi def link bufExplorerTitle NonText |
|||
hi def link bufExplorerSortType bufExplorerSortBy |
|||
hi def link bufExplorerToggleSplit bufExplorerSplit |
|||
hi def link bufExplorerToggleOpen bufExplorerOpenIn |
|||
|
|||
hi def link bufExplorerActBuf Identifier |
|||
hi def link bufExplorerAltBuf String |
|||
hi def link bufExplorerCurBuf Type |
|||
hi def link bufExplorerHidBuf Constant |
|||
hi def link bufExplorerLockedBuf Special |
|||
hi def link bufExplorerModBuf Exception |
|||
hi def link bufExplorerUnlBuf Comment |
|||
endif |
|||
endfunction |
|||
|
|||
" ToggleHelp {{{1 |
|||
function s:ToggleHelp() |
|||
let g:bufExplorerDetailedHelp = !g:bufExplorerDetailedHelp |
|||
|
|||
setlocal modifiable |
|||
|
|||
" Save position |
|||
normal! ma |
|||
|
|||
" Remove old header |
|||
if (s:firstBufferLine > 1) |
|||
exec "keepjumps 1,".(s:firstBufferLine - 1) "d _" |
|||
endif |
|||
|
|||
call append(0, s:CreateHelp()) |
|||
|
|||
silent! normal! g`a |
|||
delmarks a |
|||
|
|||
setlocal nomodifiable |
|||
|
|||
if exists("b:displayMode") && b:displayMode == "winmanager" |
|||
call WinManagerForceReSize("BufExplorer") |
|||
end |
|||
endfunction |
|||
|
|||
" GetHelpStatus {{{1 |
|||
function s:GetHelpStatus() |
|||
let ret = '" Sorted by '.((g:bufExplorerReverseSort == 1) ? "reverse " : "").g:bufExplorerSortBy |
|||
let ret .= ' | '.((g:bufExplorerFindActive == 0) ? "Don't " : "")."Locate buffer" |
|||
let ret .= ((g:bufExplorerShowUnlisted == 0) ? "" : " | Show unlisted") |
|||
let ret .= ' | '.((g:bufExplorerShowRelativePath == 0) ? "Absolute" : "Relative") |
|||
let ret .= ' '.((g:bufExplorerSplitOutPathName == 0) ? "Full" : "Split")." path" |
|||
|
|||
return ret |
|||
endfunction |
|||
|
|||
" CreateHelp {{{1 |
|||
function s:CreateHelp() |
|||
if g:bufExplorerDefaultHelp == 0 && g:bufExplorerDetailedHelp == 0 |
|||
let s:firstBufferLine = 1 |
|||
return [] |
|||
endif |
|||
|
|||
let header = [] |
|||
|
|||
if g:bufExplorerDetailedHelp == 1 |
|||
call add(header, '" Buffer Explorer ('.g:bufexplorer_version.')') |
|||
call add(header, '" --------------------------') |
|||
call add(header, '" <F1> : toggle this help') |
|||
call add(header, '" <enter> or Mouse-Double-Click : open buffer under cursor') |
|||
call add(header, '" <shift-enter> or t : open buffer in another tab') |
|||
call add(header, '" d : wipe buffer') |
|||
call add(header, '" D : delete buffer') |
|||
call add(header, '" p : toggle spliting of file and path name') |
|||
call add(header, '" q : quit') |
|||
call add(header, '" r : reverse sort') |
|||
call add(header, '" R : toggle showing relative or full paths') |
|||
call add(header, '" u : toggle showing unlisted buffers') |
|||
call add(header, '" s : select sort field '.string(s:sort_by).'') |
|||
call add(header, '" f : toggle find active buffer') |
|||
else |
|||
call add(header, '" Press <F1> for Help') |
|||
endif |
|||
|
|||
call add(header, s:GetHelpStatus()) |
|||
call add(header, '"=') |
|||
|
|||
let s:firstBufferLine = len(header) + 1 |
|||
|
|||
return header |
|||
endfunction |
|||
|
|||
" GetBufferInfo {{{1 |
|||
function s:GetBufferInfo() |
|||
redir => bufoutput |
|||
buffers! |
|||
redir END |
|||
|
|||
let [all, allwidths, listedwidths] = [[], {}, {}] |
|||
|
|||
for n in keys(s:types) |
|||
let allwidths[n] = [] |
|||
let listedwidths[n] = [] |
|||
endfor |
|||
|
|||
for buf in split(bufoutput, '\n') |
|||
let bits = split(buf, '"') |
|||
let b = {"attributes": bits[0], "line": substitute(bits[2], '\s*', '', '')} |
|||
|
|||
for [key, val] in items(s:types) |
|||
let b[key] = fnamemodify(bits[1], val) |
|||
endfor |
|||
|
|||
if getftype(b.fullname) == "dir" && g:bufExplorerShowDirectories == 1 |
|||
let b.shortname = "<DIRECTORY>" |
|||
end |
|||
|
|||
call add(all, b) |
|||
|
|||
for n in keys(s:types) |
|||
call add(allwidths[n], len(b[n])) |
|||
|
|||
if b.attributes !~ "u" |
|||
call add(listedwidths[n], len(b[n])) |
|||
endif |
|||
endfor |
|||
endfor |
|||
|
|||
let [s:allpads, s:listedpads] = [{}, {}] |
|||
|
|||
for n in keys(s:types) |
|||
let s:allpads[n] = repeat(' ', max(allwidths[n])) |
|||
let s:listedpads[n] = repeat(' ', max(listedwidths[n])) |
|||
endfor |
|||
|
|||
return all |
|||
endfunction |
|||
|
|||
" BuildBufferList {{{1 |
|||
function s:BuildBufferList() |
|||
let lines = [] |
|||
|
|||
" Loop through every buffer. |
|||
for buf in s:raw_buffer_listing |
|||
if (!g:bufExplorerShowUnlisted && buf.attributes =~ "u") |
|||
" skip unlisted buffers if we are not to show them |
|||
continue |
|||
endif |
|||
|
|||
let line = buf.attributes." " |
|||
|
|||
if g:bufExplorerSplitOutPathName |
|||
let type = (g:bufExplorerShowRelativePath) ? "relativepath" : "path" |
|||
let path = buf[type] |
|||
let pad = (g:bufExplorerShowUnlisted) ? s:allpads.shortname : s:listedpads.shortname |
|||
let line .= buf.shortname." ".strpart(pad.path, len(buf.shortname)) |
|||
else |
|||
let type = (g:bufExplorerShowRelativePath) ? "relativename" : "fullname" |
|||
let path = buf[type] |
|||
let line .= path |
|||
endif |
|||
|
|||
let pads = (g:bufExplorerShowUnlisted) ? s:allpads : s:listedpads |
|||
|
|||
if !empty(pads[type]) |
|||
let line .= strpart(pads[type], len(path))." " |
|||
endif |
|||
|
|||
let line .= buf.line |
|||
|
|||
call add(lines, line) |
|||
endfor |
|||
|
|||
call setline(s:firstBufferLine, lines) |
|||
|
|||
call s:SortListing() |
|||
endfunction |
|||
|
|||
" SelectBuffer {{{1 |
|||
function s:SelectBuffer(...) |
|||
" Sometimes messages are not cleared when we get here so it looks like an |
|||
" error has occurred when it really has not. |
|||
echo "" |
|||
|
|||
" Are we on a line with a file name? |
|||
if line('.') < s:firstBufferLine |
|||
exec "normal! \<cr>" |
|||
return |
|||
endif |
|||
|
|||
let _bufNbr = str2nr(getline('.')) |
|||
|
|||
if exists("b:displayMode") && b:displayMode == "winmanager" |
|||
let bufname = expand("#"._bufNbr.":p") |
|||
|
|||
call WinManagerFileEdit(bufname, 0) |
|||
|
|||
return |
|||
end |
|||
|
|||
if bufexists(_bufNbr) |
|||
if bufnr("#") == _bufNbr |
|||
return s:Close() |
|||
endif |
|||
|
|||
if (a:0 == 1) && (a:1 == "tab") |
|||
" Restore [BufExplorer] buffer. |
|||
exec "keepjumps silent buffer!".s:originBuffer |
|||
|
|||
let tabNbr = s:GetTabNbr(_bufNbr) |
|||
|
|||
if tabNbr == 0 |
|||
" _bufNbr is not opened in any tabs |
|||
exec "999tab split +buffer" . _bufNbr |
|||
else |
|||
" _bufNbr is already opened in tab(s) |
|||
exec tabNbr . "tabnext" |
|||
" Focus window. |
|||
exec s:GetWinNbr(tabNbr, _bufNbr) . "wincmd w" |
|||
endif |
|||
else |
|||
" If the buf is active, then go to the tab where it is opened. |
|||
if bufloaded(_bufNbr) && g:bufExplorerFindActive |
|||
call s:Close() |
|||
let bufname = expand("#"._bufNbr.":p") |
|||
exec bufname ? "drop ".escape(bufname, " ") : "buffer "._bufNbr |
|||
endif |
|||
|
|||
" Switch to the buffer. |
|||
exec "keepalt keepjumps silent b!" _bufNbr |
|||
endif |
|||
|
|||
" Make the buffer 'listed' again. |
|||
call setbufvar(_bufNbr, "&buflisted", "1") |
|||
else |
|||
call s:Error("Sorry, that buffer no longer exists, please select another") |
|||
call s:DeleteBuffer(_bufNbr, "wipe") |
|||
endif |
|||
endfunction |
|||
|
|||
" RemoveBuffer {{{1 |
|||
function s:RemoveBuffer(mode) |
|||
" Are we on a line with a file name? |
|||
if line('.') < s:firstBufferLine |
|||
return |
|||
endif |
|||
|
|||
" Do not allow this buffer to be deleted if it is the last one. |
|||
if len(s:MRUList) == 1 |
|||
call s:Error("Sorry, you are not allowed to delete the last buffer") |
|||
return |
|||
endif |
|||
|
|||
" These commands are to temporarily suspend the activity of winmanager. |
|||
if exists("b:displayMode") && b:displayMode == "winmanager" |
|||
call WinManagerSuspendAUs() |
|||
end |
|||
|
|||
let _bufNbr = str2nr(getline('.')) |
|||
|
|||
if getbufvar(_bufNbr, '&modified') == 1 |
|||
call s:Error("Sorry, no write since last change for buffer "._bufNbr.", unable to delete") |
|||
return |
|||
else |
|||
" Okay, everything is good, delete or wipe the buffer. |
|||
call s:DeleteBuffer(_bufNbr, a:mode) |
|||
endif |
|||
|
|||
" Reactivate winmanager autocommand activity. |
|||
if exists("b:displayMode") && b:displayMode == "winmanager" |
|||
call WinManagerForceReSize("BufExplorer") |
|||
call WinManagerResumeAUs() |
|||
end |
|||
endfunction |
|||
|
|||
" DeleteBuffer {{{1 |
|||
function s:DeleteBuffer(buf, mode) |
|||
" This routine assumes that the buffer to be removed is on the current line. |
|||
try |
|||
if a:mode == "wipe" |
|||
exe "silent bw" a:buf |
|||
else |
|||
exe "silent bd" a:buf |
|||
end |
|||
|
|||
setlocal modifiable |
|||
normal! "_dd |
|||
setlocal nomodifiable |
|||
|
|||
" Delete the buffer from the raw buffer list. |
|||
call filter(s:raw_buffer_listing, 'v:val.attributes !~ " '.a:buf.' "') |
|||
catch |
|||
call s:Error(v:exception) |
|||
endtry |
|||
endfunction |
|||
|
|||
" Close {{{1 |
|||
function s:Close() |
|||
" Get only the listed buffers. |
|||
let listed = filter(copy(s:MRUList), "buflisted(v:val)") |
|||
|
|||
for b in reverse(listed[0:1]) |
|||
exec "keepjumps silent b ".b |
|||
endfor |
|||
endfunction |
|||
|
|||
" ToggleSplitOutPathName {{{1 |
|||
function s:ToggleSplitOutPathName() |
|||
let g:bufExplorerSplitOutPathName = !g:bufExplorerSplitOutPathName |
|||
call s:RebuildBufferList() |
|||
call s:UpdateHelpStatus() |
|||
endfunction |
|||
|
|||
" ToggleShowRelativePath {{{1 |
|||
function s:ToggleShowRelativePath() |
|||
let g:bufExplorerShowRelativePath = !g:bufExplorerShowRelativePath |
|||
call s:RebuildBufferList() |
|||
call s:UpdateHelpStatus() |
|||
endfunction |
|||
|
|||
" ToggleShowUnlisted {{{1 |
|||
function s:ToggleShowUnlisted() |
|||
let g:bufExplorerShowUnlisted = !g:bufExplorerShowUnlisted |
|||
let num_bufs = s:RebuildBufferList(g:bufExplorerShowUnlisted == 0) |
|||
call s:UpdateHelpStatus() |
|||
endfunction |
|||
|
|||
" ToggleFindActive {{{1 |
|||
function s:ToggleFindActive() |
|||
let g:bufExplorerFindActive = !g:bufExplorerFindActive |
|||
call s:UpdateHelpStatus() |
|||
endfunction |
|||
|
|||
" RebuildBufferList {{{1 |
|||
function s:RebuildBufferList(...) |
|||
setlocal modifiable |
|||
|
|||
let curPos = getpos('.') |
|||
|
|||
if a:0 |
|||
" Clear the list first. |
|||
exec "keepjumps ".s:firstBufferLine.',$d "_' |
|||
endif |
|||
|
|||
let num_bufs = s:BuildBufferList() |
|||
|
|||
call setpos('.', curPos) |
|||
|
|||
setlocal nomodifiable |
|||
|
|||
return num_bufs |
|||
endfunction |
|||
|
|||
" UpdateHelpStatus {{{1 |
|||
function s:UpdateHelpStatus() |
|||
setlocal modifiable |
|||
|
|||
let text = s:GetHelpStatus() |
|||
call setline(s:firstBufferLine - 2, text) |
|||
|
|||
setlocal nomodifiable |
|||
endfunction |
|||
|
|||
" MRUCmp {{{1 |
|||
function s:MRUCmp(line1, line2) |
|||
return index(s:MRUList, str2nr(a:line1)) - index(s:MRUList, str2nr(a:line2)) |
|||
endfunction |
|||
|
|||
" SortReverse {{{1 |
|||
function s:SortReverse() |
|||
let g:bufExplorerReverseSort = !g:bufExplorerReverseSort |
|||
|
|||
call s:ReSortListing() |
|||
endfunction |
|||
|
|||
" SortSelect {{{1 |
|||
function s:SortSelect() |
|||
let g:bufExplorerSortBy = get(s:sort_by, index(s:sort_by, g:bufExplorerSortBy)+1, s:sort_by[0]) |
|||
|
|||
call s:ReSortListing() |
|||
endfunction |
|||
|
|||
" ReSortListing {{{1 |
|||
function s:ReSortListing() |
|||
setlocal modifiable |
|||
|
|||
let curPos = getpos('.') |
|||
|
|||
call s:SortListing() |
|||
call s:UpdateHelpStatus() |
|||
|
|||
call setpos('.', curPos) |
|||
|
|||
setlocal nomodifiable |
|||
endfunction |
|||
|
|||
" SortListing {{{1 |
|||
function s:SortListing() |
|||
let sort = s:firstBufferLine.",$sort".((g:bufExplorerReverseSort == 1) ? "!": "") |
|||
|
|||
if g:bufExplorerSortBy == "number" |
|||
" Easiest case. |
|||
exec sort 'n' |
|||
elseif g:bufExplorerSortBy == "name" |
|||
if g:bufExplorerSplitOutPathName |
|||
exec sort 'ir /\d.\{7}\zs\f\+\ze/' |
|||
else |
|||
exec sort 'ir /\zs[^\/\\]\+\ze\s*line/' |
|||
endif |
|||
elseif g:bufExplorerSortBy == "fullpath" |
|||
if g:bufExplorerSplitOutPathName |
|||
" Sort twice - first on the file name then on the path. |
|||
exec sort 'ir /\d.\{7}\zs\f\+\ze/' |
|||
endif |
|||
|
|||
exec sort 'ir /\zs\f\+\ze\s\+line/' |
|||
elseif g:bufExplorerSortBy == "extension" |
|||
exec sort 'ir /\.\zs\w\+\ze\s/' |
|||
elseif g:bufExplorerSortBy == "mru" |
|||
let l = getline(s:firstBufferLine, "$") |
|||
|
|||
call sort(l, "<SID>MRUCmp") |
|||
|
|||
if g:bufExplorerReverseSort |
|||
call reverse(l) |
|||
endif |
|||
|
|||
call setline(s:firstBufferLine, l) |
|||
endif |
|||
endfunction |
|||
|
|||
" MRUListShow {{{1 |
|||
function s:MRUListShow() |
|||
echomsg "MRUList=".string(s:MRUList) |
|||
endfunction |
|||
|
|||
" Error {{{1 |
|||
function s:Error(msg) |
|||
echohl ErrorMsg | echo a:msg | echohl none |
|||
endfunction |
|||
|
|||
" Warn {{{1 |
|||
function s:Warn(msg) |
|||
echohl WarningMsg | echo a:msg | echohl none |
|||
endfunction |
|||
|
|||
" GetTabNbr {{{1 |
|||
function s:GetTabNbr(bufNbr) |
|||
" Searching buffer bufno, in tabs. |
|||
for i in range(tabpagenr("$")) |
|||
if index(tabpagebuflist(i + 1), a:bufNbr) != -1 |
|||
return i + 1 |
|||
endif |
|||
endfor |
|||
|
|||
return 0 |
|||
endfunction |
|||
|
|||
" GetWinNbr" {{{1 |
|||
function s:GetWinNbr(tabNbr, bufNbr) |
|||
" window number in tabpage. |
|||
return index(tabpagebuflist(a:tabNbr), a:bufNbr) + 1 |
|||
endfunction |
|||
|
|||
" Winmanager Integration {{{1 |
|||
let g:BufExplorer_title = "\[Buf\ List\]" |
|||
call s:Set("g:bufExplorerResize", 1) |
|||
call s:Set("g:bufExplorerMaxHeight", 25) " Handles dynamic resizing of the window. |
|||
|
|||
" Function to start display. Set the mode to 'winmanager' for this buffer. |
|||
" This is to figure out how this plugin was called. In a standalone fashion |
|||
" or by winmanager. |
|||
function BufExplorer_Start() |
|||
let b:displayMode = "winmanager" |
|||
call StartBufExplorer("e") |
|||
endfunction |
|||
|
|||
" Returns whether the display is okay or not. |
|||
function BufExplorer_IsValid() |
|||
return 0 |
|||
endfunction |
|||
|
|||
" Handles dynamic refreshing of the window. |
|||
function BufExplorer_Refresh() |
|||
let b:displayMode = "winmanager" |
|||
call StartBufExplorer("e") |
|||
endfunction |
|||
|
|||
function BufExplorer_ReSize() |
|||
if !g:bufExplorerResize |
|||
return |
|||
end |
|||
|
|||
let nlines = min([line("$"), g:bufExplorerMaxHeight]) |
|||
|
|||
exe nlines." wincmd _" |
|||
|
|||
" The following lines restore the layout so that the last file line is also |
|||
" the last window line. Sometimes, when a line is deleted, although the |
|||
" window size is exactly equal to the number of lines in the file, some of |
|||
" the lines are pushed up and we see some lagging '~'s. |
|||
let pres = getpos(".") |
|||
|
|||
exe $ |
|||
|
|||
let _scr = &scrolloff |
|||
let &scrolloff = 0 |
|||
|
|||
normal! z- |
|||
|
|||
let &scrolloff = _scr |
|||
|
|||
call setpos(".", pres) |
|||
endfunction |
|||
"}}}1 |
|||
|
|||
" vim:ft=vim foldmethod=marker sw=2 |
@ -0,0 +1 @@ |
|||
au BufNewFile,BufRead *.t set filetype=perl |
@ -0,0 +1,812 @@ |
|||
" matchit.vim: (global plugin) Extended "%" matching |
|||
" Last Change: Fri Jan 25 10:00 AM 2008 EST |
|||
" Maintainer: Benji Fisher PhD <benji@member.AMS.org> |
|||
" Version: 1.13.2, for Vim 6.3+ |
|||
" URL: http://www.vim.org/script.php?script_id=39 |
|||
|
|||
" Documentation: |
|||
" The documentation is in a separate file, matchit.txt . |
|||
|
|||
" Credits: |
|||
" Vim editor by Bram Moolenaar (Thanks, Bram!) |
|||
" Original script and design by Raul Segura Acevedo |
|||
" Support for comments by Douglas Potts |
|||
" Support for back references and other improvements by Benji Fisher |
|||
" Support for many languages by Johannes Zellner |
|||
" Suggestions for improvement, bug reports, and support for additional |
|||
" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark |
|||
" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner. |
|||
|
|||
" Debugging: |
|||
" If you'd like to try the built-in debugging commands... |
|||
" :MatchDebug to activate debugging for the current buffer |
|||
" This saves the values of several key script variables as buffer-local |
|||
" variables. See the MatchDebug() function, below, for details. |
|||
|
|||
" TODO: I should think about multi-line patterns for b:match_words. |
|||
" This would require an option: how many lines to scan (default 1). |
|||
" This would be useful for Python, maybe also for *ML. |
|||
" TODO: Maybe I should add a menu so that people will actually use some of |
|||
" the features that I have implemented. |
|||
" TODO: Eliminate the MultiMatch function. Add yet another argument to |
|||
" Match_wrapper() instead. |
|||
" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' |
|||
" TODO: Make backrefs safer by using '\V' (very no-magic). |
|||
" TODO: Add a level of indirection, so that custom % scripts can use my |
|||
" work but extend it. |
|||
|
|||
" allow user to prevent loading |
|||
" and prevent duplicate loading |
|||
if exists("loaded_matchit") || &cp |
|||
finish |
|||
endif |
|||
let loaded_matchit = 1 |
|||
let s:last_mps = "" |
|||
let s:last_words = ":" |
|||
|
|||
let s:save_cpo = &cpo |
|||
set cpo&vim |
|||
|
|||
nnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'n') <CR> |
|||
nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR> |
|||
vnoremap <silent> % :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv`` |
|||
vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv`` |
|||
onoremap <silent> % v:<C-U>call <SID>Match_wrapper('',1,'o') <CR> |
|||
onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR> |
|||
|
|||
" Analogues of [{ and ]} using matching patterns: |
|||
nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR> |
|||
nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "n") <CR> |
|||
vmap [% <Esc>[%m'gv`` |
|||
vmap ]% <Esc>]%m'gv`` |
|||
" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv`` |
|||
" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W", "v") <CR>m'gv`` |
|||
onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR> |
|||
onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W", "o") <CR> |
|||
|
|||
" text object: |
|||
vmap a% <Esc>[%v]% |
|||
|
|||
" Auto-complete mappings: (not yet "ready for prime time") |
|||
" TODO Read :help write-plugin for the "right" way to let the user |
|||
" specify a key binding. |
|||
" let g:match_auto = '<C-]>' |
|||
" let g:match_autoCR = '<C-CR>' |
|||
" if exists("g:match_auto") |
|||
" execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls' |
|||
" endif |
|||
" if exists("g:match_autoCR") |
|||
" execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>' |
|||
" endif |
|||
" if exists("g:match_gthhoh") |
|||
" execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>' |
|||
" endif " gthhoh = "Get the heck out of here!" |
|||
|
|||
let s:notslash = '\\\@<!\%(\\\\\)*' |
|||
|
|||
function! s:Match_wrapper(word, forward, mode) range |
|||
" In s:CleanUp(), :execute "set" restore_options . |
|||
let restore_options = (&ic ? " " : " no") . "ignorecase" |
|||
if exists("b:match_ignorecase") |
|||
let &ignorecase = b:match_ignorecase |
|||
endif |
|||
let restore_options = " ve=" . &ve . restore_options |
|||
set ve= |
|||
" If this function was called from Visual mode, make sure that the cursor |
|||
" is at the correct end of the Visual range: |
|||
if a:mode == "v" |
|||
execute "normal! gv\<Esc>" |
|||
endif |
|||
" In s:CleanUp(), we may need to check whether the cursor moved forward. |
|||
let startline = line(".") |
|||
let startcol = col(".") |
|||
" Use default behavior if called with a count. |
|||
if v:count |
|||
exe "normal! " . v:count . "%" |
|||
return s:CleanUp(restore_options, a:mode, startline, startcol) |
|||
end |
|||
|
|||
" First step: if not already done, set the script variables |
|||
" s:do_BR flag for whether there are backrefs |
|||
" s:pat parsed version of b:match_words |
|||
" s:all regexp based on s:pat and the default groups |
|||
" |
|||
if !exists("b:match_words") || b:match_words == "" |
|||
let match_words = "" |
|||
" Allow b:match_words = "GetVimMatchWords()" . |
|||
elseif b:match_words =~ ":" |
|||
let match_words = b:match_words |
|||
else |
|||
execute "let match_words =" b:match_words |
|||
endif |
|||
" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion! |
|||
if (match_words != s:last_words) || (&mps != s:last_mps) || |
|||
\ exists("b:match_debug") |
|||
let s:last_words = match_words |
|||
let s:last_mps = &mps |
|||
" The next several lines were here before |
|||
" BF started messing with this script. |
|||
" quote the special chars in 'matchpairs', replace [,:] with \| and then |
|||
" append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif) |
|||
" let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+', |
|||
" \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>' |
|||
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . |
|||
\ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' |
|||
" s:all = pattern with all the keywords |
|||
let match_words = match_words . (strlen(match_words) ? "," : "") . default |
|||
if match_words !~ s:notslash . '\\\d' |
|||
let s:do_BR = 0 |
|||
let s:pat = match_words |
|||
else |
|||
let s:do_BR = 1 |
|||
let s:pat = s:ParseWords(match_words) |
|||
endif |
|||
let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g') |
|||
let s:all = '\%(' . s:all . '\)' |
|||
" let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)' |
|||
if exists("b:match_debug") |
|||
let b:match_pat = s:pat |
|||
endif |
|||
endif |
|||
|
|||
" Second step: set the following local variables: |
|||
" matchline = line on which the cursor started |
|||
" curcol = number of characters before match |
|||
" prefix = regexp for start of line to start of match |
|||
" suffix = regexp for end of match to end of line |
|||
" Require match to end on or after the cursor and prefer it to |
|||
" start on or before the cursor. |
|||
let matchline = getline(startline) |
|||
if a:word != '' |
|||
" word given |
|||
if a:word !~ s:all |
|||
echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE |
|||
return s:CleanUp(restore_options, a:mode, startline, startcol) |
|||
endif |
|||
let matchline = a:word |
|||
let curcol = 0 |
|||
let prefix = '^\%(' |
|||
let suffix = '\)$' |
|||
" Now the case when "word" is not given |
|||
else " Find the match that ends on or after the cursor and set curcol. |
|||
let regexp = s:Wholematch(matchline, s:all, startcol-1) |
|||
let curcol = match(matchline, regexp) |
|||
" If there is no match, give up. |
|||
if curcol == -1 |
|||
return s:CleanUp(restore_options, a:mode, startline, startcol) |
|||
endif |
|||
let endcol = matchend(matchline, regexp) |
|||
let suf = strlen(matchline) - endcol |
|||
let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(') |
|||
let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$') |
|||
endif |
|||
if exists("b:match_debug") |
|||
let b:match_match = matchstr(matchline, regexp) |
|||
let b:match_col = curcol+1 |
|||
endif |
|||
|
|||
" Third step: Find the group and single word that match, and the original |
|||
" (backref) versions of these. Then, resolve the backrefs. |
|||
" Set the following local variable: |
|||
" group = colon-separated list of patterns, one of which matches |
|||
" = ini:mid:fin or ini:fin |
|||
" |
|||
" Reconstruct the version with unresolved backrefs. |
|||
let patBR = substitute(match_words.',', |
|||
\ s:notslash.'\zs[,:]*,[,:]*', ',', 'g') |
|||
let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g') |
|||
" Now, set group and groupBR to the matching group: 'if:endif' or |
|||
" 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns |
|||
" group . "," . groupBR, and we pick it apart. |
|||
let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) |
|||
let i = matchend(group, s:notslash . ",") |
|||
let groupBR = strpart(group, i) |
|||
let group = strpart(group, 0, i-1) |
|||
" Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix |
|||
if s:do_BR " Do the hard part: resolve those backrefs! |
|||
let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) |
|||
endif |
|||
if exists("b:match_debug") |
|||
let b:match_wholeBR = groupBR |
|||
let i = matchend(groupBR, s:notslash . ":") |
|||
let b:match_iniBR = strpart(groupBR, 0, i-1) |
|||
endif |
|||
|
|||
" Fourth step: Set the arguments for searchpair(). |
|||
let i = matchend(group, s:notslash . ":") |
|||
let j = matchend(group, '.*' . s:notslash . ":") |
|||
let ini = strpart(group, 0, i-1) |
|||
let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g') |
|||
let fin = strpart(group, j) |
|||
"Un-escape the remaining , and : characters. |
|||
let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') |
|||
let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') |
|||
let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g') |
|||
" searchpair() requires that these patterns avoid \(\) groups. |
|||
let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g') |
|||
let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g') |
|||
let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g') |
|||
" Set mid. This is optimized for readability, not micro-efficiency! |
|||
if a:forward && matchline =~ prefix . fin . suffix |
|||
\ || !a:forward && matchline =~ prefix . ini . suffix |
|||
let mid = "" |
|||
endif |
|||
" Set flag. This is optimized for readability, not micro-efficiency! |
|||
if a:forward && matchline =~ prefix . fin . suffix |
|||
\ || !a:forward && matchline !~ prefix . ini . suffix |
|||
let flag = "bW" |
|||
else |
|||
let flag = "W" |
|||
endif |
|||
" Set skip. |
|||
if exists("b:match_skip") |
|||
let skip = b:match_skip |
|||
elseif exists("b:match_comment") " backwards compatibility and testing! |
|||
let skip = "r:" . b:match_comment |
|||
else |
|||
let skip = 's:comment\|string' |
|||
endif |
|||
let skip = s:ParseSkip(skip) |
|||
if exists("b:match_debug") |
|||
let b:match_ini = ini |
|||
let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin |
|||
endif |
|||
|
|||
" Fifth step: actually start moving the cursor and call searchpair(). |
|||
" Later, :execute restore_cursor to get to the original screen. |
|||
let restore_cursor = virtcol(".") . "|" |
|||
normal! g0 |
|||
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor |
|||
normal! H |
|||
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor |
|||
execute restore_cursor |
|||
call cursor(0, curcol + 1) |
|||
" normal! 0 |
|||
" if curcol |
|||
" execute "normal!" . curcol . "l" |
|||
" endif |
|||
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) |
|||
let skip = "0" |
|||
else |
|||
execute "if " . skip . "| let skip = '0' | endif" |
|||
endif |
|||
let sp_return = searchpair(ini, mid, fin, flag, skip) |
|||
let final_position = "call cursor(" . line(".") . "," . col(".") . ")" |
|||
" Restore cursor position and original screen. |
|||
execute restore_cursor |
|||
normal! m' |
|||
if sp_return > 0 |
|||
execute final_position |
|||
endif |
|||
return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin) |
|||
endfun |
|||
|
|||
" Restore options and do some special handling for Operator-pending mode. |
|||
" The optional argument is the tail of the matching group. |
|||
fun! s:CleanUp(options, mode, startline, startcol, ...) |
|||
execute "set" a:options |
|||
" Open folds, if appropriate. |
|||
if a:mode != "o" |
|||
if &foldopen =~ "percent" |
|||
normal! zv |
|||
endif |
|||
" In Operator-pending mode, we want to include the whole match |
|||
" (for example, d%). |
|||
" This is only a problem if we end up moving in the forward direction. |
|||
elseif (a:startline < line(".")) || |
|||
\ (a:startline == line(".") && a:startcol < col(".")) |
|||
if a:0 |
|||
" Check whether the match is a single character. If not, move to the |
|||
" end of the match. |
|||
let matchline = getline(".") |
|||
let currcol = col(".") |
|||
let regexp = s:Wholematch(matchline, a:1, currcol-1) |
|||
let endcol = matchend(matchline, regexp) |
|||
if endcol > currcol " This is NOT off by one! |
|||
execute "normal!" . (endcol - currcol) . "l" |
|||
endif |
|||
endif " a:0 |
|||
endif " a:mode != "o" && etc. |
|||
return 0 |
|||
endfun |
|||
|
|||
" Example (simplified HTML patterns): if |
|||
" a:groupBR = '<\(\k\+\)>:</\1>' |
|||
" a:prefix = '^.\{3}\(' |
|||
" a:group = '<\(\k\+\)>:</\(\k\+\)>' |
|||
" a:suffix = '\).\{2}$' |
|||
" a:matchline = "123<tag>12" or "123</tag>12" |
|||
" then extract "tag" from a:matchline and return "<tag>:</tag>" . |
|||
fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline) |
|||
if a:matchline !~ a:prefix . |
|||
\ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix |
|||
return a:group |
|||
endif |
|||
let i = matchend(a:groupBR, s:notslash . ':') |
|||
let ini = strpart(a:groupBR, 0, i-1) |
|||
let tailBR = strpart(a:groupBR, i) |
|||
let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix, |
|||
\ a:groupBR) |
|||
let i = matchend(word, s:notslash . ":") |
|||
let wordBR = strpart(word, i) |
|||
let word = strpart(word, 0, i-1) |
|||
" Now, a:matchline =~ a:prefix . word . a:suffix |
|||
if wordBR != ini |
|||
let table = s:Resolve(ini, wordBR, "table") |
|||
else |
|||
" let table = "----------" |
|||
let table = "" |
|||
let d = 0 |
|||
while d < 10 |
|||
if tailBR =~ s:notslash . '\\' . d |
|||
" let table[d] = d |
|||
let table = table . d |
|||
else |
|||
let table = table . "-" |
|||
endif |
|||
let d = d + 1 |
|||
endwhile |
|||
endif |
|||
let d = 9 |
|||
while d |
|||
if table[d] != "-" |
|||
let backref = substitute(a:matchline, a:prefix.word.a:suffix, |
|||
\ '\'.table[d], "") |
|||
" Are there any other characters that should be escaped? |
|||
let backref = escape(backref, '*,:') |
|||
execute s:Ref(ini, d, "start", "len") |
|||
let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len) |
|||
let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d, |
|||
\ escape(backref, '\\'), 'g') |
|||
endif |
|||
let d = d-1 |
|||
endwhile |
|||
if exists("b:match_debug") |
|||
if s:do_BR |
|||
let b:match_table = table |
|||
let b:match_word = word |
|||
else |
|||
let b:match_table = "" |
|||
let b:match_word = "" |
|||
endif |
|||
endif |
|||
return ini . ":" . tailBR |
|||
endfun |
|||
|
|||
" Input a comma-separated list of groups with backrefs, such as |
|||
" a:groups = '\(foo\):end\1,\(bar\):end\1' |
|||
" and return a comma-separated list of groups with backrefs replaced: |
|||
" return '\(foo\):end\(foo\),\(bar\):end\(bar\)' |
|||
fun! s:ParseWords(groups) |
|||
let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g') |
|||
let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g') |
|||
let parsed = "" |
|||
while groups =~ '[^,:]' |
|||
let i = matchend(groups, s:notslash . ':') |
|||
let j = matchend(groups, s:notslash . ',') |
|||
let ini = strpart(groups, 0, i-1) |
|||
let tail = strpart(groups, i, j-i-1) . ":" |
|||
let groups = strpart(groups, j) |
|||
let parsed = parsed . ini |
|||
let i = matchend(tail, s:notslash . ':') |
|||
while i != -1 |
|||
" In 'if:else:endif', ini='if' and word='else' and then word='endif'. |
|||
let word = strpart(tail, 0, i-1) |
|||
let tail = strpart(tail, i) |
|||
let i = matchend(tail, s:notslash . ':') |
|||
let parsed = parsed . ":" . s:Resolve(ini, word, "word") |
|||
endwhile " Now, tail has been used up. |
|||
let parsed = parsed . "," |
|||
endwhile " groups =~ '[^,:]' |
|||
let parsed = substitute(parsed, ',$', '', '') |
|||
return parsed |
|||
endfun |
|||
|
|||
" TODO I think this can be simplified and/or made more efficient. |
|||
" TODO What should I do if a:start is out of range? |
|||
" Return a regexp that matches all of a:string, such that |
|||
" matchstr(a:string, regexp) represents the match for a:pat that starts |
|||
" as close to a:start as possible, before being preferred to after, and |
|||
" ends after a:start . |
|||
" Usage: |
|||
" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1) |
|||
" let i = match(getline("."), regexp) |
|||
" let j = matchend(getline("."), regexp) |
|||
" let match = matchstr(getline("."), regexp) |
|||
fun! s:Wholematch(string, pat, start) |
|||
let group = '\%(' . a:pat . '\)' |
|||
let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^') |
|||
let len = strlen(a:string) |
|||
let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$') |
|||
if a:string !~ prefix . group . suffix |
|||
let prefix = '' |
|||
endif |
|||
return prefix . group . suffix |
|||
endfun |
|||
|
|||
" No extra arguments: s:Ref(string, d) will |
|||
" find the d'th occurrence of '\(' and return it, along with everything up |
|||
" to and including the matching '\)'. |
|||
" One argument: s:Ref(string, d, "start") returns the index of the start |
|||
" of the d'th '\(' and any other argument returns the length of the group. |
|||
" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be |
|||
" executed, having the effect of |
|||
" :let foo = s:Ref(string, d, "start") |
|||
" :let bar = s:Ref(string, d, "len") |
|||
fun! s:Ref(string, d, ...) |
|||
let len = strlen(a:string) |
|||
if a:d == 0 |
|||
let start = 0 |
|||
else |
|||
let cnt = a:d |
|||
let match = a:string |
|||
while cnt |
|||
let cnt = cnt - 1 |
|||
let index = matchend(match, s:notslash . '\\(') |
|||
if index == -1 |
|||
return "" |
|||
endif |
|||
let match = strpart(match, index) |
|||
endwhile |
|||
let start = len - strlen(match) |
|||
if a:0 == 1 && a:1 == "start" |
|||
return start - 2 |
|||
endif |
|||
let cnt = 1 |
|||
while cnt |
|||
let index = matchend(match, s:notslash . '\\(\|\\)') - 1 |
|||
if index == -2 |
|||
return "" |
|||
endif |
|||
" Increment if an open, decrement if a ')': |
|||
let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')' |
|||
" let cnt = stridx('0(', match[index]) + cnt |
|||
let match = strpart(match, index+1) |
|||
endwhile |
|||
let start = start - 2 |
|||
let len = len - start - strlen(match) |
|||
endif |
|||
if a:0 == 1 |
|||
return len |
|||
elseif a:0 == 2 |
|||
return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len |
|||
else |
|||
return strpart(a:string, start, len) |
|||
endif |
|||
endfun |
|||
|
|||
" Count the number of disjoint copies of pattern in string. |
|||
" If the pattern is a literal string and contains no '0' or '1' characters |
|||
" then s:Count(string, pattern, '0', '1') should be faster than |
|||
" s:Count(string, pattern). |
|||
fun! s:Count(string, pattern, ...) |
|||
let pat = escape(a:pattern, '\\') |
|||
if a:0 > 1 |
|||
let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g") |
|||
let foo = substitute(a:string, pat, a:2, "g") |
|||
let foo = substitute(foo, '[^' . a:2 . ']', "", "g") |
|||
return strlen(foo) |
|||
endif |
|||
let result = 0 |
|||
let foo = a:string |
|||
let index = matchend(foo, pat) |
|||
while index != -1 |
|||
let result = result + 1 |
|||
let foo = strpart(foo, index) |
|||
let index = matchend(foo, pat) |
|||
endwhile |
|||
return result |
|||
endfun |
|||
|
|||
" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where |
|||
" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first |
|||
" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this |
|||
" indicates that all other instances of '\1' in target are to be replaced |
|||
" by '\3'. The hard part is dealing with nesting... |
|||
" Note that ":" is an illegal character for source and target, |
|||
" unless it is preceded by "\". |
|||
fun! s:Resolve(source, target, output) |
|||
let word = a:target |
|||
let i = matchend(word, s:notslash . '\\\d') - 1 |
|||
let table = "----------" |
|||
while i != -2 " There are back references to be replaced. |
|||
let d = word[i] |
|||
let backref = s:Ref(a:source, d) |
|||
" The idea is to replace '\d' with backref. Before we do this, |
|||
" replace any \(\) groups in backref with :1, :2, ... if they |
|||
" correspond to the first, second, ... group already inserted |
|||
" into backref. Later, replace :1 with \1 and so on. The group |
|||
" number w+b within backref corresponds to the group number |
|||
" s within a:source. |
|||
" w = number of '\(' in word before the current one |
|||
let w = s:Count( |
|||
\ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1') |
|||
let b = 1 " number of the current '\(' in backref |
|||
let s = d " number of the current '\(' in a:source |
|||
while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1') |
|||
\ && s < 10 |
|||
if table[s] == "-" |
|||
if w + b < 10 |
|||
" let table[s] = w + b |
|||
let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1) |
|||
endif |
|||
let b = b + 1 |
|||
let s = s + 1 |
|||
else |
|||
execute s:Ref(backref, b, "start", "len") |
|||
let ref = strpart(backref, start, len) |
|||
let backref = strpart(backref, 0, start) . ":". table[s] |
|||
\ . strpart(backref, start+len) |
|||
let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1') |
|||
endif |
|||
endwhile |
|||
let word = strpart(word, 0, i-1) . backref . strpart(word, i+1) |
|||
let i = matchend(word, s:notslash . '\\\d') - 1 |
|||
endwhile |
|||
let word = substitute(word, s:notslash . '\zs:', '\\', 'g') |
|||
if a:output == "table" |
|||
return table |
|||
elseif a:output == "word" |
|||
return word |
|||
else |
|||
return table . word |
|||
endif |
|||
endfun |
|||
|
|||
" Assume a:comma = ",". Then the format for a:patterns and a:1 is |
|||
" a:patterns = "<pat1>,<pat2>,..." |
|||
" a:1 = "<alt1>,<alt2>,..." |
|||
" If <patn> is the first pattern that matches a:string then return <patn> |
|||
" if no optional arguments are given; return <patn>,<altn> if a:1 is given. |
|||
fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...) |
|||
let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma) |
|||
let i = matchend(tail, s:notslash . a:comma) |
|||
if a:0 |
|||
let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma) |
|||
let j = matchend(alttail, s:notslash . a:comma) |
|||
endif |
|||
let current = strpart(tail, 0, i-1) |
|||
if a:branch == "" |
|||
let currpat = current |
|||
else |
|||
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') |
|||
endif |
|||
while a:string !~ a:prefix . currpat . a:suffix |
|||
let tail = strpart(tail, i) |
|||
let i = matchend(tail, s:notslash . a:comma) |
|||
if i == -1 |
|||
return -1 |
|||
endif |
|||
let current = strpart(tail, 0, i-1) |
|||
if a:branch == "" |
|||
let currpat = current |
|||
else |
|||
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g') |
|||
endif |
|||
if a:0 |
|||
let alttail = strpart(alttail, j) |
|||
let j = matchend(alttail, s:notslash . a:comma) |
|||
endif |
|||
endwhile |
|||
if a:0 |
|||
let current = current . a:comma . strpart(alttail, 0, j-1) |
|||
endif |
|||
return current |
|||
endfun |
|||
|
|||
" Call this function to turn on debugging information. Every time the main |
|||
" script is run, buffer variables will be saved. These can be used directly |
|||
" or viewed using the menu items below. |
|||
if !exists(":MatchDebug") |
|||
command! -nargs=0 MatchDebug call s:Match_debug() |
|||
endif |
|||
|
|||
fun! s:Match_debug() |
|||
let b:match_debug = 1 " Save debugging information. |
|||
" pat = all of b:match_words with backrefs parsed |
|||
amenu &Matchit.&pat :echo b:match_pat<CR> |
|||
" match = bit of text that is recognized as a match |
|||
amenu &Matchit.&match :echo b:match_match<CR> |
|||
" curcol = cursor column of the start of the matching text |
|||
amenu &Matchit.&curcol :echo b:match_col<CR> |
|||
" wholeBR = matching group, original version |
|||
amenu &Matchit.wh&oleBR :echo b:match_wholeBR<CR> |
|||
" iniBR = 'if' piece, original version |
|||
amenu &Matchit.ini&BR :echo b:match_iniBR<CR> |
|||
" ini = 'if' piece, with all backrefs resolved from match |
|||
amenu &Matchit.&ini :echo b:match_ini<CR> |
|||
" tail = 'else\|endif' piece, with all backrefs resolved from match |
|||
amenu &Matchit.&tail :echo b:match_tail<CR> |
|||
" fin = 'endif' piece, with all backrefs resolved from match |
|||
amenu &Matchit.&word :echo b:match_word<CR> |
|||
" '\'.d in ini refers to the same thing as '\'.table[d] in word. |
|||
amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR> |
|||
endfun |
|||
|
|||
" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW" |
|||
" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W". |
|||
" Return a "mark" for the original position, so that |
|||
" let m = MultiMatch("bW", "n") ... execute m |
|||
" will return to the original position. If there is a problem, do not |
|||
" move the cursor and return "", unless a count is given, in which case |
|||
" go up or down as many levels as possible and again return "". |
|||
" TODO This relies on the same patterns as % matching. It might be a good |
|||
" idea to give it its own matching patterns. |
|||
fun! s:MultiMatch(spflag, mode) |
|||
if !exists("b:match_words") || b:match_words == "" |
|||
return "" |
|||
end |
|||
let restore_options = (&ic ? "" : "no") . "ignorecase" |
|||
if exists("b:match_ignorecase") |
|||
let &ignorecase = b:match_ignorecase |
|||
endif |
|||
let startline = line(".") |
|||
let startcol = col(".") |
|||
|
|||
" First step: if not already done, set the script variables |
|||
" s:do_BR flag for whether there are backrefs |
|||
" s:pat parsed version of b:match_words |
|||
" s:all regexp based on s:pat and the default groups |
|||
" This part is copied and slightly modified from s:Match_wrapper(). |
|||
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") . |
|||
\ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>' |
|||
" Allow b:match_words = "GetVimMatchWords()" . |
|||
if b:match_words =~ ":" |
|||
let match_words = b:match_words |
|||
else |
|||
execute "let match_words =" b:match_words |
|||
endif |
|||
if (match_words != s:last_words) || (&mps != s:last_mps) || |
|||
\ exists("b:match_debug") |
|||
let s:last_words = match_words |
|||
let s:last_mps = &mps |
|||
if match_words !~ s:notslash . '\\\d' |
|||
let s:do_BR = 0 |
|||
let s:pat = match_words |
|||
else |
|||
let s:do_BR = 1 |
|||
let s:pat = s:ParseWords(match_words) |
|||
endif |
|||
let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default, |
|||
\ '[,:]\+','\\|','g') . '\)' |
|||
if exists("b:match_debug") |
|||
let b:match_pat = s:pat |
|||
endif |
|||
endif |
|||
|
|||
" Second step: figure out the patterns for searchpair() |
|||
" and save the screen, cursor position, and 'ignorecase'. |
|||
" - TODO: A lot of this is copied from s:Match_wrapper(). |
|||
" - maybe even more functionality should be split off |
|||
" - into separate functions! |
|||
let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default |
|||
let open = substitute(s:pat . cdefault, |
|||
\ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g') |
|||
let open = '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '') |
|||
let close = substitute(s:pat . cdefault, |
|||
\ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g') |
|||
let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)' |
|||
if exists("b:match_skip") |
|||
let skip = b:match_skip |
|||
elseif exists("b:match_comment") " backwards compatibility and testing! |
|||
let skip = "r:" . b:match_comment |
|||
else |
|||
let skip = 's:comment\|string' |
|||
endif |
|||
let skip = s:ParseSkip(skip) |
|||
" let restore_cursor = line(".") . "G" . virtcol(".") . "|" |
|||
" normal! H |
|||
" let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor |
|||
let restore_cursor = virtcol(".") . "|" |
|||
normal! g0 |
|||
let restore_cursor = line(".") . "G" . virtcol(".") . "|zs" . restore_cursor |
|||
normal! H |
|||
let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor |
|||
execute restore_cursor |
|||
|
|||
" Third step: call searchpair(). |
|||
" Replace '\('--but not '\\('--with '\%(' and ',' with '\|'. |
|||
let openpat = substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g') |
|||
let openpat = substitute(openpat, ',', '\\|', 'g') |
|||
let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g') |
|||
let closepat = substitute(closepat, ',', '\\|', 'g') |
|||
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on")) |
|||
let skip = '0' |
|||
else |
|||
execute "if " . skip . "| let skip = '0' | endif" |
|||
endif |
|||
mark ' |
|||
let level = v:count1 |
|||
while level |
|||
if searchpair(openpat, '', closepat, a:spflag, skip) < 1 |
|||
call s:CleanUp(restore_options, a:mode, startline, startcol) |
|||
return "" |
|||
endif |
|||
let level = level - 1 |
|||
endwhile |
|||
|
|||
" Restore options and return a string to restore the original position. |
|||
call s:CleanUp(restore_options, a:mode, startline, startcol) |
|||
return restore_cursor |
|||
endfun |
|||
|
|||
" Search backwards for "if" or "while" or "<tag>" or ... |
|||
" and return "endif" or "endwhile" or "</tag>" or ... . |
|||
" For now, this uses b:match_words and the same script variables |
|||
" as s:Match_wrapper() . Later, it may get its own patterns, |
|||
" either from a buffer variable or passed as arguments. |
|||
" fun! s:Autocomplete() |
|||
" echo "autocomplete not yet implemented :-(" |
|||
" if !exists("b:match_words") || b:match_words == "" |
|||
" return "" |
|||
" end |
|||
" let startpos = s:MultiMatch("bW") |
|||
" |
|||
" if startpos == "" |
|||
" return "" |
|||
" endif |
|||
" " - TODO: figure out whether 'if' or '<tag>' matched, and construct |
|||
" " - the appropriate closing. |
|||
" let matchline = getline(".") |
|||
" let curcol = col(".") - 1 |
|||
" " - TODO: Change the s:all argument if there is a new set of match pats. |
|||
" let regexp = s:Wholematch(matchline, s:all, curcol) |
|||
" let suf = strlen(matchline) - matchend(matchline, regexp) |
|||
" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(') |
|||
" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$') |
|||
" " Reconstruct the version with unresolved backrefs. |
|||
" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g') |
|||
" let patBR = substitute(patBR, ':\{2,}', ':', "g") |
|||
" " Now, set group and groupBR to the matching group: 'if:endif' or |
|||
" " 'while:endwhile' or whatever. |
|||
" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR) |
|||
" let i = matchend(group, s:notslash . ",") |
|||
" let groupBR = strpart(group, i) |
|||
" let group = strpart(group, 0, i-1) |
|||
" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix |
|||
" if s:do_BR |
|||
" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline) |
|||
" endif |
|||
" " let g:group = group |
|||
" |
|||
" " - TODO: Construct the closing from group. |
|||
" let fake = "end" . expand("<cword>") |
|||
" execute startpos |
|||
" return fake |
|||
" endfun |
|||
|
|||
" Close all open structures. "Get the heck out of here!" |
|||
" fun! s:Gthhoh() |
|||
" let close = s:Autocomplete() |
|||
" while strlen(close) |
|||
" put=close |
|||
" let close = s:Autocomplete() |
|||
" endwhile |
|||
" endfun |
|||
|
|||
" Parse special strings as typical skip arguments for searchpair(): |
|||
" s:foo becomes (current syntax item) =~ foo |
|||
" S:foo becomes (current syntax item) !~ foo |
|||
" r:foo becomes (line before cursor) =~ foo |
|||
" R:foo becomes (line before cursor) !~ foo |
|||
fun! s:ParseSkip(str) |
|||
let skip = a:str |
|||
if skip[1] == ":" |
|||
if skip[0] == "s" |
|||
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . |
|||
\ strpart(skip,2) . "'" |
|||
elseif skip[0] == "S" |
|||
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" . |
|||
\ strpart(skip,2) . "'" |
|||
elseif skip[0] == "r" |
|||
let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'" |
|||
elseif skip[0] == "R" |
|||
let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'" |
|||
endif |
|||
endif |
|||
return skip |
|||
endfun |
|||
|
|||
let &cpo = s:save_cpo |
|||
|
|||
" vim:sts=2:sw=2: |
File diff suppressed because it is too large
Loading…
Reference in new issue