modularized endwise, indexed search, htmlescape

This commit is contained in:
yan
2011-12-07 02:39:21 -08:00
committed by Yan Pritzker
parent 429396fcbf
commit 13a5ac829b
8 changed files with 12 additions and 1174 deletions

9
.gitmodules vendored
View File

@@ -85,3 +85,12 @@
[submodule "vim/bundle/vim-scripts-matchit.zip"]
path = vim/bundle/vim-scripts-matchit.zip
url = https://github.com/vim-scripts/matchit.zip.git
[submodule "vim/bundle/skwp-vim-indexed-search"]
path = vim/bundle/skwp-vim-indexed-search
url = https://github.com/skwp/vim-indexed-search
[submodule "vim/bundle/tpope-vim-endwise"]
path = vim/bundle/tpope-vim-endwise
url = https://github.com/tpope/vim-endwise.git
[submodule "vim/bundle/skwp-vim-html-escape"]
path = vim/bundle/skwp-vim-html-escape
url = https://github.com/skwp/vim-html-escape

View File

@@ -1,675 +0,0 @@
"
" Copyright 2006 Tye Zdrojewski
"
" Licensed under the Apache License, Version 2.0 (the "License"); you may not
" use this file except in compliance with the License. You may obtain a copy of
" the License at
"
" http://www.apache.org/licenses/LICENSE-2.0
"
" Unless required by applicable law or agreed to in writing, software distributed
" under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
" CONDITIONS OF ANY KIND, either express or implied. See the License for the
" specific language governing permissions and limitations under the License.
"
"
"
" Plugin:
"
" Indent Anything
"
" Version: 1.2.2
"
" Description:
"
" This is an indentation script that calculates the indent level based
" on begin/end syntax pairs and line-continuation patterns. It allows one
" to create an indent script without writing any code, taking it's
" instruction from configurable values.
"
" Included with this script is Javascript indentation, an example that
" explains the configurable values.
"
"
" Installation:
"
" Place this file in your home directory under ~/.vim/indent/, or replace
" the system indent/javascript.vim file to affect all users.
"
" Maintainer: Tye Z. <zdro@yahoo.com>
"
" Customization:
"
" The only thing that can really be customized at this point is whether or
" not a line is echoed explaining the indentation result. To turn this on,
" set the following variable like so:
"
" let b:indent_anything_echo = 1
"
"
" History:
"
" 1.2 - made some functions script-local to prevent naming collisions
" - fixed some broken indentation in the middle of a block comment,
" which showed up in Javascript indentation.
"
" 1.2.2 - Fixed a bug causing the line after a single-line block comment to
" always have an indent of '0' (i.e. the line after /* comment */).
" - Added Apache 2 license
"
"
let s:supportedVimVersion = 700
if version < s:supportedVimVersion
echoerr "IndentAnything only supported for Vim " . s:supportedVimVersion . " and up."
finish
endif
"
" Initialize everything needed by this script. Only set those values that are
" not set already.
"
function! IndentAnythingInit()
let b:IndentAnythingInitialized = 1
" Start with a regular expression that will never match. Matching
" will influence behavior, which the defaults should not do.
let s:nonMatcher = '[x]\&[^x]'
if !exists('b:commentRE')
let b:commentRE = s:nonMatcher
endif
if !exists('b:lineCommentRE')
let b:lineCommentRE = s:nonMatcher
endif
if !exists('b:blockCommentRE')
let b:blockCommentRE = s:nonMatcher
endif
if !exists('b:stringRE')
let b:stringRE = s:nonMatcher
endif
if !exists('b:singleQuoteStringRE')
let b:singleQuoteStringRE = s:nonMatcher
endif
if !exists('b:doubleQuoteStringRE')
let b:doubleQuoteStringRE = s:nonMatcher
endif
if !exists('b:blockCommentStartRE')
let b:blockCommentStartRE = s:nonMatcher
endif
if !exists('b:blockCommentMiddleRE')
let b:blockCommentMiddleRE = s:nonMatcher
endif
if !exists('b:blockCommentEndRE')
let b:blockCommentEndRE = s:nonMatcher
endif
if !exists('b:blockCommentMiddleExtra')
let b:blockCommentMiddleExtra = 0
endif
if !exists('b:indentTrios')
let b:indentTrios = []
endif
if !exists('b:lineContList')
let b:lineContList = []
endif
if !exists('b:contTraversesLineComments')
let b:contTraversesLineComments = 1
endif
if !exists('b:indent_anything_echo')
let b:indent_anything_echo = 0
endif
endfunction
function! SynHere()
return synIDattr(synID(line('.'), col('.'), 1), "name")
endfunction
"
" Returns true if the cursor is currently inside a comment or a string
"
function! InCommentOrString()
let syn = synIDattr(synID(line("."), col("."), 1), "name")
if syn =~ b:commentRE || syn =~ b:stringRE
return 1
endif
return 0
endfunction
"
" Returns true if the given line is a comment line (b:lineCommentRE)
"
function! IsLineComment(linenum)
let cursor = getpos('.')
exec a:linenum
normal ^
let l:iscomment = 0
let l:syn = synIDattr(synID(line('.'), col('.'), 1), "name")
if l:syn =~ b:lineCommentRE " b:commentRE || l:syn =~ b:stringRE
let l:iscomment = 1
endif
call setpos('.', cursor)
return l:iscomment
endfunction
"
" Returns true if the given line is a comment line (b:lineCommentRE)
"
function! IsComment(linenum)
let cursor = getpos('.')
exec a:linenum
normal ^
let l:iscomment = 0
let l:syn = synIDattr(synID(line('.'), col('.'), 1), "name")
if l:syn =~ b:commentRE " b:commentRE || l:syn =~ b:stringRE
let l:iscomment = 1
endif
call setpos('.', cursor)
return l:iscomment
endfunction
"
" Returns true if the given line is a comment line (b:lineCommentRE)
"
function! IsBlockComment(linenum)
let cursor = getpos('.')
exec a:linenum
normal ^
let l:iscomment = 0
let l:syn = synIDattr(synID(line('.'), col('.'), 1), "name")
if l:syn =~ b:blockCommentRE " b:commentRE || l:syn =~ b:stringRE
let l:iscomment = 1
endif
call setpos('.', cursor)
return l:iscomment
endfunction
"
" Get the first line at or on the given line that is not blank and is not a
" comment line.
"
function! GetPrevNonBlankNonComment(begin)
let cursor = getpos('.')
let l:prevbegin = a:begin
while 1
let l:lnum = prevnonblank(l:prevbegin)
if l:lnum == 0
return 0
endif
"if IsLineComment(l:lnum)
if IsComment(l:lnum)
let l:prevbegin -= 1
continue
endif
break
endwhile
" Restore original cursor location
call setpos('.', cursor)
return l:lnum
endfunction
"
" This does all the work. Does indentation for:
"
" - All pairs defined in b:indentTrios
" - All line continuations in b:lineContList
" - Block comments
"
function! IndentAnything()
if !exists('b:IndentAnythingInitialized')
call IndentAnythingInit()
endif
let adj = 0 " Adjustment
let g:lastindent = ""
let b:hardindent = -1
let currlnum = v:lnum
let currlnum = line('.')
let currline = getline(currlnum)
let lastline = ''
let prevline = ''
" Find non-blank lines above the current line.
let lastlnum = prevnonblank(currlnum - 1)
let prevlnum = prevnonblank(lastlnum - 1)
if lastlnum != 0
let lastline = getline(lastlnum)
endif
if prevlnum != 0
let prevline = getline(prevlnum)
endif
if b:contTraversesLineComments
let lastcodelnum = GetPrevNonBlankNonComment(currlnum - 1)
let prevcodelnum = GetPrevNonBlankNonComment(lastcodelnum - 1)
if lastcodelnum !=0
let lastcodeline = getline(lastcodelnum)
endif
endif
" Start from the first char on the line. Vim doesn't seem to consistently
" place the cursor there before calling the indent routines.
call cursor(0, 1)
call search('\S', 'W')
let l:cur = getpos('.')
"
" Call indentation adjustment functions.
"
"
" Block comments
"
let l:BlockCommentAdj = 0
let l:BlockCommentAdj += s:GetBlockCommentIndent(currlnum, lastlnum)
let adj += l:BlockCommentAdj
"
" Pairs
"
let b:lastclosed = { 'at' : 0 }
let b:pairadj = 0
if !l:BlockCommentAdj
" If we're not in the middle of a block comment (because we haven't
" made any adjustments for that), then process block indentation.
for trio in b:indentTrios
let b:pairadj += s:GetPairIndent(currline, lastline, lastlnum,
\ trio[0], trio[1], trio[2])
endfor
endif
let adj += b:pairadj
"
" Line continuations
"
let contadj = 0
let isBlockCommentStart = currline =~ '^\s*' . b:blockCommentStartRE
let isBlockCommentMid = (IsBlockComment(currlnum) && !isBlockCommentStart)
if !isBlockCommentMid
" If the current line is not the middle of a block comment, then
" process line continuations.
for ContRule in b:lineContList
if b:contTraversesLineComments "&& !isBlockCommentStart
let contadj = s:GetContIndent(ContRule, currline, lastcodeline, lastcodelnum, prevcodelnum)
else
let contadj = s:GetContIndent(ContRule, currline, lastline, lastlnum, prevlnum)
endif
" This is for line continuation patterns, of which there can be only
" one per line to indicate continuation
if contadj
break
endif
endfor
let adj += contadj
endif
"
" Find the previous indent to which we will add the adjustment
"
let prevind = indent(lastlnum)
if l:BlockCommentAdj
let g:lastindent .= " indent (prevblockcomment: " . prevind . " at " . lastcodelnum . ") "
elseif contadj && b:contTraversesLineComments
" If we have adjusted for line continuation, then use the indentation
" for the previous code line
let prevind = indent(lastcodelnum)
let g:lastindent .= " indent (prevcode: " . prevind . " at " . lastcodelnum . ") "
elseif (isBlockCommentStart || !IsBlockComment(currlnum)) && IsBlockComment(lastlnum)
" If this is the first line after a block comment, then add the
" adjustment to the line where the block comment started.
let prevind = s:GetPostBlockCommentIndent(lastlnum)
let g:lastindent .= " indent (prevblock: " . prevind . " at " . lastlnum . ") "
elseif exists("b:defaultIndentExpr")
let g:lastindent .= " using defaultIndentExpr (" . b:defaultIndentExpr . ") "
exec "let prevind = " . b:defaultIndentExpr
else
" Default to adjusting the previous line's indent.
let g:lastindent .= " indent (prev: " . prevind . " at " . lastlnum . ") "
endif
" Just in case there is no previous indent.
let prevind = (prevind == -1 ? 0 : prevind)
if b:indent_anything_echo
echom g:lastindent
endif
call setpos('.', l:cur)
return adj + prevind
endfunction
"
" Get the adjustment for the second line of a block comment. The second line
" will be aligned under the start of the block, even if it is not at the
" beginning of the line. Extra adjustment (b:blockCommentMiddleExtra) will
" be added.
"
function! s:GetBlockCommentIndent(CurrLNum, LastLNum)
let l:cursor = getpos('.')
let l:adj = 0
if a:LastLNum == searchpair(b:blockCommentStartRE, '', b:blockCommentEndRE, 'bWr')
\ && a:LastLNum > 0
let l:adj = col('.') + b:blockCommentMiddleExtra
normal ^
let l:adj -= col('.')
endif
call setpos('.', l:cursor)
return l:adj
endfunction
function! s:GetPostBlockCommentIndent(LastLNum)
let l:cursor = getpos('.')
let l:ind = 0
let l:comment_start_lnum = 0;
" Find beginning of block comment containing the start of line LastLNum
exec a:LastLNum
normal ^
let l:comment_start_lnum = searchpair(
\ b:blockCommentStartRE, b:blockCommentMiddleRE, b:blockCommentEndRE, 'bWr')
" Assume that the LastLNum is a block comment. If the comment both
" started and stopped on LastLNum, then searchpair will return 0. In that
" case, we just want to return the indent of LastLNum itself.
if 0 == l:comment_start_lnum
let l:comment_start_lnum = a:LastLNum
endif
let l:ind = indent(l:comment_start_lnum)
if 1 || l:ind != 0 && b:indent_anything_echo
let g:lastindent = g:lastindent .
\ "GetPostBlockCommentIndent: " . l:ind
endif
call setpos('.', l:cursor)
"return l:ind
return l:ind > 0 ? l:ind : 0
endfunction
"
" Get additional indentation based on blocks of code, as defined by the Head
" and Tail patterns.
"
function! s:GetPairIndent(CurrLine, LastLine, LastLNum, Head, Mid, Tail)
let levels = 0
let adj = 0
let origcol = col(".")
let origline = line(".")
"
" How many levels were started on the last line? Search backwards for
" pair starters until we're not on the last nonblank. If the last line
" doesn't contain the pair-starter, then don't bother with searchpair();
" it's a performance bottleneck because (I think) it will always search
" all the way back until it finds a match or can't search any more.
"
"
if a:LastLine =~ a:Head
while 1
"
" Include the limit of the search to be the last line. BIG
" performance booster! That also means we only have to see *if*
" there was a match, and not worry about where it is.
"
"let pairstart = searchpair(a:Head, a:Mid, a:Tail, 'Wb')
"if pairstart == 0 || pairstart != a:LastLNum
let pairstart = searchpair(a:Head, a:Mid, a:Tail, 'Wb', '', a:LastLNum)
if pairstart == 0 "|| pairstart != a:LastLNum
break
endif
let syn = synIDattr(synID(line("."), col("."), 1), "name")
" Also continue on the off chance that we find the match on the
" current line. This shouldn't happen, but the pattern might
" start with whitespace.
if syn =~ b:commentRE || syn =~ b:stringRE || pairstart == origline
continue
endif
let levels += 1
endwhile
endif
" If we aren't within a level that was started on the last line, then
" check how many levels were closed on the last line.
"
if levels == 0
" Move to the beginning of the last line
call cursor(a:LastLNum,0)
normal ^
" If the line starts with an open, The close shouldn't be counted as
" such, because we're looking for closes that didn't start on this
" line.
if a:LastLine =~ '^\s*' . a:Head ||
\ (a:Mid != '' && a:LastLine =~ '^\s*' . a:Mid)
let levels = 1
endif
"
" Count the closes on the last line (i.e. LastLNum), stopping once
" we've hit comments. If the line doesn't even contain the end of the
" pair, don't bother with searchpair() (same aforementioned
" rationale).
"
if a:LastLine =~ a:Tail
while 1
"
" Include the limit of the search to be the last line. BIG
" performance booster! That also means we only have to see
" *if* there was a match, and not worry about where it is.
"
"let pairend = searchpair(a:Head, a:Mid, a:Tail, 'W')
"if pairend == 0 || a:LastLNum != pairend
"let pairend = searchpair(a:Head, a:Mid, a:Tail, 'W', '', a:LastLNum)
let pairend = searchpair(a:Head, a:Mid, a:Tail, 'W',
\'InCommentOrString()', a:LastLNum)
if pairend == 0 "|| a:LastLNum != pairend
" STARTS with a:Tail, since we already know the line
" matches it.
if b:lastclosed.at < col('.') && (
\ a:LastLine =~ '^\s*' . a:Tail
\ || (a:Mid != '' && a:LastLine =~ '^\s*' . a:Mid) )
let b:lastclosed = {
\ 'at' : col('.'),
\ 'head' : a:Head,
\ 'mid' : a:Mid,
\ 'tail' : a:Tail }
endif
break
endif
" This might not be needed with the expr included in the
" search call.
"let syn = synIDattr(synID(line("."), col("."), 1), "name")
"if syn =~ b:commentRE || syn =~ b:stringRE || syn == ''
" break
"endif
let levels -= 1
" Track the last close to try to match pairs that start on
" line continuations
if b:lastclosed.at < col('.')
let b:lastclosed = {
\ 'at' : col('.'),
\ 'head' : a:Head,
\ 'mid' : a:Mid,
\ 'tail' : a:Tail }
endif
endwhile
endif
endif
" This is redundant, as per above
" If the current line starts with a close, count it. It won't effect the
" indentation of the next line because it is the first thing on the line
" and won't be counted as a "close on the last line".
if a:CurrLine =~ '^\s*' . a:Tail
\ || (a:Mid != '' && a:CurrLine =~ '^\s*' . a:Mid)
let levels -= 1
endif
" Restore original cursor location
call cursor(origline, origcol)
let adj = &sw*levels
if adj != 0 && b:indent_anything_echo
let g:lastindent = g:lastindent .
\ "GetPairIndent(" . a:Head . "/" . b:lastclosed.at . "):" . adj . " "
endif
return adj
endfunction
function! s:GetContIndent(Rule, CurrLine, LastLine, LastLNum, PrevLNum)
let adj = 0
let origcol = col(".")
let origline = line(".")
let lastcont = 0
let prevcont = 0
let l:lastlnum = a:LastLNum
let l:prevlnum = a:PrevLNum
let l:preblockstart = -1
" Get the last matching line number. If the match occurs w/in a comment
" or string, then it's a non-match.
"
"let lastmatchlnum = search(a:Rule.pattern, 'Wb', a:PrevLNum)
let lastmatchlnum = search(a:Rule.pattern, 'Wb', a:LastLNum)
let syn = synIDattr(synID(line("."), col("."), 1), "name")
"if syn =~ b:commentRE || syn =~ b:stringRE
if syn =~ b:commentRE || syn =~ b:stringRE || b:lastclosed.at > 0
let lastmatchlnum = 0
endif
" Should be able to just search to the line....
" " Figure out the last and previous continuation status
" if lastmatchlnum && lastmatchlnum == a:LastLNum
" let lastcont = 1
" endif
if lastmatchlnum == a:LastLNum
let lastcont = 1
endif
" start checking at the start of the block that ended on the prev line
if b:lastclosed.at > 0
call cursor(a:LastLNum, b:lastclosed.at)
" TODO: add 'skip' to skip comments
let l:preblockstart = searchpair(b:lastclosed.head, b:lastclosed.mid, b:lastclosed.tail, 'bW')
let g:lastindent .= ' postpair ("' . b:lastclosed.head . '"): '
\ . l:preblockstart . '/' . col('.') . ' '
if b:contTraversesLineComments
let l:prevlnum = GetPrevNonBlankNonComment(line('.') - 1)
else
let l:prevlnum = prevnonblank(line('.') - 1)
endif
endif
" Get the previous matching line number. If the match occurs w/in a
" comment or string, then it's a non-match. Use the adjusted, local
" prevlnum as the limit of the search, since we don't care about matches
" beyond that.
let prevmatchlnum = search(a:Rule.pattern, 'Wb', l:prevlnum)
let syn = synIDattr(synID(line("."), col("."), 1), "name")
" Handle:
" if ()
" if () {
" this_line; // should not be reduced
"if syn =~ b:commentRE || syn =~ b:stringRE
if syn =~ b:commentRE || syn =~ b:stringRE
let prevmatchlnum = 0
endif
" Should be able to just search to the line....
" if ( lastmatchlnum && lastmatchlnum == a:PrevLNum )
" \ || ( prevmatchlnum && prevmatchlnum == l:prevlnum )
" let prevcont = 1
" endif
"
" If there is a previous line, it is a continued line, and we haven't
" already done a positive adjustment for a pair/block, then reduce.
" Don't undo a positive adjustment for a pair because the previous line
" was a continued line. That will happen after the end of the block.
"if prevmatchlnum == l:prevlnum && b:pairadj <= 0
if l:prevlnum && prevmatchlnum == l:prevlnum && b:pairadj <= 0
let prevcont = 1
endif
"echom "lastcont: " . lastcont .
" \ ", prevcont: " . prevcont .
" \ ", lastmatchlnum: " . lastmatchlnum .
" \ ", prevmatchlnum: " . prevmatchlnum .
" \ ", lastlnum: " . a:LastLNum .
" \ ", PrevLNum: " . a:PrevLNum
let firstcont = (lastcont && !prevcont)
let firstcont = ((lastcont && !prevcont) || (lastcont && b:pairadj))
" If we are adjusting the current line for a pair, then don't count this
" line as a post-continuation line. The post continuation line will be
" after the close of said pair.
let postcont = (!lastcont && prevcont)
"let postcont = (!lastcont && prevcont && !b:pairadj )
let g:lastindent .= 'lastcont (' . lastcont . '), prevcont (' . prevcont . ') '
"if firstcont && a:CurrLine !~ '^\s*{'
if firstcont
if has_key(a:Rule, 'ignore') && a:CurrLine =~ a:Rule.ignore
let g:lastindent .= "(ignoring '" . a:Rule.ignore . "') "
else
let adj = adj + &sw
endif
"elseif postcont && a:LastLine !~ '^\s*{' "&& !b:pairadj
elseif postcont
if has_key(a:Rule, 'ignore') && a:LastLine =~ a:Rule.ignore
let g:lastindent .= "(ignoring '" . a:Rule.ignore . "') "
else
let adj = adj - &sw
endif
endif
call cursor(origline, origcol)
if adj != 0 && b:indent_anything_echo
let g:lastindent = g:lastindent .
\ "GetContIndent('" . a:Rule.pattern . "'):" . adj . " "
endif
return adj
endfunction

