def test():
    '''Test the basics of `get_n_identical_edge_characters`.'''
    assert get_n_identical_edge_characters('qqqwee') == 3
    assert get_n_identical_edge_characters('qqqqwee') == 4
    assert get_n_identical_edge_characters('qqqqwee', head=False) == 2
    assert get_n_identical_edge_characters('1234') == 1
    assert get_n_identical_edge_characters('1234', character='4') == 0
    assert get_n_identical_edge_characters('1234', character='4',
                                           head=False) == 1
    assert get_n_identical_edge_characters('1234', character='&',
                                           head=False) == 0
    assert get_n_identical_edge_characters('pppp') == \
           get_n_identical_edge_characters('pppp', head=False) == \
           get_n_identical_edge_characters('pppp', character='p',
                                           head=False) == 4
Example #2
0
 def parse(self, name, class_name):
     '''
     Parse a name into a tuple of "words".
     
     For example, under default settings, an input of
     '_on_navigation_panel__left_down' would result in an output of
     `('navigation_panel', 'left_down')`.
     
     Returns `None` if there is no match.
     '''
     unmangled_name = name_mangling.unmangle_attribute_name_if_needed(
         name,
         class_name
     )
     n_preceding_underscores = string_tools.get_n_identical_edge_characters(
         unmangled_name,
         character='_',
         head=True
     )
     if n_preceding_underscores not in \
        self.n_preceding_underscores_possibilities:
         return None
     cleaned_name = unmangled_name[n_preceding_underscores:]
     for case_style in self.case_style_possibilites:
         result = case_style.parse(cleaned_name)
         if result is not None:
             return result
     else:
         return None
def test():
    '''Test the basics of `get_n_identical_edge_characters`.'''
    assert get_n_identical_edge_characters('qqqwee') == 3
    assert get_n_identical_edge_characters('qqqqwee') == 4
    assert get_n_identical_edge_characters('qqqqwee', head=False) == 2
    assert get_n_identical_edge_characters('1234') == 1
    assert get_n_identical_edge_characters('1234', character='4') == 0
    assert get_n_identical_edge_characters('1234',
                                           character='4',
                                           head=False) == 1
    assert get_n_identical_edge_characters('1234',
                                           character='&',
                                           head=False) == 0
    assert get_n_identical_edge_characters('pppp') == \
           get_n_identical_edge_characters('pppp', head=False) == \
           get_n_identical_edge_characters('pppp', character='p',
                                           head=False) == 4
def push_line_to_end(editor=wingapi.kArgEditor, line_offset=0):
    '''
    Push the current line to the end, aligning it to right border of editor.
    
    This inserts or deletes as many spaces as necessary from the beginning of
    the line to make the end of the line exactly coincide with the right border
    of the editor. (Whose width can be configured in Wing's "Preferences" ->
    "Line Wrapping" -> "Reformatting Wrap Column".)
    
    This is useful for creating lines of this style:
    
        if first_long_condition(foo, foobar) and \
                                          second_long_condition(fubaz, bazbar):
                                          
    Also deletes trailing spaces.

    Suggested key combination: `Insert End`
    '''
    assert isinstance(editor, wingapi.CAPIEditor)
    document = editor.GetDocument()
    assert isinstance(document, wingapi.CAPIDocument)
    position, _ = editor.GetSelection()
    line = document.GetLineNumberFromPosition(position) + line_offset
    line_start = document.GetLineStart(line)
    line_end = document.GetLineEnd(line)
    line_content = document.GetCharRange(line_start, line_end)
    n_trailing_spaces = _get_n_identical_edge_characters(line_content,
                                                         character=' ',
                                                         head=False)
    current_line_length = line_end - line_start   
    n_spaces_to_add = \
        wingapi.gApplication.GetPreference('edit.text-wrap-column') - \
                                        current_line_length + n_trailing_spaces
    
    with shared.UndoableAction(document):
        document.DeleteChars(line_end - n_trailing_spaces, line_end - 1)   
        if n_spaces_to_add == 0:
            return
        elif n_spaces_to_add > 0:
            string_to_insert = (' ' * n_spaces_to_add)
            document.InsertChars(line_start, string_to_insert)
        else:
            assert n_spaces_to_add < 0
            n_spaces_to_delete = min(
                -n_spaces_to_add,
                string_tools.get_n_identical_edge_characters(
                    line_content,
                    character=' '
                )
            )    
            document.DeleteChars(
                line_start,
                line_start + (n_spaces_to_delete - 1)
            )
