<s> import os <EOL> import time <EOL> import hashlib <EOL> import collections <EOL> import webbrowser <EOL> try : <EOL> import ssl <EOL> assert ssl <EOL> except ImportError : <EOL> ssl = False <EOL> try : <EOL> unicode ( ) <EOL> except NameError : <EOL> unicode = str <EOL> import vim <EOL> try : <EOL> from . import editor <EOL> from . common import msg , shared as G , utils <EOL> from . view import View <EOL> from . common . handlers import floo_handler <EOL> assert G and msg and utils <EOL> except ImportError : <EOL> from floo import editor <EOL> from common import msg , shared as G , utils <EOL> from common . handlers import floo_handler <EOL> from view import View <EOL> def get_buf ( view ) : <EOL> if not ( G . AGENT and G . AGENT . is_ready ( ) ) : <EOL> return <EOL> return G . AGENT . get_buf_by_path ( view . file_name ( ) ) <EOL> def send_summon ( buf_id , sel ) : <EOL> highlight_json = { <EOL> '<STR_LIT:id>' : buf_id , <EOL> '<STR_LIT:name>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : sel , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } <EOL> if G . AGENT and G . AGENT . is_ready ( ) : <EOL> G . AGENT . send ( highlight_json ) <EOL> class VimHandler ( floo_handler . FlooHandler ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( VimHandler , self ) . __init__ ( * args , ** kwargs ) <EOL> self . user_highlights = { } <EOL> def tick ( self ) : <EOL> reported = set ( ) <EOL> while self . views_changed : <EOL> v , buf = self . views_changed . pop ( ) <EOL> if not G . AGENT or not G . AGENT . joined_workspace : <EOL> msg . debug ( '<STR_LIT>' ) <EOL> continue <EOL> if '<STR_LIT>' not in G . PERMS : <EOL> continue <EOL> if '<STR_LIT>' not in buf : <EOL> msg . debug ( '<STR_LIT>' % ( buf [ '<STR_LIT:id>' ] , buf [ '<STR_LIT:path>' ] ) ) <EOL> continue <EOL> view = View ( v ) <EOL> if view . is_loading ( ) : <EOL> msg . debug ( '<STR_LIT>' % buf [ '<STR_LIT:id>' ] ) <EOL> continue <EOL> if view . native_id in reported : <EOL> continue <EOL> reported . add ( view . native_id ) <EOL> patch = utils . FlooPatch ( view . get_text ( ) , buf ) <EOL> buf [ '<STR_LIT>' ] = patch . current <EOL> buf [ '<STR_LIT>' ] = hashlib . md5 ( patch . current . encode ( '<STR_LIT:utf-8>' ) ) . hexdigest ( ) <EOL> self . send ( patch . to_json ( ) ) <EOL> reported = set ( ) <EOL> while self . selection_changed : <EOL> v , buf , summon = self . selection_changed . pop ( ) <EOL> if not G . AGENT or not G . AGENT . joined_workspace : <EOL> msg . debug ( '<STR_LIT>' ) <EOL> continue <EOL> if '<STR_LIT>' not in G . PERMS : <EOL> continue <EOL> view = View ( v ) <EOL> vb_id = view . native_id <EOL> if vb_id in reported : <EOL> continue <EOL> reported . add ( vb_id ) <EOL> highlight_json = { <EOL> '<STR_LIT:id>' : buf [ '<STR_LIT:id>' ] , <EOL> '<STR_LIT:name>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : view . get_selections ( ) , <EOL> '<STR_LIT>' : summon , <EOL> '<STR_LIT>' : summon , <EOL> } <EOL> self . send ( highlight_json ) <EOL> def maybe_selection_changed ( self , vim_buf , is_ping ) : <EOL> buf = self . get_buf_by_path ( vim_buf . name ) <EOL> if not buf : <EOL> msg . debug ( '<STR_LIT>' % vim_buf . number ) <EOL> return <EOL> view = self . get_view ( buf [ '<STR_LIT:id>' ] ) <EOL> msg . debug ( "<STR_LIT>" % ( vim_buf . number , buf [ '<STR_LIT:id>' ] , view ) ) <EOL> self . selection_changed . append ( [ vim_buf , buf , is_ping ] ) <EOL> def maybe_buffer_changed ( self , vim_buf ) : <EOL> buf = self . get_buf_by_path ( vim_buf . name ) <EOL> if not buf or '<STR_LIT>' not in buf : <EOL> return <EOL> if buf [ '<STR_LIT>' ] != vim_buf [ : ] : <EOL> self . views_changed . append ( [ vim_buf , buf ] ) <EOL> def create_view ( self , buf ) : <EOL> path = buf [ '<STR_LIT:path>' ] <EOL> utils . save_buf ( buf ) <EOL> vb = self . get_vim_buf_by_path ( path ) <EOL> if vb : <EOL> return View ( vb ) <EOL> vim . command ( '<STR_LIT>' % path ) <EOL> vb = self . get_vim_buf_by_path ( path ) <EOL> if vb is None : <EOL> msg . debug ( '<STR_LIT>' % path ) <EOL> return <EOL> return View ( vb ) <EOL> def stomp_prompt ( self , changed_bufs , missing_bufs , new_files , ignored , cb ) : <EOL> def pluralize ( arg ) : <EOL> return arg != <NUM_LIT:1> and '<STR_LIT:s>' or '<STR_LIT>' <EOL> overwrite_local = '<STR_LIT>' <EOL> overwrite_remote = '<STR_LIT>' <EOL> missing = [ buf [ '<STR_LIT:path>' ] for buf in missing_bufs ] <EOL> changed = [ buf [ '<STR_LIT:path>' ] for buf in changed_bufs ] <EOL> to_upload = set ( new_files + changed ) . difference ( set ( ignored ) ) <EOL> to_remove = missing + ignored <EOL> to_fetch = changed + missing <EOL> to_upload_len = len ( to_upload ) <EOL> to_remove_len = len ( to_remove ) <EOL> remote_len = to_remove_len + to_upload_len <EOL> to_fetch_len = len ( to_fetch ) <EOL> if not to_fetch : <EOL> overwrite_local = '<STR_LIT>' <EOL> elif to_fetch_len < <NUM_LIT:5> : <EOL> overwrite_local = '<STR_LIT>' % '<STR_LIT:U+002CU+0020>' . join ( to_fetch ) <EOL> else : <EOL> overwrite_local = '<STR_LIT>' % ( to_fetch_len , pluralize ( to_fetch_len ) ) <EOL> if to_upload_len < <NUM_LIT:5> : <EOL> to_upload_str = '<STR_LIT>' % '<STR_LIT:U+002CU+0020>' . join ( to_upload ) <EOL> else : <EOL> to_upload_str = '<STR_LIT>' % to_upload_len <EOL> if to_remove_len < <NUM_LIT:5> : <EOL> to_remove_str = '<STR_LIT>' % '<STR_LIT:U+002CU+0020>' . join ( to_remove ) <EOL> else : <EOL> to_remove_str = '<STR_LIT>' % to_remove_len <EOL> if to_upload : <EOL> overwrite_remote += to_upload_str <EOL> if to_remove : <EOL> overwrite_remote += '<STR_LIT>' <EOL> if to_remove : <EOL> overwrite_remote += to_remove_str <EOL> if remote_len >= <NUM_LIT:5> and overwrite_remote : <EOL> overwrite_remote += '<STR_LIT>' <EOL> overwrite_remote = overwrite_remote . capitalize ( ) <EOL> action = '<STR_LIT>' <EOL> choices = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> prompt = '<STR_LIT>' <EOL> prompt += '<STR_LIT>' % ( action , remote_len , pluralize ( remote_len ) , overwrite_remote ) <EOL> prompt += '<STR_LIT>' % ( action , to_fetch_len , pluralize ( to_fetch_len ) , overwrite_local ) <EOL> prompt += "<STR_LIT>" <EOL> choice = editor . vim_choice ( prompt , choices [ <NUM_LIT:0> ] , choices ) <EOL> try : <EOL> return cb ( choices . index ( choice ) ) <EOL> except ValueError : <EOL> return cb ( - <NUM_LIT:1> ) <EOL> def ok_cancel_dialog ( self , msg , cb = None ) : <EOL> res = editor . ok_cancel_dialog ( msg ) <EOL> return ( cb and cb ( res ) or res ) <EOL> def get_view_text_by_path ( self , rel_path ) : <EOL> vb = self . get_vim_buf_by_path ( rel_path ) <EOL> return vb and vb [ : ] <EOL> def get_vim_buf_by_path ( self , p ) : <EOL> for vim_buf in vim . buffers : <EOL> if vim_buf . name and p == utils . to_rel_path ( vim_buf . name ) : <EOL> return vim_buf <EOL> return None <EOL> def get_view ( self , buf_id ) : <EOL> buf = self . bufs . get ( buf_id ) <EOL> if not buf : <EOL> return None <EOL> vb = self . get_vim_buf_by_path ( buf [ '<STR_LIT:path>' ] ) <EOL> if not vb : <EOL> return None <EOL> if vim . eval ( '<STR_LIT>' % vb . number ) == '<STR_LIT:0>' : <EOL> return None <EOL> return View ( vb ) <EOL> def save_view ( self , view ) : <EOL> self . ignored_saves [ view . native_id ] += <NUM_LIT:1> <EOL> view . save ( ) <EOL> def reset ( self ) : <EOL> super ( self . __class__ , self ) . reset ( ) <EOL> self . on_clone = { } <EOL> self . create_buf_cbs = { } <EOL> self . temp_disable_stalk = False <EOL> self . temp_ignore_highlight = { } <EOL> self . temp_ignore_highlight = { } <EOL> self . views_changed = [ ] <EOL> self . selection_changed = [ ] <EOL> self . ignored_saves = collections . defaultdict ( int ) <EOL> self . chat_deck = collections . deque ( maxlen = <NUM_LIT:50> ) <EOL> def send_msg ( self , text ) : <EOL> data = { <EOL> '<STR_LIT:name>' : '<STR_LIT>' , <EOL> '<STR_LIT:data>' : text , <EOL> } <EOL> self . send ( data ) <EOL> self . on_msg ( data ) <EOL> def chat ( self , username , timestamp , message , self_msg = False ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def prompt_join_hangout ( self , hangout_url ) : <EOL> if not utils . has_browser ( ) : <EOL> return <EOL> hangout_client = None <EOL> users = self . workspace_info . get ( '<STR_LIT>' ) <EOL> for user_id , user in users . items ( ) : <EOL> if user [ '<STR_LIT:username>' ] == G . USERNAME and '<STR_LIT>' in user [ '<STR_LIT>' ] : <EOL> hangout_client = user <EOL> break <EOL> if hangout_client : <EOL> return <EOL> choice = editor . vim_choice ( '<STR_LIT>' , '<STR_LIT:yes>' , [ '<STR_LIT:yes>' , '<STR_LIT>' ] ) <EOL> if choice == '<STR_LIT:yes>' : <EOL> webbrowser . open ( hangout_url , new = <NUM_LIT:2> , autoraise = True ) <EOL> def on_msg ( self , data ) : <EOL> timestamp = data . get ( '<STR_LIT:time>' ) or time . time ( ) <EOL> message = msg . MSG ( data . get ( '<STR_LIT:data>' , '<STR_LIT>' ) , timestamp , data . get ( '<STR_LIT:username>' , '<STR_LIT>' ) ) <EOL> message . display ( ) <EOL> self . chat_deck . appendleft ( message ) <EOL> def get_messages ( self ) : <EOL> return list ( self . chat_deck ) <EOL> def get_username_by_id ( self , user_id ) : <EOL> try : <EOL> return self . workspace_info [ '<STR_LIT>' ] [ str ( user_id ) ] [ '<STR_LIT:username>' ] <EOL> except Exception : <EOL> return '<STR_LIT>' <EOL> def get_buf ( self , buf_id , view = None ) : <EOL> req = { <EOL> '<STR_LIT:name>' : '<STR_LIT>' , <EOL> '<STR_LIT:id>' : buf_id <EOL> } <EOL> buf = self . bufs . get ( buf_id ) <EOL> if buf : <EOL> msg . warn ( '<STR_LIT>' % buf [ '<STR_LIT:path>' ] ) <EOL> if '<STR_LIT>' in buf : <EOL> del buf [ '<STR_LIT>' ] <EOL> if view : <EOL> view . set_read_only ( True ) <EOL> view . set_status ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> G . AGENT . send ( req ) <EOL> def delete_buf ( self , path ) : <EOL> if not utils . is_shared ( path ) : <EOL> msg . error ( '<STR_LIT>' % ( path , G . PROJECT_PATH ) ) <EOL> return <EOL> if os . path . isdir ( path ) : <EOL> for dirpath , dirnames , filenames in os . walk ( path ) : <EOL> dirnames [ : ] = [ d for d in dirnames if d [ <NUM_LIT:0> ] != '<STR_LIT:.>' ] <EOL> for f in filenames : <EOL> f_path = os . path . join ( dirpath , f ) <EOL> if f [ <NUM_LIT:0> ] == '<STR_LIT:.>' : <EOL> msg . log ( '<STR_LIT>' % f_path ) <EOL> else : <EOL> self . delete_buf ( f_path ) <EOL> return <EOL> buf_to_delete = self . get_buf_by_path ( path ) <EOL> if buf_to_delete is None : <EOL> msg . error ( '<STR_LIT>' % path ) <EOL> return <EOL> msg . log ( '<STR_LIT>' , utils . to_rel_path ( path ) ) <EOL> event = { <EOL> '<STR_LIT:name>' : '<STR_LIT>' , <EOL> '<STR_LIT:id>' : buf_to_delete [ '<STR_LIT:id>' ] , <EOL> } <EOL> G . AGENT . send ( event ) <EOL> def summon ( self , view ) : <EOL> buf = get_buf ( view ) <EOL> if buf : <EOL> msg . debug ( '<STR_LIT>' % ( buf [ '<STR_LIT:path>' ] , buf [ '<STR_LIT:id>' ] ) ) <EOL> self . selection_changed . append ( ( view , buf , True ) ) <EOL> else : <EOL> path = view . file_name ( ) <EOL> if not utils . is_shared ( path ) : <EOL> editor . error_message ( '<STR_LIT>' % ( path , G . PROJECT_PATH ) ) <EOL> return <EOL> share = editor . ok_cancel_dialog ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if share : <EOL> sel = [ [ x . a , x . b ] for x in view . sel ( ) ] <EOL> self . create_buf_cbs [ utils . to_rel_path ( path ) ] = lambda buf_id : send_summon ( buf_id , sel ) <EOL> self . upload ( path ) <EOL> def _on_room_info ( self , data ) : <EOL> super ( VimHandler , self ) . _on_room_info ( data ) <EOL> vim . command ( '<STR_LIT>' % G . PROJECT_PATH ) <EOL> def _on_delete_buf ( self , data ) : <EOL> buf_id = data [ '<STR_LIT:id>' ] <EOL> view = self . get_view ( buf_id ) <EOL> try : <EOL> if view : <EOL> view = view . view <EOL> view . set_scratch ( True ) <EOL> G . WORKSPACE_WINDOW . focus_view ( view ) <EOL> G . WORKSPACE_WINDOW . run_command ( "<STR_LIT>" ) <EOL> except Exception as e : <EOL> msg . debug ( '<STR_LIT>' % unicode ( e ) ) <EOL> try : <EOL> buf = self . bufs . get ( buf_id ) <EOL> if buf : <EOL> del self . paths_to_ids [ buf [ '<STR_LIT:path>' ] ] <EOL> del self . bufs [ buf_id ] <EOL> except KeyError : <EOL> msg . debug ( '<STR_LIT>' % buf_id ) <EOL> super ( self . __class__ , self ) . _on_delete_buf ( data ) <EOL> def _on_create_buf ( self , data ) : <EOL> super ( self . __class__ , self ) . _on_create_buf ( data ) <EOL> cb = self . create_buf_cbs . get ( data [ '<STR_LIT:path>' ] ) <EOL> if not cb : <EOL> return <EOL> del self . create_buf_cbs [ data [ '<STR_LIT:path>' ] ] <EOL> try : <EOL> cb ( data [ '<STR_LIT:id>' ] ) <EOL> except Exception as e : <EOL> print ( e ) <EOL> def _on_part ( self , data ) : <EOL> super ( self . __class__ , self ) . _on_part ( data ) <EOL> user_id = data [ '<STR_LIT>' ] <EOL> highlight = self . user_highlights . get ( user_id ) <EOL> if not highlight : <EOL> return <EOL> view = self . get_view ( highlight [ '<STR_LIT:id>' ] ) <EOL> if not view : <EOL> return <EOL> if vim . current . buffer . number != view . native_id : <EOL> return <EOL> view . clear_highlight ( user_id ) <EOL> del self . user_highlights [ user_id ] <EOL> def _on_highlight ( self , data ) : <EOL> buf_id = data [ '<STR_LIT:id>' ] <EOL> user_id = data [ '<STR_LIT>' ] <EOL> username = data . get ( '<STR_LIT:username>' , '<STR_LIT>' ) <EOL> ping = G . FOLLOW_MODE or data . get ( '<STR_LIT>' , False ) <EOL> previous_highlight = self . user_highlights . get ( user_id ) <EOL> buf = self . bufs . get ( buf_id ) <EOL> if not buf : <EOL> return <EOL> view = self . get_view ( buf_id ) <EOL> if not view : <EOL> if not ping : <EOL> return <EOL> view = self . create_view ( buf ) <EOL> if not view : <EOL> return <EOL> data [ '<STR_LIT:path>' ] = buf [ '<STR_LIT:path>' ] <EOL> self . user_highlights [ user_id ] = data <EOL> if ping : <EOL> try : <EOL> offset = data [ '<STR_LIT>' ] [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> except IndexError as e : <EOL> msg . debug ( '<STR_LIT>' % e ) <EOL> else : <EOL> if data . get ( '<STR_LIT>' ) : <EOL> msg . log ( '<STR_LIT>' % ( username ) ) <EOL> view . focus ( ) <EOL> view . set_cursor_position ( offset ) <EOL> if G . SHOW_HIGHLIGHTS : <EOL> if previous_highlight and previous_highlight [ '<STR_LIT:id>' ] == data [ '<STR_LIT:id>' ] : <EOL> view . clear_highlight ( user_id ) <EOL> view . highlight ( data [ '<STR_LIT>' ] , user_id ) </s>