View File

@@ -1,352 +0,0 @@
let g:indexed_search_colors=0
" File: IndexedSearch.vim
" Author: Yakov Lerner <iler.ml@gmail.com>
" URL: http://www.vim.org/scripts/script.php?script_id=1682
" Last change: 2006-11-21
"
" This script redefines 6 search commands (/,?,n,N,*,#). At each search,
" it shows at which match number you are, and the total number
" of matches, like this: "At Nth match out of M". This is printed
" at the bottom line at every n,N,/,?,*,# search command, automatically.
"
" To try out the plugin, source it and play with N,n,*,#,/,? commands.
" At the bottom line, you'll see wha it shows. There are no new
" commands and no new behavior to learn. Just additional info
" on the bottom line, whenever you perform search.
"
" Works on vim6 and vim7. On very large files, won't cause slowdown
" because it checks the file size.
" Don't use if you're sensitive to one of its components :-)
"
" I am posting this plugin because I find it useful.
" -----------------------------------------------------
" Checking Where You Are with respect to Search Matches
" .....................................................
" You can press \\ or \/ (that's backslach then slash),
" or :ShowSearchIndex to show at which match index you are,
" without moving cursor.
"
" If cursor is exactly on the match, the message is:
" At Nth match of M
" If cursor is between matches, following messages are displayed:
" Betwen matches 189-190 of 300
" Before first match, of 300
" After last match, of 300
" ------------------------------------------------------
" To disable colors for messages, set 'let g:indexed_search_colors=0'.
" ------------------------------------------------------
" Performance. Plugin bypasses match counting when it would take
" too much time (too many matches, too large file). You can
" tune performance limits below, after comment "Performance tuning limits"
" ------------------------------------------------------
" In case of bugs and wishes, please email: iler.ml at gmail.com
" ------------------------------------------------------
" before 061119, it worked only vim7 not on vim6 (we use winrestview())
" after 061119, works only on vim6 (we avoid winrestview on vim6)
"if version < 700 | finish | endif " we need vim7 at least. Won't work for vim6
"if &cp | echo "warning: IndexedSearch.vim need nocp" | finish | endif " we need &nocp mode
if exists("g:indexed_search_plugin") | finish | endif
let g:indexed_search_plugin = 1
if !exists('g:indexed_search_colors')
let g:indexed_search_colors=1 " 1-use colors for messages, 0-no colors
endif
if !exists('g:indexed_search_shortmess')
let g:indexed_search_shortmess=0 " 1-longer messages; 0(or undefined)-longer messages.
endif
" ------------------ "Performance tuning limits" -------------------
if !exists('g:search_index_max')
let g:search_index_max=30000 " max filesize(in lines) up to what
" ShowCurrentSearchIndex() works
endif
if !exists("g:search_index_maxhit")
let g:search_index_maxhit=1000
endif
" -------------- End of Performance tuning limits ------------------
let s:save_cpo = &cpo
set cpo&vim
command! ShowSearchIndex :call s:ShowCurrentSearchIndex(1,'')
" before 061114 we had op invocation inside the function but this
" did not properly keep @/ and direction (func.return restores @/ and direction)
" after 061114 invoking op inside the function does not work because
" @/ and direction is restored at return from function
" We must have op invocation at the toplevel of mapping even though this
" makes mappings longer.
nnoremap <silent>n :let v:errmsg=''<cr>:silent! norm! n<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
nnoremap <silent>N :let v:errmsg=''<cr>:silent! norm! N<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
nnoremap <silent>* :let v:errmsg=''<cr>:silent! norm! *<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
nnoremap <silent># :let v:errmsg=''<cr>:silent! norm! #<cr>:call <SID>ShowCurrentSearchIndex(0,'!')<cr>
nnoremap <silent>\/ :call <SID>ShowCurrentSearchIndex(1,'')<cr>
nnoremap <silent>\\ :call <SID>ShowCurrentSearchIndex(1,'')<cr>
nnoremap <silent>g/ :call <SID>ShowCurrentSearchIndex(1,'')<cr>
" before 061120, I had cmapping for <cr> which was very intrusive. Didn't work
" with supertab iInde<c-x><c-p>(resulted in something like recursive <c-r>=
" after 061120, I remap [/?] instead of remapping <cr>. Works in vim6, too
nnoremap / :call <SID>DelaySearchIndex(0,'')<cr>/
nnoremap ? :call <SID>DelaySearchIndex(0,'')<cr>?
let s:ScheduledEcho = ''
let s:DelaySearchIndex = 0
let g:IndSearchUT = &ut
func! s:ScheduleEcho(msg,highlight)
"if &ut > 50 | let g:IndSearchUT=&ut | let &ut=50 | endif
"if &ut > 100 | let g:IndSearchUT=&ut | let &ut=100 | endif
if &ut > 200 | let g:IndSearchUT=&ut | let &ut=200 | endif
" 061116 &ut is sometimes not restored and drops permanently to 50. But how ?
let s:ScheduledEcho = a:msg
let use_colors = !exists('g:indexed_search_colors') || g:indexed_search_colors
let s:ScheduledHighlight = ( use_colors ? a:highlight : "None" )
aug IndSearchEcho
au CursorHold *
\ exe 'set ut='.g:IndSearchUT |
\ if s:DelaySearchIndex | call s:ShowCurrentSearchIndex(0,'') |
\ let s:ScheduledEcho = s:Msg | let s:ScheduledHighlight = s:Highlight |
\ let s:DelaySearchIndex = 0 | endif |
\ if s:ScheduledEcho != ""
\ | exe "echohl ".s:ScheduledHighlight | echo s:ScheduledEcho | echohl None
\ | let s:ScheduledEcho='' |
\ endif |
\ aug IndSearchEcho | exe 'au!' | aug END | aug! IndSearchEcho
" how about moving contents of this au into function
aug END
endfun " s:ScheduleEcho
func! s:DelaySearchIndex(force,cmd)
let s:DelaySearchIndex = 1
call s:ScheduleEcho('','')
endfunc
func! s:ShowCurrentSearchIndex(force, cmd)
" NB: function saves and restores @/ and direction
" this used to cause me many troubles
call s:CountCurrentSearchIndex(a:force, a:cmd) " -> s:Msg, s:Highlight
if s:Msg != ""
call s:ScheduleEcho(s:Msg, s:Highlight )
endif
endfun
function! s:MilliSince( start )
" usage: let s = reltime() | sleep 100m | let milli = MilliSince(s)
let x = reltimestr( reltime( a:start ) )
" there can be leading spaces in x
let sec = substitute(x, '^ *\([0-9]\+\)', '\1', '')
let frac = substitute(x, '\.\([0-9]\+\)', '\1', '') . "000"
let milli = strpart( frac, 0, 3)
return sec * 1000 + milli
endfun
func! s:CountCurrentSearchIndex(force, cmd)
" sets globals -> s:Msg , s:Highlight
let s:Msg = '' | let s:Highlight = ''
let builtin_errmsg = ""
" echo "" | " make sure old msg is erased
if a:cmd == '!'
" if cmd is '!', we do not execute any command but report
" last errmsg
if v:errmsg != ""
echohl Error
echomsg v:errmsg
echohl None
endif
elseif a:cmd != ''
let v:errmsg = ""
silent! exe "norm! ".a:cmd
if v:errmsg != ""
echohl Error
echomsg v:errmsg
echohl None
endif
if line('$') >= g:search_index_max
" for large files, preserve original error messages and add nothing
return ""
endif
else
endif
if !a:force && line('$') >= g:search_index_max
let too_slow=1
" when too_slow, we'll want to switch the work over to CursorHold
return ""
endif
if @/ == '' | return "" | endif
if version >= 700
let save = winsaveview()
endif
let line = line('.')
let vcol = virtcol('.')
norm gg0
let num = 0 " total # of matches in the buffer
let exact = -1
let after = 0
let too_slow = 0 " if too_slow, we'll want to switch the work over to CursorHold
let s_opt = 'Wc'
while search(@/, s_opt) && ( num <= g:search_index_maxhit || a:force)
let num = num + 1
if line('.') == line && virtcol('.') == vcol
let exact = num
elseif line('.') < line || (line('.') == line && virtcol('.') < vcol)
let after = num
endif
let s_opt = 'W'
endwh
if version >= 700
call winrestview(save)
else
exe line
exe "norm! ".vcol."|"
endif
if !a:force && num > g:search_index_maxhit
if exact >= 0
let too_slow=1 " if too_slow, we'll want to switch the work over to CursorHold
let num=">".(num-1)
else
let s:Msg = ">".(num-1)." matches"
if v:errmsg != ""
let s:Msg = "" " avoid overwriting builtin errmsg with our ">1000 matches"
endif
return ""
endif
endif
let s:Highlight = "Directory"
if num == "0"
let s:Highlight = "Error"
let prefix = "No matches "
elseif exact == 1 && num==1
" s:Highlight remains default
"let prefix = "At single match"
let prefix = "Single match"
elseif exact == 1
let s:Highlight = "Search"
"let prefix = "At 1st match, # 1 of " . num
"let prefix = "First match, # 1 of " . num
let prefix = "First of " . num . " matches "
elseif exact == num
let s:Highlight = "LineNr"
"let prefix = "Last match, # ".num." of " . num
"let prefix = "At last match, # ".num." of " . num
let prefix = "Last of " . num . " matches "
elseif exact >= 0
"let prefix = "At # ".exact." match of " . num
"let prefix = "Match # ".exact." of " . num
"let prefix = "# ".exact." match of " . num
if exists('g:indexed_search_shortmess') && g:indexed_search_shortmess
let prefix = exact." of " . num . " matches "
else
let prefix = "Match ".exact." of " . num
endif
elseif after == 0
let s:Highlight = "MoreMsg"
let prefix = "Before first match, of ".num." matches "
if num == 1
let prefix = "Before single match"
endif
elseif after == num
let s:Highlight = "WarningMsg"
let prefix = "After last match of ".num." matches "
if num == 1
let prefix = "After single match"
endif
else
let prefix = "Between matches ".after."-".(after+1)." of ".num
endif
let s:Msg = prefix . " /".@/ . "/"
return ""
endfunc
" Messages Summary
"
" Short Message Long Message
" -------------------------------------------
" %d of %d matches Match %d of %d
" Last of %d matches <-same
" First of %d matches <-same
" No matchess <-same
" -------------------------------------------
let &cpo = s:save_cpo
" Last changes
" 2006-10-20 added limitation by # of matches
" 061021 lerner fixed problem with cmap <enter> that screwed maps
" 061021 colors added
" 061022 fixed g/ when too many matches
" 061106 got message to work with check for largefile right
" 061110 addition of DelayedEcho(ScheduledEcho) fixes and simplifies things
" 061110 mapping for nN*# greately simplifified by switching to ScheduledEcho
" 061110 fixed problem with i<c-o>/pat<cr> and c/PATTERN<CR> Markus Braun
" 061110 fixed bug in / and ?, Counting moved to Delayd
" 061110 fixed bug extra line+enter prompt in [/?] by addinf redraw
" 061110 fixed overwriting builtin errmsg with ">1000 matches"
" 061111 fixed bug with gg & 'set nosol' (gg->gg0)
" 061113 fixed mysterious eschewing of @/ wfte *,#
" 061113 fixed counting of match at the very beginning of file
" 061113 added msgs "Before single match", "After single match"
" 061113 fixed bug with &ut not always restored. This could happen if
" ScheduleEcho() was called twice in a row.
" 061114 fixed problem with **#n. Direction of the last n is incorrect (must be backward
" but was incorrectly forward)
" 061114 fixed disappearrance of "Hit BOTTOM" native msg when file<max and numhits>max
" 061116 changed hlgroup os "At last match" from DiffChange to LineNr. Looks more natural.
" 061120 shortened text messages.
" 061120 made to work on vim6
" 061120 bugfix for vim6 (virtcol() not col())
" 061120 another bug with virtcol() vs col()
" 061120 fixed [/?] on vim6 (vim6 doesn't have getcmdtype())
" 061121 fixed mapping in <cr> with supertab.vim. Switched to [/?] mapping, removed <cr> mapping.
" also shortened code considerably, made vim6 and vim7 work same way, removed need
" for getcmdtype().
" 061121 fixed handling of g:indexed_search_colors (Markus Braun)
" Wishlist
" - using high-precision timer of vim7, count number of millisec
" to run the counters, and base auto-disabling on time it takes.
" very complex regexes can be terribly slow even of files like 'man bash'
" which is mere 5k lines long. Also when there are >10k matches in the file
" set limit to 200 millisec
" - implement CursorHold bg counting to which too_slow will resort
" - even on large files, we can show "At last match", "After last match"
" - define global vars for all highlights, with defaults
" hh
" hh
" hh
" hh

