<s> from gi . repository import Gtk , GObject , Gedit , PeasGtk <EOL> import re <EOL> import traceback <EOL> import gconf <EOL> class IntelligentTextCompletionPlugin ( GObject . Object , Gedit . WindowActivatable , PeasGtk . Configurable ) : <EOL> window = GObject . property ( type = Gedit . Window ) <EOL> def __init__ ( self ) : <EOL> GObject . Object . __init__ ( self ) <EOL> self . _instances = { } <EOL> def do_create_configure_widget ( self ) : <EOL> return IntelligentTextCompletionOptions . get_instance ( ) . create_configure_dialog ( ) <EOL> def _connect_view ( self , view , window ) : <EOL> """<STR_LIT>""" <EOL> callback = self . _on_view_key_press_event <EOL> id = view . connect ( "<STR_LIT>" , callback , window ) <EOL> view . intelligent_text_completion_id = id <EOL> def _on_window_tab_added ( self , window , tab ) : <EOL> """<STR_LIT>""" <EOL> view = tab . get_view ( ) <EOL> handler_id = getattr ( view , '<STR_LIT>' , None ) <EOL> if handler_id is None : <EOL> self . _connect_view ( view , window ) <EOL> def _on_window_tab_removed ( self , window , tab ) : <EOL> pass <EOL> def do_activate ( self ) : <EOL> """<STR_LIT>""" <EOL> window = self . window <EOL> callback = self . _on_window_tab_added <EOL> id_1 = window . connect ( "<STR_LIT>" , callback ) <EOL> callback = self . _on_window_tab_removed <EOL> id_2 = window . connect ( "<STR_LIT>" , callback ) <EOL> window . intelligent_text_completion_id = ( id_1 , id_2 ) <EOL> views = window . get_views ( ) <EOL> for view in views : <EOL> self . _connect_view ( view , window ) <EOL> def do_deactivate ( self ) : <EOL> """<STR_LIT>""" <EOL> window = self . window <EOL> widgets = [ window ] <EOL> widgets . extend ( window . get_views ( ) ) <EOL> widgets . extend ( window . get_documents ( ) ) <EOL> for widget in widgets : <EOL> for handler_id in getattr ( widget , '<STR_LIT>' , [ ] ) : <EOL> widget . disconnect ( handler_id ) <EOL> widget . intelligent_text_completion_id = None <EOL> def _on_view_key_press_event ( self , view , event , window ) : <EOL> doc = window . get_active_document ( ) <EOL> try : <EOL> return self . _handle_event ( view , event , window ) <EOL> except : <EOL> err = "<STR_LIT>" <EOL> err += traceback . format_exc ( ) <EOL> doc . set_text ( err ) <EOL> def _handle_event ( self , view , event , window ) : <EOL> """<STR_LIT>""" <EOL> ignore_whitespace = '<STR_LIT>' <EOL> doc = window . get_active_document ( ) <EOL> cursor = doc . get_iter_at_mark ( doc . get_insert ( ) ) <EOL> typed_string = unicode ( event . string , '<STR_LIT>' ) <EOL> prev_char = None <EOL> if not cursor . get_line_offset ( ) == <NUM_LIT:0> : <EOL> prev_char_pos = cursor . copy ( ) <EOL> prev_char_pos . set_line_offset ( cursor . get_line_offset ( ) - <NUM_LIT:1> ) <EOL> prev_char = doc . get_text ( prev_char_pos , cursor , False ) <EOL> next_char = None <EOL> if not cursor . ends_line ( ) : <EOL> next_char_pos = cursor . copy ( ) <EOL> next_char_pos . set_line_offset ( cursor . get_line_offset ( ) + <NUM_LIT:1> ) <EOL> next_char = doc . get_text ( cursor , next_char_pos , False ) <EOL> line_start = cursor . copy ( ) <EOL> line_start . set_line_offset ( <NUM_LIT:0> ) <EOL> preceding_line = doc . get_text ( line_start , cursor , False ) <EOL> line_end = cursor . copy ( ) <EOL> if not cursor . ends_line ( ) : <EOL> line_end . forward_to_line_end ( ) <EOL> line_after = doc . get_text ( cursor , line_end , False ) <EOL> whitespace_pos = <NUM_LIT:0> <EOL> whitespace = "<STR_LIT>" <EOL> while len ( preceding_line ) > whitespace_pos and preceding_line [ whitespace_pos ] in ignore_whitespace : <EOL> whitespace += preceding_line [ whitespace_pos ] <EOL> whitespace_pos += <NUM_LIT:1> <EOL> options = IntelligentTextCompletionOptions . get_instance ( ) <EOL> if len ( typed_string ) > <NUM_LIT:1> : <EOL> return False <EOL> typed_char = typed_string <EOL> open_close = { <EOL> '<STR_LIT:">' : '<STR_LIT:">' , <EOL> "<STR_LIT:'>" : "<STR_LIT:'>" , <EOL> '<STR_LIT:(>' : '<STR_LIT:)>' , <EOL> '<STR_LIT:{>' : '<STR_LIT:}>' , <EOL> '<STR_LIT:[>' : '<STR_LIT:]>' , <EOL> } <EOL> bounds = doc . get_selection_bounds ( ) <EOL> if len ( bounds ) > <NUM_LIT:0> : <EOL> if options . closeBracketsAndQuotes : <EOL> for open , close in open_close . items ( ) : <EOL> if typed_char == open : <EOL> off1 = bounds [ <NUM_LIT:0> ] . get_offset ( ) <EOL> off2 = bounds [ <NUM_LIT:1> ] . get_offset ( ) <EOL> doc . place_cursor ( bounds [ <NUM_LIT:0> ] ) <EOL> doc . insert_at_cursor ( open ) <EOL> cursor = doc . get_iter_at_mark ( doc . get_insert ( ) ) <EOL> cursor . set_offset ( cursor . get_offset ( ) + ( off2 - off1 ) ) <EOL> doc . place_cursor ( cursor ) <EOL> doc . insert_at_cursor ( close ) <EOL> return True <EOL> return False <EOL> if options . closeBracketsAndQuotes and prev_char != '<STR_LIT:\\>' : <EOL> """<STR_LIT>""" <EOL> if typed_char == '<STR_LIT:">' and re . search ( '<STR_LIT>' , preceding_line ) and cursor . ends_line ( ) : <EOL> return self . _insert_at_cursor ( typed_char + '<STR_LIT:U+0020>' , '<STR_LIT>' ) <EOL> for check_char , add_char in open_close . items ( ) : <EOL> if typed_char == add_char : <EOL> if not cursor . ends_line ( ) : <EOL> if next_char == add_char : <EOL> if check_char != add_char : <EOL> preceding_check_chars = len ( re . findall ( '<STR_LIT>' % check_char , preceding_line ) ) <EOL> preceding_add_chars = len ( re . findall ( '<STR_LIT>' % add_char , preceding_line ) ) <EOL> following_check_chars = len ( re . findall ( '<STR_LIT>' % check_char , line_after ) ) <EOL> following_add_chars = len ( re . findall ( '<STR_LIT>' % add_char , line_after ) ) <EOL> if preceding_check_chars - preceding_add_chars > following_add_chars : <EOL> continue <EOL> if following_check_chars > <NUM_LIT:0> : <EOL> continue <EOL> doc . delete ( cursor , next_char_pos ) <EOL> return False <EOL> if typed_char == check_char : <EOL> if check_char == add_char : <EOL> if len ( re . findall ( check_char , preceding_line ) ) % <NUM_LIT:2> == <NUM_LIT:1> : <EOL> continue <EOL> if len ( re . findall ( check_char , line_after ) ) % <NUM_LIT:2> == <NUM_LIT:1> : <EOL> continue <EOL> non_text_left = '<STR_LIT>' <EOL> non_text_right = '<STR_LIT>' <EOL> if not next_char and not check_char == "<STR_LIT:'>" : <EOL> pass <EOL> elif ( not prev_char or prev_char in non_text_left ) and ( not next_char or next_char in non_text_right ) : <EOL> pass <EOL> elif check_char != add_char and ( not next_char or next_char in non_text_right ) : <EOL> pass <EOL> else : <EOL> continue <EOL> return self . _insert_at_cursor ( typed_char , add_char ) <EOL> if event . keyval == <NUM_LIT> : <EOL> if prev_char == check_char and next_char == add_char : <EOL> doc . delete ( cursor , next_char_pos ) <EOL> if options . completeXML : <EOL> if prev_char == "<STR_LIT:<>" and typed_char == "<STR_LIT:/>" : <EOL> start = doc . get_start_iter ( ) <EOL> preceding_document = doc . get_text ( start , cursor , False ) <EOL> closing_tag = get_closing_xml_tag ( preceding_document ) <EOL> if closing_tag : <EOL> return self . _insert_at_cursor ( typed_char + closing_tag + "<STR_LIT:>>" ) <EOL> else : <EOL> return False <EOL> if options . detectLists : <EOL> if event . keyval == <NUM_LIT> : <EOL> list_bullets = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> for bullet in list_bullets : <EOL> if len ( preceding_line ) >= whitespace_pos + len ( bullet ) : <EOL> if preceding_line [ whitespace_pos : whitespace_pos + len ( bullet ) ] == bullet : <EOL> if preceding_line == whitespace + bullet and bullet != '<STR_LIT>' : <EOL> start = cursor . copy ( ) <EOL> start . set_line_offset ( len ( whitespace ) ) <EOL> doc . delete ( start , cursor ) <EOL> return True <EOL> return self . _insert_at_cursor ( typed_char + whitespace + bullet ) <EOL> if event . keyval == <NUM_LIT> : <EOL> comments = { <EOL> '<STR_LIT>' : ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> } <EOL> for comment_start , ( comment_middle , comment_end ) in comments . items ( ) : <EOL> if preceding_line [ whitespace_pos : ] == comment_start : <EOL> add_middle = typed_char + whitespace + comment_middle <EOL> add_end = typed_char + whitespace + comment_end <EOL> return self . _insert_at_cursor ( add_middle , add_end ) <EOL> if options . autoindentAfterFunctionOrList : <EOL> if event . keyval == <NUM_LIT> : <EOL> indent_triggers = { <EOL> '<STR_LIT:(>' : '<STR_LIT:)>' , <EOL> '<STR_LIT:{>' : '<STR_LIT:}>' , <EOL> '<STR_LIT:[>' : '<STR_LIT:]>' , <EOL> '<STR_LIT::>' : '<STR_LIT>' , <EOL> } <EOL> for indent_trigger , ending_char in indent_triggers . items ( ) : <EOL> if prev_char == indent_trigger : <EOL> if line_after : <EOL> if ending_char != '<STR_LIT>' and ending_char in line_after : <EOL> ending_pos = line_after . find ( ending_char ) <EOL> else : <EOL> ending_pos = len ( line_after ) <EOL> end = cursor . copy ( ) <EOL> end . set_line_offset ( end . get_line_offset ( ) + ending_pos ) <EOL> ending_text = doc . get_text ( cursor , end , False ) . strip ( ) <EOL> doc . delete ( cursor , end ) <EOL> add_middle = typed_char + whitespace + get_tab_string ( view ) <EOL> add_end = ending_text + typed_char + whitespace <EOL> else : <EOL> add_middle = typed_char + whitespace + get_tab_string ( view ) <EOL> add_end = "<STR_LIT>" <EOL> return self . _insert_at_cursor ( add_middle , add_end ) <EOL> def _insert_at_cursor ( self , middle , end = "<STR_LIT>" ) : <EOL> window = self . window <EOL> doc = window . get_active_document ( ) <EOL> doc . insert_at_cursor ( middle + end ) <EOL> cursor = doc . get_iter_at_mark ( doc . get_insert ( ) ) <EOL> cursor . set_offset ( cursor . get_offset ( ) - len ( end ) ) <EOL> doc . place_cursor ( cursor ) <EOL> return True <EOL> def get_tab_string ( view ) : <EOL> tab_width = view . get_tab_width ( ) <EOL> tab_spaces = view . get_insert_spaces_instead_of_tabs ( ) <EOL> tab_code = "<STR_LIT>" <EOL> if tab_spaces : <EOL> for x in range ( tab_width ) : <EOL> tab_code += "<STR_LIT:U+0020>" <EOL> else : <EOL> tab_code = "<STR_LIT:\t>" <EOL> return tab_code <EOL> def get_closing_xml_tag ( document ) : <EOL> tags = re . findall ( r'<STR_LIT>' , document ) <EOL> tags . reverse ( ) <EOL> closed = [ ] <EOL> for tag in tags : <EOL> if re . match ( r'<STR_LIT>' , tag ) : <EOL> continue <EOL> if re . match ( r'<STR_LIT>' , tag ) : <EOL> continue <EOL> if re . match ( r'<STR_LIT>' , tag ) : <EOL> continue <EOL> m = re . match ( r'<STR_LIT>' , tag ) <EOL> if m : <EOL> closed . append ( m . group ( <NUM_LIT:1> ) ) <EOL> continue <EOL> m = re . match ( r'<STR_LIT>' , tag ) <EOL> if m : <EOL> openedtag = m . group ( <NUM_LIT:1> ) <EOL> while True : <EOL> if len ( closed ) == <NUM_LIT:0> : <EOL> return openedtag <EOL> close_tag = closed . pop ( ) <EOL> if close_tag . lower ( ) == openedtag . lower ( ) : <EOL> break <EOL> continue <EOL> return None <EOL> class IntelligentTextCompletionOptions ( object ) : <EOL> closeBracketsAndQuotes = True <EOL> completeXML = True <EOL> detectLists = True <EOL> autoindentAfterFunctionOrList = True <EOL> _closeBracketsAndQuotesButton = None <EOL> _completeXMLButton = None <EOL> _detectListsButton = None <EOL> _autoindentAfterFunctionOrListButton = None <EOL> _GCONF_SETTINGS_DIR = "<STR_LIT>" <EOL> _gconf_client = None <EOL> singleton = None <EOL> def __init__ ( self ) : <EOL> self . _gconf_client = gconf . client_get_default ( ) <EOL> if not self . _gconf_client . dir_exists ( self . _GCONF_SETTINGS_DIR ) : <EOL> self . _gconf_client . add_dir ( self . _GCONF_SETTINGS_DIR , gconf . CLIENT_PRELOAD_NONE ) <EOL> self . closeBracketsAndQuotes = self . _load_setting ( "<STR_LIT>" ) <EOL> self . completeXML = self . _load_setting ( "<STR_LIT>" ) <EOL> self . detectLists = self . _load_setting ( "<STR_LIT>" ) <EOL> self . autoindentAfterFunctionOrList = self . _load_setting ( "<STR_LIT>" ) <EOL> @ classmethod <EOL> def get_instance ( cls ) : <EOL> """<STR_LIT>""" <EOL> if cls . singleton is None : <EOL> cls . singleton = cls ( ) <EOL> return cls . singleton <EOL> def create_configure_dialog ( self ) : <EOL> """<STR_LIT>""" <EOL> vbox = Gtk . VBox ( ) <EOL> vbox . set_border_width ( <NUM_LIT:6> ) <EOL> self . _closeBracketsAndQuotesButton = self . _add_setting_checkbox ( <EOL> vbox = vbox , <EOL> current_value = self . closeBracketsAndQuotes , <EOL> helptext = "<STR_LIT>" , <EOL> ) <EOL> self . _completeXMLButton = self . _add_setting_checkbox ( <EOL> vbox = vbox , <EOL> current_value = self . completeXML , <EOL> helptext = "<STR_LIT>" , <EOL> ) <EOL> self . _detectListsButton = self . _add_setting_checkbox ( <EOL> vbox = vbox , <EOL> current_value = self . detectLists , <EOL> helptext = "<STR_LIT>" , <EOL> ) <EOL> self . _autoindentAfterFunctionOrListButton = self . _add_setting_checkbox ( <EOL> vbox = vbox , <EOL> current_value = self . autoindentAfterFunctionOrList , <EOL> helptext = "<STR_LIT>" , <EOL> ) <EOL> return vbox <EOL> def _add_setting_checkbox ( self , vbox , current_value , helptext ) : <EOL> box = Gtk . HBox ( ) <EOL> check_button = Gtk . CheckButton ( helptext ) <EOL> check_button . set_active ( current_value ) <EOL> box . pack_start ( check_button , False , False , <NUM_LIT:6> ) <EOL> check_button . connect ( '<STR_LIT>' , self . _on_check_button_toggled ) <EOL> vbox . pack_start ( box , False , True , <NUM_LIT:0> ) <EOL> return check_button <EOL> def _on_check_button_toggled ( self , * args ) : <EOL> self . closeBracketsAndQuotes = self . _closeBracketsAndQuotesButton . get_active ( ) <EOL> self . completeXML = self . _completeXMLButton . get_active ( ) <EOL> self . detectLists = self . _detectListsButton . get_active ( ) <EOL> self . autoindentAfterFunctionOrList = self . _autoindentAfterFunctionOrListButton . get_active ( ) <EOL> self . _save_setting ( "<STR_LIT>" , self . closeBracketsAndQuotes ) <EOL> self . _save_setting ( "<STR_LIT>" , self . completeXML ) <EOL> self . _save_setting ( "<STR_LIT>" , self . detectLists ) <EOL> self . _save_setting ( "<STR_LIT>" , self . autoindentAfterFunctionOrList ) <EOL> def _save_setting ( self , setting_name , value ) : <EOL> self . _gconf_client . set_bool ( "<STR_LIT>" . format ( self . _GCONF_SETTINGS_DIR , setting_name ) , value ) <EOL> def _load_setting ( self , setting_name ) : <EOL> try : <EOL> return self . _gconf_client . get_bool ( "<STR_LIT>" . format ( self . _GCONF_SETTINGS_DIR , setting_name ) ) <EOL> except Exception , e : <EOL> print e </s>
