<s> import sublime , sublime_plugin , subprocess , threading , json , re , platform , sys , os <EOL> ON_WINDOWS = platform . system ( ) is '<STR_LIT>' <EOL> ST2 = sys . version_info < ( <NUM_LIT:3> , <NUM_LIT:0> ) <EOL> class NodeCheck : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self ) : <EOL> self . works = False <EOL> self . checkDone = False <EOL> self . nodeName = "<STR_LIT>" <EOL> def mightWork ( self , path ) : <EOL> if ( self . checkDone ) : <EOL> return self . works <EOL> if ( path ) : <EOL> self . nodeName = path <EOL> self . tryWithSelfName ( ) <EOL> if ( self . works is False ) : <EOL> sublime . error_message ( "<STR_LIT>" ) <EOL> return self . works <EOL> def tryWithSelfName ( self ) : <EOL> try : <EOL> subprocess . Popen ( [ self . nodeName , "<STR_LIT>" ] , bufsize = <NUM_LIT:1> , stdin = None , stdout = None , stderr = None , startupinfo = getStartupInfo ( ) ) <EOL> self . works = True <EOL> except OSError as e : <EOL> self . works = False <EOL> NODE = NodeCheck ( ) <EOL> AM_I_FORMATTING_AFTER_SAVE = False <EOL> if not ON_WINDOWS : <EOL> os . environ [ '<STR_LIT>' ] += '<STR_LIT>' <EOL> def getNpmGlobalRoot ( ) : <EOL> try : <EOL> return subprocess . check_output ( [ "<STR_LIT>" , "<STR_LIT:root>" , "<STR_LIT>" ] ) . rstrip ( ) . decode ( '<STR_LIT:utf-8>' ) <EOL> except : <EOL> return None <EOL> npmRoot = getNpmGlobalRoot ( ) <EOL> if npmRoot : <EOL> if hasattr ( os . environ , '<STR_LIT>' ) : <EOL> os . environ [ '<STR_LIT>' ] += os . pathsep + npmRoot <EOL> else : <EOL> os . environ [ '<STR_LIT>' ] = npmRoot <EOL> class EsformatterCommand ( sublime_plugin . TextCommand ) : <EOL> def run ( self , edit , save = False , ignoreSelection = False ) : <EOL> settings = sublime . load_settings ( "<STR_LIT>" ) <EOL> if ( NODE . mightWork ( settings . get ( "<STR_LIT>" ) ) == False ) : <EOL> return <EOL> if ( ignoreSelection or len ( self . view . sel ( ) ) == <NUM_LIT:1> and self . view . sel ( ) [ <NUM_LIT:0> ] . empty ( ) ) : <EOL> textContent = self . view . substr ( sublime . Region ( <NUM_LIT:0> , self . view . size ( ) ) ) <EOL> thread = NodeCall ( textContent , getFilePath ( self . view ) ) <EOL> thread . start ( ) <EOL> self . handle_thread ( thread , lambda : self . replaceFile ( thread , save ) ) <EOL> else : <EOL> threads = [ ] <EOL> for selection in self . view . sel ( ) : <EOL> region = self . view . line ( selection ) <EOL> textContent = self . view . substr ( region ) <EOL> thread = NodeCall ( textContent , getFilePath ( self . view ) , len ( threads ) , region ) <EOL> threads . append ( thread ) <EOL> thread . start ( ) <EOL> self . handle_threads ( threads , lambda process , lastError : self . handleSyntaxErrors ( process , lastError ) ) <EOL> def replaceFile ( self , thread , save = False ) : <EOL> '''<STR_LIT>''' <EOL> if thread . code == thread . result . encode ( '<STR_LIT:utf-8>' ) : <EOL> return <EOL> self . view . run_command ( "<STR_LIT>" , { "<STR_LIT:text>" : thread . result } ) <EOL> sublime . status_message ( "<STR_LIT>" ) <EOL> if ( save ) : <EOL> self . view . run_command ( "<STR_LIT>" ) <EOL> def handleSyntaxErrors ( self , threads = None , lastError = None ) : <EOL> '''<STR_LIT>''' <EOL> if ( lastError is None and threads is not None ) : <EOL> self . replaceSelections ( threads , None ) <EOL> else : <EOL> threads = [ ] <EOL> for selection in self . view . sel ( ) : <EOL> textContent = self . view . substr ( selection ) <EOL> thread = NodeCall ( textContent , getFilePath ( self . view ) , len ( threads ) , selection ) <EOL> threads . append ( thread ) <EOL> thread . start ( ) <EOL> self . handle_threads ( threads , lambda process , lastError : self . replaceSelections ( process , lastError ) ) <EOL> def replaceSelections ( self , threads , lastError ) : <EOL> '''<STR_LIT>''' <EOL> if ( lastError ) : <EOL> sublime . error_message ( "<STR_LIT>" + lastError ) <EOL> else : <EOL> offset = <NUM_LIT:0> <EOL> regions = [ ] <EOL> for thread in sorted ( threads , key = lambda t : t . region . begin ( ) ) : <EOL> if thread . code == thread . result . encode ( '<STR_LIT:utf-8>' ) : <EOL> continue <EOL> if offset : <EOL> region = [ thread . region . begin ( ) + offset , thread . region . end ( ) + offset , thread . result ] <EOL> else : <EOL> region = [ thread . region . begin ( ) , thread . region . end ( ) , thread . result ] <EOL> offset += len ( thread . result ) - len ( thread . code ) <EOL> regions . append ( region ) <EOL> self . view . run_command ( "<STR_LIT>" , { "<STR_LIT>" : regions } ) <EOL> def handle_thread ( self , thread , callback ) : <EOL> if thread . is_alive ( ) : <EOL> sublime . set_timeout ( lambda : self . handle_thread ( thread , callback ) , <NUM_LIT:100> ) <EOL> elif thread . result is not False : <EOL> callback ( ) <EOL> else : <EOL> sublime . error_message ( "<STR_LIT>" + thread . error ) <EOL> def handle_threads ( self , threads , callback , process = False , lastError = None ) : <EOL> next_threads = [ ] <EOL> if process is False : <EOL> process = [ ] <EOL> for thread in threads : <EOL> if thread . is_alive ( ) : <EOL> next_threads . append ( thread ) <EOL> continue <EOL> if thread . result is False : <EOL> lastError = thread . error <EOL> continue <EOL> process . append ( thread ) <EOL> if len ( next_threads ) : <EOL> sublime . set_timeout ( lambda : self . handle_threads ( next_threads , callback , process , lastError ) , <NUM_LIT:100> ) <EOL> else : <EOL> callback ( process , lastError ) <EOL> class NodeCall ( threading . Thread ) : <EOL> def __init__ ( self , code , path , id = <NUM_LIT:0> , region = None ) : <EOL> self . code = code . encode ( '<STR_LIT:utf-8>' ) <EOL> self . region = region <EOL> self . result = None <EOL> threading . Thread . __init__ ( self ) <EOL> def run ( self ) : <EOL> try : <EOL> process = subprocess . Popen ( <EOL> [ "<STR_LIT>" ] , <EOL> bufsize = <NUM_LIT> * len ( self . code ) , <EOL> stdin = subprocess . PIPE , <EOL> stdout = subprocess . PIPE , <EOL> stderr = subprocess . PIPE , <EOL> startupinfo = getStartupInfo ( ) ) <EOL> if ST2 : <EOL> stdout , stderr = process . communicate ( self . code ) <EOL> self . result = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , stdout ) . decode ( '<STR_LIT:utf-8>' ) <EOL> else : <EOL> stdout , stderr = process . communicate ( self . code ) <EOL> self . result = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , str ( stdout , encoding = '<STR_LIT:utf-8>' ) ) <EOL> if stderr : <EOL> self . result = False <EOL> if ST2 : <EOL> self . error = str ( stderr . decode ( '<STR_LIT:utf-8>' ) ) <EOL> else : <EOL> self . error = str ( stderr , encoding = '<STR_LIT:utf-8>' ) <EOL> except Exception as e : <EOL> self . result = False <EOL> self . error = str ( e ) <EOL> def getStartupInfo ( ) : <EOL> if ON_WINDOWS : <EOL> info = subprocess . STARTUPINFO ( ) <EOL> info . dwFlags |= subprocess . STARTF_USESHOWWINDOW <EOL> info . wShowWindow = subprocess . SW_HIDE <EOL> return info <EOL> return None <EOL> def getFilePath ( view ) : <EOL> path = view . file_name ( ) <EOL> if ( path ) : <EOL> return str ( path ) <EOL> else : <EOL> return '<STR_LIT>' ; <EOL> class EsformatUpdateContent ( sublime_plugin . TextCommand ) : <EOL> def run ( self , edit , text = None , regions = None ) : <EOL> if text : <EOL> self . view . replace ( edit , sublime . Region ( <NUM_LIT:0> , self . view . size ( ) ) , text ) <EOL> else : <EOL> for region in regions : <EOL> self . view . replace ( edit , sublime . Region ( region [ <NUM_LIT:0> ] , region [ <NUM_LIT:1> ] ) , region [ <NUM_LIT:2> ] ) <EOL> class EsformatEventListener ( sublime_plugin . EventListener ) : <EOL> def on_pre_save ( self , view ) : <EOL> global AM_I_FORMATTING_AFTER_SAVE <EOL> if AM_I_FORMATTING_AFTER_SAVE : <EOL> AM_I_FORMATTING_AFTER_SAVE = False <EOL> return <EOL> AM_I_FORMATTING_AFTER_SAVE = True <EOL> settings = sublime . load_settings ( "<STR_LIT>" ) <EOL> if ( settings . get ( "<STR_LIT>" ) and self . isJavascript ( view ) ) : <EOL> view . window ( ) . run_command ( "<STR_LIT>" , { <EOL> "<STR_LIT>" : True , <EOL> "<STR_LIT>" : True <EOL> } ) <EOL> def isJavascript ( self , view ) : <EOL> name = view . file_name ( ) <EOL> if ( name and os . path . splitext ( name ) [ <NUM_LIT:1> ] [ <NUM_LIT:1> : ] in [ "<STR_LIT>" ] ) : <EOL> return True <EOL> syntax = view . settings ( ) . get ( "<STR_LIT>" ) <EOL> if ( syntax and "<STR_LIT>" in syntax . split ( "<STR_LIT:/>" ) [ - <NUM_LIT:1> ] . lower ( ) ) : <EOL> return True <EOL> return False </s>
