<s> import sublime , sublime_plugin <EOL> import re , time <EOL> from collections import namedtuple <EOL> BracketPosition = namedtuple ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> BracketResult = namedtuple ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> bracketGuardRegions = "<STR_LIT>" <EOL> class EventListener ( sublime_plugin . EventListener ) : <EOL> def __init__ ( self ) : <EOL> self . latest_keypresses = { } <EOL> def on_modified ( self , view ) : <EOL> if view . settings ( ) . get ( "<STR_LIT>" , False ) : <EOL> self . highlightBracketError ( view ) <EOL> def on_modified_async ( self , view ) : <EOL> self . clearRegions ( view ) <EOL> if self . doAutoCheck ( view ) : <EOL> self . debounce ( view , "<STR_LIT>" , self . highlightBracketError ) <EOL> def on_post_save_async ( self , view ) : <EOL> if self . checkOnSave ( ) and not self . doAutoCheck ( view ) : <EOL> self . highlightBracketError ( view ) <EOL> def clearRegions ( self , view ) : <EOL> view . erase_regions ( bracketGuardRegions ) <EOL> def settings ( self ) : <EOL> return sublime . load_settings ( "<STR_LIT>" ) <EOL> def checkOnSave ( self ) : <EOL> return self . settings ( ) . get ( "<STR_LIT>" ) <EOL> def doAutoCheck ( self , view ) : <EOL> threshold = self . settings ( ) . get ( "<STR_LIT>" ) <EOL> return threshold == - <NUM_LIT:1> or threshold >= view . size ( ) <EOL> def highlightBracketError ( self , view ) : <EOL> bracketResult = self . getFirstBracketError ( view ) <EOL> if not bracketResult . success : <EOL> openerRegion = sublime . Region ( bracketResult . start , bracketResult . start + <NUM_LIT:1> ) <EOL> closerRegion = sublime . Region ( bracketResult . end , bracketResult . end + <NUM_LIT:1> ) <EOL> view . add_regions ( bracketGuardRegions , [ openerRegion , closerRegion ] , "<STR_LIT>" ) <EOL> def debounce ( self , view , event_type , func ) : <EOL> key = ( event_type , view . file_name ( ) ) <EOL> this_keypress = time . time ( ) <EOL> self . latest_keypresses [ key ] = this_keypress <EOL> debounceTime = self . settings ( ) . get ( "<STR_LIT>" , <NUM_LIT> ) <EOL> def callback ( ) : <EOL> latest_keypress = self . latest_keypresses . get ( key , None ) <EOL> if this_keypress == latest_keypress : <EOL> func ( view ) <EOL> sublime . set_timeout_async ( callback , debounceTime ) <EOL> def getFirstBracketError ( self , view ) : <EOL> opener = list ( "<STR_LIT>" ) <EOL> closer = list ( "<STR_LIT>" ) <EOL> matchingStack = [ ] <EOL> successResult = BracketResult ( True , - <NUM_LIT:1> , - <NUM_LIT:1> ) <EOL> codeStr = view . substr ( sublime . Region ( <NUM_LIT:0> , view . size ( ) ) ) <EOL> for index , char in enumerate ( codeStr ) : <EOL> if char not in opener and not char in closer : <EOL> continue <EOL> scopeName = view . scope_name ( index ) <EOL> hasScope = lambda s : s in scopeName <EOL> markdownBracketScopeBegin = "<STR_LIT>" <EOL> markdownBracketScopeEnd = "<STR_LIT>" <EOL> isMarkdownStringBeginOrEnd = lambda s : hasScope ( markdownBracketScopeBegin ) or hasScope ( markdownBracketScopeEnd ) <EOL> if hasScope ( "<STR_LIT:string>" ) and not hasScope ( "<STR_LIT>" ) and not isMarkdownStringBeginOrEnd ( markdownBracketScopeBegin ) or hasScope ( "<STR_LIT>" ) : <EOL> continue <EOL> if char in opener : <EOL> matchingStack . append ( BracketPosition ( index , char ) ) <EOL> elif char in closer : <EOL> matchingOpener = opener [ closer . index ( char ) ] <EOL> if len ( matchingStack ) == <NUM_LIT:0> : <EOL> return BracketResult ( False , - <NUM_LIT:1> , index ) <EOL> poppedOpener = matchingStack . pop ( ) <EOL> if matchingOpener != poppedOpener . opener : <EOL> return BracketResult ( False , poppedOpener . position , index ) <EOL> if len ( matchingStack ) == <NUM_LIT:0> : <EOL> return successResult <EOL> else : <EOL> poppedOpener = matchingStack . pop ( ) <EOL> return BracketResult ( False , poppedOpener . position , - <NUM_LIT:1> ) </s>