View File

@@ -1,132 +0,0 @@
" endwise.vim - EndWise
" Author: Tim Pope <vimNOSPAM@tpope.info>
" Version: 1.0
" Distributable under the same terms as Vim itself (see :help license)
" Exit quickly when:
" - this plugin was already loaded (or disabled)
" - when 'compatible' is set
if (exists("g:loaded_endwise") && g:loaded_endwise) || &cp
finish
endif
let g:loaded_endwise = 1
let s:cpo_save = &cpo
set cpo&vim
augroup endwise " {{{1
au!
autocmd FileType ruby
\ let b:endwise_addition = '\=submatch(0)=="{" ? "}" : "end"' |
\ let b:endwise_words = 'module,class,def,if,unless,case,while,until,begin,do' |
\ let b:endwise_pattern = '^\s*\zs\%(module\|class\|def\|if\|unless\|case\|while\|until\|for\|\|begin\)\>\%(.*[^.:@$]\<end\>\)\@!\|\<do\ze\%(\s*|.*|\)\=\s*$' |
\ let b:endwise_syngroups = 'rubyModule,rubyClass,rubyDefine,rubyControl,rubyConditional,rubyRepeat'
autocmd FileType vb,vbnet,aspvbs
\ let b:endwise_addition = 'End &' |
\ let b:endwise_words = 'Function,Sub,Class,Module,Enum,Namespace' |
\ let b:endwise_pattern = '\%(\<End\>.*\)\@<!\<&\>' |
\ let b:endwise_syngroups = 'vbStatement,vbnetStorage,vbnetProcedure,vbnet.*Words,AspVBSStatement'
autocmd FileType vim
\ let b:endwise_addition = 'end&' |
\ let b:endwise_words = 'fu\%[nction],wh\%[ile],if,for,try' |
\ let b:endwise_syngroups = 'vimFuncKey,vimNotFunc,vimCommand'
augroup END " }}}1
" Maps {{{1
if maparg("<Plug>DiscretionaryEnd") == ""
inoremap <silent> <SID>DiscretionaryEnd <C-R>=<SID>crend(0)<CR>
inoremap <silent> <SID>AlwaysEnd <C-R>=<SID>crend(1)<CR>
imap <script> <Plug>DiscretionaryEnd <SID>DiscretionaryEnd
imap <script> <Plug>AlwaysEnd <SID>AlwaysEnd
endif
if maparg('<CR>','i') =~# '<C-R>=.*crend(.)<CR>\|<\%(Plug\|SID\)>.*End'
" Already mapped
elseif maparg('<CR>','i') =~ '<CR>'
exe "imap <script> <C-X><CR> ".maparg('<CR>','i')."<SID>AlwaysEnd"
exe "imap <script> <CR> ".maparg('<CR>','i')."<SID>DiscretionaryEnd"
else
imap <C-X><CR> <CR><Plug>AlwaysEnd
imap <CR> <CR><Plug>DiscretionaryEnd
endif
if maparg('<M-o>','i') == ''
inoremap <M-o> <C-O>o
endif
" }}}1
" Code {{{1
function! s:mysearchpair(beginpat,endpat,synpat)
let g:endwise_syntaxes = ""
let s:lastline = line('.')
call s:synname()
let line = searchpair(a:beginpat,'',a:endpat,'Wn','<SID>synname() !~# "^'.substitute(a:synpat,'\\','\\\\','g').'$"',line('.')+50)
return line
endfunction
function! s:crend(always)
let n = ""
if !exists("b:endwise_addition") || !exists("b:endwise_words") || !exists("b:endwise_syngroups")
return n
end
let synpat = '\%('.substitute(b:endwise_syngroups,',','\\|','g').'\)'
let wordchoice = '\%('.substitute(b:endwise_words,',','\\|','g').'\)'
if exists("b:endwise_pattern")
let beginpat = substitute(b:endwise_pattern,'&',substitute(wordchoice,'\\','\\&','g'),'g')
else
let beginpat = '\<'.wordchoice.'\>'
endif
let lnum = line('.') - 1
let space = matchstr(getline(lnum),'^\s*')
let col = match(getline(lnum),beginpat) + 1
let word = matchstr(getline(lnum),beginpat)
let endpat = substitute(word,'.*',b:endwise_addition,'')
let y = n.endpat."\<C-O>O"
let endpat = '\<'.substitute(wordchoice,'.*',b:endwise_addition,'').'\>'
if a:always
return y
elseif col <= 0 || synIDattr(synID(lnum,col,1),'name') !~ '^'.synpat.'$'
return n
elseif getline('.') !~ '^\s*#\=$'
return n
endif
let line = s:mysearchpair(beginpat,endpat,synpat)
" even is false if no end was found, or if the end found was less
" indented than the current line
let even = strlen(matchstr(getline(line),'^\s*')) >= strlen(space)
if line == 0
let even = 0
endif
let g:endwise_debug = line . "(" . even . ")"
if !even && line == line('.') + 1
return y
endif
if even
return n
endif
return y
endfunction
function! s:synname()
" Checking this helps to force things to stay in sync
while s:lastline < line('.')
let s = synIDattr(synID(s:lastline,indent(s:lastline)+1,1),'name')
let s:lastline = nextnonblank(s:lastline + 1)
endwhile
let s = synIDattr(synID(line('.'),col('.'),1),'name')
let g:endwise_syntaxes = g:endwise_syntaxes . line('.').','.col('.')."=".s."\n"
let s:lastline = line('.')
return s
endfunction
" }}}1
let &cpo = s:cpo_save
" vim:set ft=vim ff=unix ts=8 sw=4 sts=4:

View File

@@ -1,15 +0,0 @@
" via: http://vim.wikia.com/wiki/HTML_entities
function HtmlEscape()
silent s/&/\&amp;/eg
silent s/</\&lt;/eg
silent s/>/\&gt;/eg
endfunction
function HtmlUnEscape()
silent s/&lt;/</eg
silent s/&gt;/>/eg
silent s/&amp;/\&/eg
endfunction
map <silent> <c-h> :call HtmlEscape()<CR>
map <silent> <c-u> :call HtmlUnEscape()<CR>