def unmangle_attribute_name_if_needed(attribute_name, class_name):

    # Ruling out four cases in which mangling wouldn't have happened:
    if ((string_tools.get_n_identical_edge_characters(attribute_name, '_') !=
         1) or (len(attribute_name) >= MANGLE_LEN)
            or (attribute_name.endswith('__')) or set(class_name) == set('_')):

        return attribute_name

    cleaned_class_name = class_name.lstrip('_')
    if not attribute_name[1:].startswith(cleaned_class_name + '__'):
        return attribute_name

    return attribute_name[(len(cleaned_class_name) + 1):]
Example #6
0
def push_line_to_end(editor=wingapi.kArgEditor, line_offset=0):
    '''
    Push the current line to the end, aligning it to right border of editor.
    
    This inserts or deletes as many spaces as necessary from the beginning of
    the line to make the end of the line exactly coincide with the right border
    of the editor. (Whose width can be configured in Wing's "Preferences" ->
    "Line Wrapping" -> "Reformatting Wrap Column".)
    
    This is useful for creating lines of this style:
    
        if first_long_condition(foo, foobar) and \
                                          second_long_condition(fubaz, bazbar):
                                          
    Also deletes trailing spaces.

    Suggested key combination: `Insert End`
    '''
    assert isinstance(editor, wingapi.CAPIEditor)
    document = editor.GetDocument()
    assert isinstance(document, wingapi.CAPIDocument)
    position, _ = editor.GetSelection()
    line = document.GetLineNumberFromPosition(position) + line_offset
    line_start = document.GetLineStart(line)
    line_end = document.GetLineEnd(line)
    line_content = document.GetCharRange(line_start, line_end)
    n_trailing_spaces = _get_n_identical_edge_characters(line_content,
                                                         character=' ',
                                                         head=False)
    current_line_length = line_end - line_start
    n_spaces_to_add = \
        wingapi.gApplication.GetPreference('edit.text-wrap-column') - \
                                        current_line_length + n_trailing_spaces

    with shared.UndoableAction(document):
        document.DeleteChars(line_end - n_trailing_spaces, line_end - 1)
        if n_spaces_to_add == 0:
            return
        elif n_spaces_to_add > 0:
            string_to_insert = (' ' * n_spaces_to_add)
            document.InsertChars(line_start, string_to_insert)
        else:
            assert n_spaces_to_add < 0
            n_spaces_to_delete = min(
                -n_spaces_to_add,
                string_tools.get_n_identical_edge_characters(line_content,
                                                             character=' '))
            document.DeleteChars(line_start,
                                 line_start + (n_spaces_to_delete - 1))
Example #7
0
def unmangle_attribute_name_if_needed(attribute_name, class_name):
    
    # Ruling out four cases in which mangling wouldn't have happened:
    if ((string_tools.get_n_identical_edge_characters(attribute_name,
                                                      '_') != 1) or
        (len(attribute_name) >= MANGLE_LEN) or
        (attribute_name.endswith('__')) or
        set(class_name) == set('_')):
        
        return attribute_name
    
    cleaned_class_name = class_name.lstrip('_')
    if not attribute_name[1:].startswith(cleaned_class_name + '__'):
        return attribute_name
    
    return attribute_name[(len(cleaned_class_name) + 1):]
Example #8
0
    def parse(self, name, class_name):
        '''
        Parse a name into a tuple of "words".

        For example, under default settings, an input of
        '_on_navigation_panel__left_down' would result in an output of
        `('navigation_panel', 'left_down')`.

        Returns `None` if there is no match.
        '''
        unmangled_name = name_mangling.unmangle_attribute_name_if_needed(
            name, class_name)
        n_preceding_underscores = string_tools.get_n_identical_edge_characters(
            unmangled_name, character='_', head=True)
        if n_preceding_underscores not in \
           self.n_preceding_underscores_possibilities:
            return None
        cleaned_name = unmangled_name[n_preceding_underscores:]
        for case_style in self.case_style_possibilites:
            result = case_style.parse(cleaned_name)
            if result is not None:
                return result
        else:
            return None
