diff --git a/.bash_aliases b/.bash_aliases index d3840e2..2b7252b 100644 --- a/.bash_aliases +++ b/.bash_aliases @@ -61,6 +61,10 @@ alias pshosers="ps axeo pcpu,pid,user,command | sort -k 1 -r | head -11 " alias memhosers="ps axeo size,pcpu,pid,user,command | sort -n -r | head -11 " alias psx="ps auxwww | grep $1" +#work +alias totemp="cd `pwd | sed 's/controllers/templates/'`" +alias tocont="cd `pwd | sed 's/templates/controllers/'`" + #Some orly aliases alias yarly="orly -y" alias nowai="orly -n" diff --git a/.bashrc b/.bashrc index 553a425..5b44be0 100644 --- a/.bashrc +++ b/.bashrc @@ -85,3 +85,8 @@ fi if [ -f /etc/bash_completion ]; then . /etc/bash_completion fi + +if [ -n "`which fortune`" ]; then + fortune +fi + diff --git a/.vim/closetag.vim b/.vim/closetag.vim new file mode 100644 index 0000000..6ce41fb --- /dev/null +++ b/.vim/closetag.vim @@ -0,0 +1,327 @@ +" File: closetag.vim +" Summary: Functions and mappings to close open HTML/XML tags +" Uses: -- close matching open tag +" Author: Steven Mueller +" Last Modified: Tue May 24 13:29:48 PDT 2005 +" Version: 0.9.1 +" XXX - breaks if close attempted while XIM is in preedit mode +" TODO - allow usability as a global plugin - +" Add g:unaryTagsStack - always contains html tags settings +" and g:closetag_default_xml - user should define this to default to xml +" When a close is attempted but b:unaryTagsStack undefined, +" use b:closetag_html_style to determine if the file is to be treated +" as html or xml. Failing that, check the filetype for xml or html. +" Finally, default to g:closetag_html_style. +" If the file is html, let b:unaryTagsStack=g:unaryTagsStack +" otherwise, let b:unaryTagsStack="" +" TODO - make matching work for all comments +" -- kinda works now, but needs syn sync minlines to be very long +" -- Only check whether in syntax in the beginning, then store comment tags +" in the tagstacks to determine whether to move into or out of comment mode +" TODO - The new normal mode mapping clears recent messages with its , and +" it doesn't fix the null-undo issue for vim 5.7 anyway. +" TODO - make use of the following neat features: +" -- the ternary ?: operator +" -- :echomsg and :echoerr +" -- curly brace expansion for variables and function name definitions? +" -- check up on map \FuncName +" +" Description: +" This script eases redundant typing when writing html or xml files (even if +" you're very good with ctrl-p and ctrl-n :). Hitting ctrl-_ will initiate a +" search for the most recent open tag above that is not closed in the +" intervening space and then insert the matching close tag at the cursor. In +" normal mode, the close tag is inserted one character after cursor rather than +" at it, as if a had been used. This allows putting close tags at the +" ends of lines while in normal mode, but disallows inserting them in the +" first column. +" +" For HTML, a configurable list of tags are ignored in the matching process. +" By default, the following tags will not be matched and thus not closed +" automatically: area, base, br, dd, dt, hr, img, input, link, meta, and +" param. +" +" For XML, all tags must have a closing match or be terminated by />, as in +" . These empty element tags are ignored for matching. +" +" Comment checking is now handled by vim's internal syntax checking. If tag +" closing is initiated outside a comment, only tags outside of comments will +" be matched. When closing tags in comments, only tags within comments will +" be matched, skipping any non-commented out code (wee!). However, the +" process of determining the syntax ID of an arbitrary position can still be +" erroneous if a comment is not detected because the syntax highlighting is +" out of sync, or really slow if syn sync minlines is large. +" Set the b:closetag_disable_synID variable to disable this feature if you +" have really big chunks of comment in your code and closing tags is too slow. +" +" If syntax highlighting is not enabled, comments will not be handled very +" well. Commenting out HTML in certain ways may cause a "tag mismatch" +" message and no completion. For example, '' +" between the cursor and the most recent unclosed open tag above causes +" trouble. Properly matched well formed tags in comments don't cause a +" problem. +" +" Install: +" To use, place this file in your standard vim scripts directory, and source +" it while editing the file you wish to close tags in. If the filetype is not +" set or the file is some sort of template with embedded HTML, you may force +" HTML style tag matching by first defining the b:closetag_html_style buffer +" variable. Otherwise, the default is XML style tag matching. +" +" Example: +" :let b:closetag_html_style=1 +" :source ~/.vim/scripts/closetag.vim +" +" For greater convenience, load this script in an autocommand: +" :au Filetype html,xml,xsl source ~/.vim/scripts/closetag.vim +" +" Also, set noignorecase for html files or edit b:unaryTagsStack to match your +" capitalization style. You may set this variable before or after loading the +" script, or simply change the file itself. +" +" Configuration Variables: +" +" b:unaryTagsStack Buffer local string containing a whitespace +" seperated list of element names that should be +" ignored while finding matching closetags. Checking +" is done according to the current setting of the +" ignorecase option. +" +" b:closetag_html_style Define this (as with let b:closetag_html_style=1) +" and source the script again to set the +" unaryTagsStack to its default value for html. +" +" b:closetag_disable_synID Define this to disable comment checking if tag +" closing is too slow. This can be set or unset +" without having to source again. +" +" Changelog: +" May 24, 2005 Tuesday +" * Changed function names to be script-local to avoid conflicts with other +" scripts' stack implementations. +" +" June 07, 2001 Thursday +" * Added comment handling. Currently relies on synID, so if syn sync +" minlines is small, the chance for failure is high, but if minlines is +" large, tagclosing becomes rather slow... +" +" * Changed normal mode closetag mapping to use in insert mode +" rather than p in normal mode. This has 2 implications: +" - Tag closing no longer clobbers the unnamed register +" - When tag closing fails or finds no match, no longer adds to the undo +" buffer for recent vim 6.0 development versions. +" - However, clears the last message when closing tags in normal mode +" +" * Changed the closetag_html_style variable to be buffer-local rather than +" global. +" +" * Expanded documentation + +"------------------------------------------------------------------------------ +" User configurable settings +"------------------------------------------------------------------------------ + +" if html, don't close certain tags. Works best if ignorecase is set. +" otherwise, capitalize these elements according to your html editing style +if !exists("b:unaryTagsStack") || exists("b:closetag_html_style") + if &filetype == "html" || exists("b:closetag_html_style") + let b:unaryTagsStack="area base br dd dt hr img input link meta param" + else " for xsl and xsl + let b:unaryTagsStack="" + endif +endif + +" Has this already been loaded? +if exists("loaded_closetag") + finish +endif +let loaded_closetag=1 + +" set up mappings for tag closing +inoremap =GetCloseTag() +map a + +"------------------------------------------------------------------------------ +" Tag closer - uses the stringstack implementation below +"------------------------------------------------------------------------------ + +" Returns the most recent unclosed tag-name +" (ignores tags in the variable referenced by a:unaryTagsStack) +function! GetLastOpenTag(unaryTagsStack) + " Search backwards through the file line by line using getline() + " Overall strategy (moving backwards through the file from the cursor): + " Push closing tags onto a stack. + " On an opening tag, if the tag matches the stack top, discard both. + " -- if the tag doesn't match, signal an error. + " -- if the stack is empty, use this tag + let linenum=line(".") + let lineend=col(".") - 1 " start: cursor position + let first=1 " flag for first line searched + let b:TagStack="" " main stack of tags + let startInComment=s:InComment() + + let tagpat='' + " Search for: closing tags + while (linenum>0) + " Every time we see an end-tag, we push it on the stack. When we see an + " open tag, if the stack isn't empty, we pop it and see if they match. + " If no, signal an error. + " If yes, continue searching backwards. + " If stack is empty, return this open tag as the one that needs closing. + let line=getline(linenum) + if first + let line=strpart(line,0,lineend) + else + let lineend=strlen(line) + endif + let b:lineTagStack="" + let mpos=0 + let b:TagCol=0 + " Search the current line in the forward direction, pushing any tags + " onto a special stack for the current line + while (mpos > -1) + let mpos=matchend(line,tagpat) + if mpos > -1 + let b:TagCol=b:TagCol+mpos + let tag=matchstr(line,tagpat) + + if exists("b:closetag_disable_synID") || startInComment==s:InCommentAt(linenum, b:TagCol) + let b:TagLine=linenum + call s:Push(matchstr(tag,'[^<>]\+'),"b:lineTagStack") + endif + "echo "Tag: ".tag." ending at position ".mpos." in '".line."'." + let lineend=lineend-mpos + let line=strpart(line,mpos,lineend) + endif + endwhile + " Process the current line stack + while (!s:EmptystackP("b:lineTagStack")) + let tag=s:Pop("b:lineTagStack") + if match(tag, "^/") == 0 "found end tag + call s:Push(tag,"b:TagStack") + "echo linenum." ".b:TagStack + elseif s:EmptystackP("b:TagStack") && !s:Instack(tag, a:unaryTagsStack) "found unclosed tag + return tag + else + let endtag=s:Peekstack("b:TagStack") + if endtag == "/".tag || endtag == "/" + call s:Pop("b:TagStack") "found a open/close tag pair + "echo linenum." ".b:TagStack + elseif !s:Instack(tag, a:unaryTagsStack) "we have a mismatch error + echohl Error + echon "\rError:" + echohl None + echo " tag mismatch: <".tag."> doesn't match <".endtag.">. (Line ".linenum." Tagstack: ".b:TagStack.")" + return "" + endif + endif + endwhile + let linenum=linenum-1 | let first=0 + endwhile + " At this point, we have exhausted the file and not found any opening tag + echo "No opening tags." + return "" +endfunction + +" Returns closing tag for most recent unclosed tag, respecting the +" current setting of b:unaryTagsStack for tags that should not be closed +function! GetCloseTag() + let tag=GetLastOpenTag("b:unaryTagsStack") + if tag == "" + return "" + else + return "" + endif +endfunction + +" return 1 if the cursor is in a syntactically identified comment field +" (fails for empty lines: always returns not-in-comment) +function! s:InComment() + return synIDattr(synID(line("."), col("."), 0), "name") =~ 'Comment' +endfunction + +" return 1 if the position specified is in a syntactically identified comment field +function! s:InCommentAt(line, col) + return synIDattr(synID(a:line, a:col, 0), "name") =~ 'Comment' +endfunction + +"------------------------------------------------------------------------------ +" String Stacks +"------------------------------------------------------------------------------ +" These are strings of whitespace-separated elements, matched using the \< and +" \> patterns after setting the iskeyword option. +" +" The sname argument should contain a symbolic reference to the stack variable +" on which method should operate on (i.e., sname should be a string containing +" a fully qualified (ie: g:, b:, etc) variable name.) + +" Helper functions +function! s:SetKeywords() + let g:IsKeywordBak=&iskeyword + let &iskeyword="33-255" +endfunction + +function! s:RestoreKeywords() + let &iskeyword=g:IsKeywordBak +endfunction + +" Push el onto the stack referenced by sname +function! s:Push(el, sname) + if !s:EmptystackP(a:sname) + exe "let ".a:sname."=a:el.' '.".a:sname + else + exe "let ".a:sname."=a:el" + endif +endfunction + +" Check whether the stack is empty +function! s:EmptystackP(sname) + exe "let stack=".a:sname + if match(stack,"^ *$") == 0 + return 1 + else + return 0 + endif +endfunction + +" Return 1 if el is in stack sname, else 0. +function! s:Instack(el, sname) + exe "let stack=".a:sname + call s:SetKeywords() + let m=match(stack, "\\<".a:el."\\>") + call s:RestoreKeywords() + if m < 0 + return 0 + else + return 1 + endif +endfunction + +" Return the first element in the stack +function! s:Peekstack(sname) + call s:SetKeywords() + exe "let stack=".a:sname + let top=matchstr(stack, "\\<.\\{-1,}\\>") + call s:RestoreKeywords() + return top +endfunction + +" Remove and return the first element in the stack +function! s:Pop(sname) + if s:EmptystackP(a:sname) + echo "Error! Stack ".a:sname." is empty and can't be popped." + return "" + endif + exe "let stack=".a:sname + " Find the first space, loc is 0-based. Marks the end of 1st elt in stack. + call s:SetKeywords() + let loc=matchend(stack,"\\<.\\{-1,}\\>") + exe "let ".a:sname."=strpart(stack, loc+1, strlen(stack))" + let top=strpart(stack, match(stack, "\\<"), loc) + call s:RestoreKeywords() + return top +endfunction + +function! s:Clearstack(sname) + exe "let ".a:sname."=''" +endfunction diff --git a/.vim/colors/barak.vim b/.vim/colors/barak.vim index 4898464..4848c04 100644 --- a/.vim/colors/barak.vim +++ b/.vim/colors/barak.vim @@ -53,6 +53,15 @@ endif " syntax hi colors hi Comment term=bold ctermfg=darkgreen guifg=ForestGreen hi PreProc term=underline ctermfg=darkmagenta guifg=magenta3 + +hi makoDelim term=underline ctermfg=darkyellow guifg=goldenrod1 guibg=gray25 +hi makoAttributeKey term=underline ctermfg=darkcyan gui=bold guifg=turquoise3 guibg=gray25 +hi makoAttributeValue term=underline ctermfg=red guifg=firebrick3 guibg=gray25 +hi makoText ctermfg=gray guifg=gray55 guibg=gray25 +hi makoEnd term=bold ctermfg=blue gui=bold guifg=RoyalBlue1 guibg=gray25 +hi makoComment term=bold ctermfg=darkgreen guifg=ForestGreen guibg=gray25 +hi makoEscape term=underline ctermfg=brown guifg=khaki3 guibg=gray25 + hi Constant term=underline ctermfg=red guifg=#b62f61 hi String term=underline ctermfg=red guifg=firebrick3 hi Boolean term=underline ctermfg=magenta guifg=LightSalmon1 diff --git a/.vim/doc/matchit.txt b/.vim/doc/matchit.txt new file mode 100644 index 0000000..8a3a96e --- /dev/null +++ b/.vim/doc/matchit.txt @@ -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 = '<:>,:' +< and hit "%" with the cursor on or before the "<" in "a is born". + The pattern '<' comes first, so it is preferred over '', which + also matches. If the cursor is on the "t", however, then '' 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 = '\:\' +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 = '\:\,' + \ . '\:\:\:\' +(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" +matches the end of "endif" but "\" 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: '\' rather than "\\" 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 "label", "<.*>" +matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "" and +"". + + *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 = '\%(\:\' +< *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 = '\:\(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 "", 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: diff --git a/.vim/doc/tags b/.vim/doc/tags index a90d741..8acf107 100644 --- a/.vim/doc/tags +++ b/.vim/doc/tags @@ -7,6 +7,7 @@ :CVSWatchOn vcscommand.txt /*:CVSWatchOn* :CVSWatchRemove vcscommand.txt /*:CVSWatchRemove* :CVSWatchers vcscommand.txt /*:CVSWatchers* +:MatchDebug matchit.txt /*:MatchDebug* :VCSAdd vcscommand.txt /*:VCSAdd* :VCSAnnotate vcscommand.txt /*:VCSAnnotate* :VCSBlame vcscommand.txt /*:VCSBlame* @@ -24,6 +25,7 @@ :VCSUnlock vcscommand.txt /*:VCSUnlock* :VCSUpdate vcscommand.txt /*:VCSUpdate* :VCSVimDiff vcscommand.txt /*:VCSVimDiff* +MatchError matchit.txt /*MatchError* VCSCommandCVSDiffOpt vcscommand.txt /*VCSCommandCVSDiffOpt* VCSCommandCVSExec vcscommand.txt /*VCSCommandCVSExec* VCSCommandCommitOnWrite vcscommand.txt /*VCSCommandCommitOnWrite* @@ -40,10 +42,25 @@ VCSCommandSVNDiffExt vcscommand.txt /*VCSCommandSVNDiffExt* VCSCommandSVNDiffOpt vcscommand.txt /*VCSCommandSVNDiffOpt* VCSCommandSVNExec vcscommand.txt /*VCSCommandSVNExec* VCSCommandSplit vcscommand.txt /*VCSCommandSplit* +[% matchit.txt /*[%* +]% matchit.txt /*]%* b:VCSCommandCommand vcscommand.txt /*b:VCSCommandCommand* b:VCSCommandOriginalBuffer vcscommand.txt /*b:VCSCommandOriginalBuffer* b:VCSCommandSourceFile vcscommand.txt /*b:VCSCommandSourceFile* b:VCSCommandVCSType vcscommand.txt /*b:VCSCommandVCSType* +b:match_col matchit.txt /*b:match_col* +b:match_debug matchit.txt /*b:match_debug* +b:match_ignorecase matchit.txt /*b:match_ignorecase* +b:match_ini matchit.txt /*b:match_ini* +b:match_iniBR matchit.txt /*b:match_iniBR* +b:match_match matchit.txt /*b:match_match* +b:match_pat matchit.txt /*b:match_pat* +b:match_skip matchit.txt /*b:match_skip* +b:match_table matchit.txt /*b:match_table* +b:match_tail matchit.txt /*b:match_tail* +b:match_wholeBR matchit.txt /*b:match_wholeBR* +b:match_word matchit.txt /*b:match_word* +b:match_words matchit.txt /*b:match_words* cs surround.txt /*cs* cvscommand-changes vcscommand.txt /*cvscommand-changes* drawit DrawIt.txt /*drawit* @@ -74,9 +91,38 @@ drawit-usage DrawIt.txt /*drawit-usage* drawit-visblock DrawIt.txt /*drawit-visblock* drawit.txt DrawIt.txt /*drawit.txt* ds surround.txt /*ds* +g% matchit.txt /*g%* g:drawit_insertmode DrawIt.txt /*g:drawit_insertmode* i_CTRL-G_S surround.txt /*i_CTRL-G_S* i_CTRL-G_s surround.txt /*i_CTRL-G_s* +matchit matchit.txt /*matchit* +matchit-% matchit.txt /*matchit-%* +matchit-\1 matchit.txt /*matchit-\\1* +matchit-activate matchit.txt /*matchit-activate* +matchit-backref matchit.txt /*matchit-backref* +matchit-bugs matchit.txt /*matchit-bugs* +matchit-choose matchit.txt /*matchit-choose* +matchit-configure matchit.txt /*matchit-configure* +matchit-debug matchit.txt /*matchit-debug* +matchit-details matchit.txt /*matchit-details* +matchit-highlight matchit.txt /*matchit-highlight* +matchit-hl matchit.txt /*matchit-hl* +matchit-intro matchit.txt /*matchit-intro* +matchit-languages matchit.txt /*matchit-languages* +matchit-modes matchit.txt /*matchit-modes* +matchit-newlang matchit.txt /*matchit-newlang* +matchit-o_% matchit.txt /*matchit-o_%* +matchit-parse matchit.txt /*matchit-parse* +matchit-s:notend matchit.txt /*matchit-s:notend* +matchit-s:sol matchit.txt /*matchit-s:sol* +matchit-spaces matchit.txt /*matchit-spaces* +matchit-troubleshoot matchit.txt /*matchit-troubleshoot* +matchit-v_% matchit.txt /*matchit-v_%* +matchit.txt matchit.txt /*matchit.txt* +matchit.vim matchit.txt /*matchit.vim* +o_[% matchit.txt /*o_[%* +o_]% matchit.txt /*o_]%* +o_g% matchit.txt /*o_g%* project project.txt /*project* project-adding-mappings project.txt /*project-adding-mappings* project-example project.txt /*project-example* @@ -125,6 +171,10 @@ surround-mappings surround.txt /*surround-mappings* surround-replacements surround.txt /*surround-replacements* surround-targets surround.txt /*surround-targets* surround.txt surround.txt /*surround.txt* +v_[% matchit.txt /*v_[%* +v_]% matchit.txt /*v_]%* +v_a% matchit.txt /*v_a%* +v_g% matchit.txt /*v_g%* vcscommand vcscommand.txt /*vcscommand* vcscommand-buffer-management vcscommand.txt /*vcscommand-buffer-management* vcscommand-buffer-variables vcscommand.txt /*vcscommand-buffer-variables* diff --git a/.vim/filetype.vim b/.vim/filetype.vim index 7ff28ec..0c1e7e9 100644 --- a/.vim/filetype.vim +++ b/.vim/filetype.vim @@ -5,3 +5,6 @@ endif augroup markdown au! BufRead,BufNewFile *.mkd setfiletype mkd augroup END +augroup mako + au! BufRead,BufNewFile *.mak setfiletype mako +augroup END diff --git a/.vim/plugin/matchit.vim b/.vim/plugin/matchit.vim new file mode 100755 index 0000000..e41cda9 --- /dev/null +++ b/.vim/plugin/matchit.vim @@ -0,0 +1,812 @@ +" matchit.vim: (global plugin) Extended "%" matching +" Last Change: Fri Jan 25 10:00 AM 2008 EST +" Maintainer: Benji Fisher PhD +" 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 % :call Match_wrapper('',1,'n') +nnoremap g% :call Match_wrapper('',0,'n') +vnoremap % :call Match_wrapper('',1,'v') m'gv`` +vnoremap g% :call Match_wrapper('',0,'v') m'gv`` +onoremap % v:call Match_wrapper('',1,'o') +onoremap g% v:call Match_wrapper('',0,'o') + +" Analogues of [{ and ]} using matching patterns: +nnoremap [% :call MultiMatch("bW", "n") +nnoremap ]% :call MultiMatch("W", "n") +vmap [% [%m'gv`` +vmap ]% ]%m'gv`` +" vnoremap [% :call MultiMatch("bW", "v") m'gv`` +" vnoremap ]% :call MultiMatch("W", "v") m'gv`` +onoremap [% v:call MultiMatch("bW", "o") +onoremap ]% v:call MultiMatch("W", "o") + +" text object: +vmap a% [%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 = '' +" let g:match_autoCR = '' +" if exists("g:match_auto") +" execute "inoremap " . g:match_auto . ' x"=Autocomplete()Pls' +" endif +" if exists("g:match_autoCR") +" execute "inoremap " . g:match_autoCR . ' =Autocomplete()' +" endif +" if exists("g:match_gthhoh") +" execute "inoremap " . g:match_gthhoh . ' :call Gthhoh()' +" endif " gthhoh = "Get the heck out of here!" + +let s:notslash = '\\\@" + 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\+\)>:' +" a:prefix = '^.\{3}\(' +" a:group = '<\(\k\+\)>:' +" a:suffix = '\).\{2}$' +" a:matchline = "12312" or "12312" +" then extract "tag" from a:matchline and return ":" . +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 = ",,..." +" a:1 = ",,..." +" If is the first pattern that matches a:string then return +" if no optional arguments are given; return , 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 + " match = bit of text that is recognized as a match + amenu &Matchit.&match :echo b:match_match + " curcol = cursor column of the start of the matching text + amenu &Matchit.&curcol :echo b:match_col + " wholeBR = matching group, original version + amenu &Matchit.wh&oleBR :echo b:match_wholeBR + " iniBR = 'if' piece, original version + amenu &Matchit.ini&BR :echo b:match_iniBR + " ini = 'if' piece, with all backrefs resolved from match + amenu &Matchit.&ini :echo b:match_ini + " tail = 'else\|endif' piece, with all backrefs resolved from match + amenu &Matchit.&tail :echo b:match_tail + " fin = 'endif' piece, with all backrefs resolved from match + amenu &Matchit.&word :echo b:match_word + " '\'.d in ini refers to the same thing as '\'.table[d] in word. + amenu &Matchit.t&able :echo '0:' . b:match_table . ':9' +endfun + +" Jump to the nearest unmatched "(" or "if" or "" if a:spflag == "bW" +" or the nearest unmatched "" 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, '\(\\\@" or ... +" and return "endif" or "endwhile" or "" 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 '' 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("") +" 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: diff --git a/.vim/syntax/mako.vim b/.vim/syntax/mako.vim new file mode 100644 index 0000000..a9244a2 --- /dev/null +++ b/.vim/syntax/mako.vim @@ -0,0 +1,83 @@ +" Vim syntax file +" Language: Mako +" Maintainer: Armin Ronacher +" URL: http://lucumr.pocoo.org/ +" Last Change: 2007 April 8 +" Version: 0.6 +" +" Known Limitations +" the <%text> block does not have correct attributes + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +if !exists("main_syntax") + let main_syntax = "html" +endif + +"Source the html syntax file +ru! syntax/html.vim +unlet b:current_syntax + +"Put the python syntax file in @pythonTop +syn include @pythonTop syntax/python.vim + +" End keywords +syn keyword makoEnd contained endfor endwhile endif endtry enddef + +" Block rules +syn region makoLine matchgroup=makoDelim start=#%\s*# end=#$# keepend contains=@pythonTop,makoEnd +syn region makoBlock matchgroup=makoDelim start=#<%!\?# end=#%># keepend contains=@pythonTop,makoEnd + +" Variables +syn region makoNested start="{" end="}" transparent display contained contains=makoNested,@pythonTop +syn region makoVariable matchgroup=makoDelim start=#\${# end=#}# contains=makoNested,@pythonTop + +" Comments +syn region makoComment start="##" end="$" +syn region makoDocComment matchgroup=makoDelim start="<%doc>" end="" keepend + +" Literal Blocks +syn region makoText matchgroup=makoDelim start="<%text[^>]*>" end="" + +" Attribute Sublexing +syn match makoAttributeKey containedin=makoTag contained "[a-zA-Z_][a-zA-Z0-9_]*=" +syn region makoAttributeValue containedin=makoTag contained start=/"/ skip=/\\"/ end=/"/ +syn region makoAttributeValue containedin=MakoTag contained start=/'/ skip=/\\'/ end=/'/ + +" Tags +syn region makoTag matchgroup=makoDelim start="<%\(def\|call\|page\|include\|namespace\|inherit\)\>\s*" end="/\?>" +syn match makoDelim "" + +" Newline Escapes +syn match makoEscape /\\$/ + +" Default highlighting links +if version >= 508 || !exists("did_mako_syn_inits") + if version < 508 + let did_mako_syn_inits = 1 + com -nargs=+ HiLink hi link + else + com -nargs=+ HiLink hi def link + endif + + HiLink makoDocComment makoComment + HiLink makoDefEnd makoDelim + + HiLink makoAttributeKey Type + HiLink makoAttributeValue String + HiLink makoText Normal + HiLink makoDelim Preproc + HiLink makoEnd Keyword + HiLink makoComment Comment + HiLink makoEscape Special + + delc HiLink +endif + +let b:current_syntax = "mako" diff --git a/.vimrc b/.vimrc index 5606868..1d5edea 100644 --- a/.vimrc +++ b/.vimrc @@ -4,6 +4,9 @@ syntax on colorscheme barak "set gfn=Monaco:h12:a set ts=4 +set softtabstop=4 +set shiftwidth=4 +set expandtab set nocompatible set smartcase set smartindent @@ -20,8 +23,9 @@ au BufNewFile,BufRead motd.public,/tmp/motd.public.r.* setf motd autocmd FileType ruby,eruby set omnifunc=rubycomplete#Complete autocmd FileType python set tags+=$HOME/.vim/tags/python.ctags autocmd FileType python set omnifunc=pythoncomplete#Complete -autocmd FileType python call SuperTabSetCompletionType("") +"autocmd FileType python call SuperTabSetCompletionType("") let python_highlight_all = 1 +au Filetype html,xml,xsl source ~/.vim/closetag.vim set t_Co=16 set t_Sf=ESC[3%dm @@ -53,6 +57,20 @@ vnoremap $ inoremap ^ inoremap $ +" , #perl # comments +map ,# :s/^/#/ +" , #mako ## comments +map ,% :s/^/##/ + +" ,/ C/C++/C#/Java // comments +map ,/ :s/^/\/\// + +" ,< HTML comment +map ,< :s/^\(.*\)$//:nohlsearch + +" c++ java style comments +map ,* :s/^\(.*\)$/\/\* \1 \*\//:nohlsearch + if !exists(":W") command W :w