" Vim plugin for showing matching parens" Maintainer: Bram Moolenaar <Bram@vim.org>" Last Change: 2016 Feb 16" Exit quickly when:" - this plugin was already loaded (or disabled)" - when 'compatible' is set" - the "CursorMoved" autocmd event is not available.if exists("g:loaded_matchparen") || &cp || !exists("##CursorMoved")finishendiflet g:loaded_matchparen = 1if !exists("g:matchparen_timeout")let g:matchparen_timeout = 300endifif !exists("g:matchparen_insert_timeout")let g:matchparen_insert_timeout = 60endifaugroup matchparen" Replace all matchparen autocommandsautocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()if exists('##TextChanged')autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair()endifaugroup END" Skip the rest if it was already done.if exists("*s:Highlight_Matching_Pair")finishendiflet s:cpo_save = &cposet cpo-=C" The function that is invoked (very often) to define a ":match" highlighting" for any matching paren.function! s:Highlight_Matching_Pair()" Remove any previous match.if exists('w:paren_hl_on') && w:paren_hl_onsilent! call matchdelete(3)let w:paren_hl_on = 0endif" Avoid that we remove the popup menu." Return when there are no colors (looks like the cursor jumps).if pumvisible() || (&t_Co < 8 && !has("gui_running"))returnendif" Get the character under the cursor and check if it's in 'matchpairs'.let c_lnum = line('.')let c_col = col('.')let before = 0let text = getline(c_lnum)let matches = matchlist(text, '\(.\)\=\%'.c_col.'c\(.\=\)')if empty(matches)let [c_before, c] = ['', '']elselet [c_before, c] = matches[1:2]endiflet plist = split(&matchpairs, '.\zs[:,]')let i = index(plist, c)if i < 0" not found, in Insert mode try character before the cursorif c_col > 1 && (mode() == 'i' || mode() == 'R')let before = strlen(c_before)let c = c_beforelet i = index(plist, c)endifif i < 0" not found, nothing to doreturnendifendif" Figure out the arguments for searchpairpos().if i % 2 == 0let s_flags = 'nW'let c2 = plist[i + 1]elselet s_flags = 'nbW'let c2 = clet c = plist[i - 1]endifif c == '['let c = '\['let c2 = '\]'endif" Find the match. When it was just before the cursor move it there for a" moment.if before > 0let has_getcurpos = exists("*getcurpos")if has_getcurpos" getcurpos() is more efficient but doesn't exist before 7.4.313.let save_cursor = getcurpos()elselet save_cursor = winsaveview()endifcall cursor(c_lnum, c_col - before)endif" Build an expression that detects whether the current cursor position is in" certain syntax types (string, comment, etc.), for use as searchpairpos()'s" skip argument." We match "escape" for special items, such as lispEscapeSpecial.let s_skip = '!empty(filter(map(synstack(line("."), col(".")), ''synIDattr(v:val, "name")''), ' .\ '''v:val =~? "string\\|character\\|singlequote\\|escape\\|comment"''))'" If executing the expression determines that the cursor is currently in" one of the syntax types, then we want searchpairpos() to find the pair" within those syntax types (i.e., not skip). Otherwise, the cursor is" outside of the syntax types and s_skip should keep its value so we skip any" matching pair inside the syntax types.execute 'if' s_skip '| let s_skip = 0 | endif'" Limit the search to lines visible in the window.let stoplinebottom = line('w$')let stoplinetop = line('w0')if i % 2 == 0let stopline = stoplinebottomelselet stopline = stoplinetopendif" Limit the search time to 300 msec to avoid a hang on very long lines." This fails when a timeout is not supported.if mode() == 'i' || mode() == 'R'let timeout = exists("b:matchparen_insert_timeout") ? b:matchparen_insert_timeout : g:matchparen_insert_timeoutelselet timeout = exists("b:matchparen_timeout") ? b:matchparen_timeout : g:matchparen_timeoutendiftrylet [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, timeout)catch /E118/" Can't use the timeout, restrict the stopline a bit more to avoid taking" a long time on closed folds and long lines." The "viewable" variables give a range in which we can scroll while" keeping the cursor at the same position." adjustedScrolloff accounts for very large numbers of scrolloff.let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])" one of these stoplines will be adjusted below, but the current values are" minimal boundaries within the current windowif i % 2 == 0if has("byte_offset") && has("syntax_items") && &smc > 0let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])let stopline = min([bottom_viewable, byte2line(stopbyte)])elselet stopline = min([bottom_viewable, c_lnum + 100])endiflet stoplinebottom = stoplineelseif has("byte_offset") && has("syntax_items") && &smc > 0let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])let stopline = max([top_viewable, byte2line(stopbyte)])elselet stopline = max([top_viewable, c_lnum - 100])endiflet stoplinetop = stoplineendiflet [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)endtryif before > 0if has_getcurposcall setpos('.', save_cursor)elsecall winrestview(save_cursor)endifendif" If a match is found setup match highlighting.if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottomif exists('*matchaddpos')call matchaddpos('MatchParen', [[c_lnum, c_col - before], [m_lnum, m_col]], 10, 3)elseexe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .\ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'endiflet w:paren_hl_on = 1endifendfunction" Define commands that will disable and enable the plugin.command! NoMatchParen windo silent! call matchdelete(3) | unlet! g:loaded_matchparen |\ au! matchparencommand! DoMatchParen runtime plugin/matchparen.vim | windo doau CursorMovedlet &cpo = s:cpo_saveunlet s:cpo_save
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。