Example #9
0
def deep_to_var(editor=wingapi.kArgEditor):
    '''
    Create a variable from a deep expression.
    
    When you're programming, you're often writing lines like these:
    
        html_color = self._style_handler.html_color
        
    Or:
    
        location = context_data['location']
        
    Or:
        
        event_handler = super(Foobsnicator, self).get_event_handler()
    
    Or:
        
        user_profile = models.UserProfile.objects.get(pk=pk)
        
    What's common to all these lines is that you're accessing some expression,
    sometimes a deep one, and then getting an object, and making a variable for
    that object with the same name that it has in the deep expression.
    
    What this `deep-to-var` script will do for you is save you from having to
    write the `html_color = ` part, which is annoying to type because you don't
    have autocompletion for it.
    
    Just write your deep expression, like `self._style_handler.html_color`,
    invoke this `deep-to-var` script, and you'll get the full line and have the
    caret put on the next line.

    Suggested key combination: `Insert E`
    '''
    assert isinstance(editor, wingapi.CAPIEditor)
    document = editor.GetDocument()
    assert isinstance(document, wingapi.CAPIDocument)
    
    position, _ = editor.GetSelection()
    line_number = document.GetLineNumberFromPosition(position)
    line_start = document.GetLineStart(line_number)
    line_end = document.GetLineEnd(line_number)
    line = document.GetCharRange(line_start, line_end)
    line_stripped = line.strip()
    
    variable_name = None
    match = None
    for pattern in patterns:
        match = pattern.search(line_stripped)
        if match:
            if pattern in variable_name_map:
                variable_name = variable_name_map[pattern]
            else:
                (variable_name,) = match.groups()
            break
        
    if match:
        if variable_name != variable_name.lower():
            # `variable_name` has an uppercase letter, and thus is probably
            # camel-case. Let's flip it to underscore:
            variable_name = shared.camel_case_to_lower_case(variable_name)
        string_to_insert = '%s = ' % variable_name
        actual_line_start = line_start + \
              string_tools.get_n_identical_edge_characters(line, character=' ')
        
        with shared.UndoableAction(document):
            
            document.InsertChars(actual_line_start, string_to_insert)
            new_position = line_end + len(string_to_insert)
            editor.SetSelection(new_position, new_position)
            editor.ExecuteCommand('new-line')
Example #10
0
def deep_to_var(editor=wingapi.kArgEditor):
    '''
    Create a variable from a deep expression.
    
    When you're programming, you're often writing lines like these:
    
        html_color = self._style_handler.html_color
        
    Or:
    
        location = context_data['location']
        
    Or:
        
        event_handler = super(Foobsnicator, self).get_event_handler()
    
    Or:
        
        user_profile = models.UserProfile.objects.get(pk=pk)
        
    What's common to all these lines is that you're accessing some expression,
    sometimes a deep one, and then getting an object, and making a variable for
    that object with the same name that it has in the deep expression.
    
    What this `deep-to-var` script will do for you is save you from having to
    write the `html_color = ` part, which is annoying to type because you don't
    have autocompletion for it.
    
    Just write your deep expression, like `self._style_handler.html_color`,
    invoke this `deep-to-var` script, and you'll get the full line and have the
    caret put on the next line.

    Suggested key combination: `Insert E`
    '''
    assert isinstance(editor, wingapi.CAPIEditor)
    document = editor.GetDocument()
    assert isinstance(document, wingapi.CAPIDocument)

    position, _ = editor.GetSelection()
    line_number = document.GetLineNumberFromPosition(position)
    line_start = document.GetLineStart(line_number)
    line_end = document.GetLineEnd(line_number)
    line = document.GetCharRange(line_start, line_end)
    line_stripped = line.strip()

    variable_name = None
    match = None
    for pattern in patterns:
        match = pattern.search(line_stripped)
        if match:
            if pattern in variable_name_map:
                variable_name = variable_name_map[pattern]
            else:
                (variable_name, ) = match.groups()
            break

    if match:
        if variable_name != variable_name.lower():
            # `variable_name` has an uppercase letter, and thus is probably
            # camel-case. Let's flip it to underscore:
            variable_name = shared.camel_case_to_lower_case(variable_name)
        string_to_insert = '%s = ' % variable_name
        actual_line_start = line_start + \
              string_tools.get_n_identical_edge_characters(line, character=' ')

        with shared.UndoableAction(document):

            document.InsertChars(actual_line_start, string_to_insert)
            new_position = line_end + len(string_to_insert)
            editor.SetSelection(new_position, new_position)
            editor.ExecuteCommand('new-line')