Changeset 1170

Show
Ignore:
Timestamp:
03/14/08 17:19:59 (6 months ago)
Author:
rob
Message:

Added electricChar to autoindent
* electricChar is used in the OnChar? method of FundamentalMode? to automatically reindent a line if a certain char is pressed
* converted PythonMode?'s ElectricColon? into electricChar method of PythonAutoindent?
* added CStyleAutoindent's electricChar to handle opening and closing braces and semicolon

Location:
trunk/peppy
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/peppy/fundamental.py

    r1166 r1170  
    400400        """ 
    401401        uchar = unichr(evt.GetKeyCode()) 
     402        if self.autoindent.electricChar(self, uchar): 
     403            # If the autoindenter handles the char, it will insert the char. 
     404            # So, we don't call Skip in this case and the processing ends 
     405            # here. 
     406            return 
    402407        if self.classprefs.spell_check and uchar in self.word_end_chars: 
    403408            # We are catching the event before the character is added to the 
  • trunk/peppy/lib/autoindent.py

    r1169 r1170  
    152152            newline = linesep 
    153153        else: 
     154            # When we insert a new line, the colorization isn't always 
     155            # immediately updated, so we have to force that here before 
     156            # calling findIndent 
     157            stc.ReplaceTarget(linesep) 
     158            pos += len(linesep) 
     159            end = min(pos + 1, stc.GetTextLength()) 
     160            # Colorize the entire last line up to one character beyond the 
     161            # newly inserted linesep character, guaranteeing that the new line 
     162            # will have the correct fold property set. 
     163            stc.Colourise(stc.PositionFromLine(linenum), end) 
     164            stc.SetTargetStart(pos) 
     165            stc.SetTargetEnd(pos) 
    154166            ind = self.findIndent(stc, linenum + 1) 
    155             newline = linesep + stc.GetIndentString(ind) 
     167            dprint("pos=%d ind=%d fold=%d" % (pos, ind, (stc.GetFoldLevel(linenum+1)&wx.stc.STC_FOLDLEVELNUMBERMASK) - wx.stc.STC_FOLDLEVELBASE)) 
     168            newline = stc.GetIndentString(ind) 
    156169        stc.ReplaceTarget(newline) 
    157170        stc.GotoPos(pos + len(newline)) 
     
    163176        stc.GotoPos(pos) 
    164177        stc.EndUndoAction() 
     178     
     179    def electricChar(self, stc, uchar): 
     180        """Autoindent in response to a special character 
     181 
     182        This is a hook to cause an autoindent on a particular character. 
     183        Note that the hook can do more than that -- it can insert or delete 
     184        characters as well. 
     185         
     186        This takes its name from emacs, where "electric" meant that something 
     187        else happened other than simply inserting the char. 
     188         
     189        @param stc: stc instance 
     190         
     191        @param uchar: unicode character that was just typed by the user (note 
     192        that it hasn't been inserted into the document yet.) 
     193         
     194        @return: True if this method handled the character and the text 
     195        was modified; False if the calling event handler should handle the 
     196        character. 
     197        """ 
     198        return False 
    165199 
    166200 
     
    211245 
    212246        # folding says this should be the current indention 
    213         fold = stc.GetFoldLevel(linenum)&wx.stc.STC_FOLDLEVELNUMBERMASK - wx.stc.STC_FOLDLEVELBASE 
     247        fold = (stc.GetFoldLevel(linenum)&wx.stc.STC_FOLDLEVELNUMBERMASK) - wx.stc.STC_FOLDLEVELBASE 
    214248        c = stc.GetCharAt(pos) 
    215249        s = stc.GetStyleAt(pos) 
     
    224258 
    225259        return fold * stc.GetIndent() 
     260     
     261    def electricChar(self, stc, uchar): 
     262        """Reindent the line and insert a newline when special chars are typed. 
     263         
     264        Like emacs, a semicolon or curly brace causes the line to be reindented 
     265        and the next line to be indented to the correct column. 
     266         
     267        @param stc: stc instance 
     268         
     269        @param uchar: unicode character that was just typed by the user (note 
     270        that it hasn't been inserted into the document yet.) 
     271         
     272        @return: True if this method handled the character and the text 
     273        was modified; False if the calling event handler should handle the 
     274        character. 
     275        """ 
     276        if uchar == u';' or uchar == '{' or uchar == '}': 
     277            pos = stc.GetCurrentPos() 
     278            s = stc.GetStyleAt(pos) 
     279            if not stc.isStyleComment(s) and not stc.isStyleString(s): 
     280                stc.BeginUndoAction() 
     281                stc.AddText(uchar) 
     282                self.processTab(stc) 
     283                self.processReturn(stc) 
     284                stc.EndUndoAction() 
     285                return True 
     286        return False 
    226287 
    227288 
     
    504565        """Don't reindent but insert the equivalent of a tab character""" 
    505566        stc.AddText(stc.GetIndentString(stc.GetIndent())) 
     567     
     568    def electricChar(self, stc, uchar): 
     569        """No electric chars in Null autoindenter.""" 
     570        return False 
  • trunk/peppy/plugins/python_mode.py

    r1166 r1170  
    5151    def action(self, index=-1, multiplier=1): 
    5252        self.frame.open("about:sample.py") 
    53  
    54  
    55 class ElectricColon(TextModificationAction): 
    56     name = "Electric Colon" 
    57     tooltip = "Indent the current line when a colon is pressed" 
    58     key_bindings = {'default': 'S-;',} # FIXME: doesn't work to specify ':' 
    59  
    60     @classmethod 
    61     def worksWithMajorMode(cls, mode): 
    62         return mode.keyword == 'Python' 
    63  
    64     def action(self, index=-1, multiplier=1): 
    65         s = self.mode 
    66         style = s.GetStyleAt(s.GetSelectionEnd()) 
    67         s.BeginUndoAction() 
    68         s.ReplaceSelection(":") 
    69         if s.isStyleComment(style) or s.isStyleString(style): 
    70             self.dprint("within comment or string: not indenting") 
    71             pass 
    72         else: 
    73             # folding info not automatically updated after a Replace, so 
    74             # do it manually 
    75             linestart = s.PositionFromLine(s.GetCurrentLine()) 
    76             s.Colourise(linestart, s.GetSelectionEnd()) 
    77             s.autoindent.reindentLine(s, dedent_only=True) 
    78         s.EndUndoAction() 
    7953 
    8054 
     
    216190        return indent 
    217191 
     192    def electricChar(self, stc, uchar): 
     193        """Reindent the line and insert a newline when special chars are typed. 
     194         
     195        For python mode, a colon should reindent the line (for example, after 
     196        an else statement, it should dedent it one level) 
     197        """ 
     198        if uchar == u':': 
     199            pos = stc.GetCurrentPos() 
     200            s = stc.GetStyleAt(pos) 
     201            if not stc.isStyleComment(s) and not stc.isStyleString(s): 
     202                stc.BeginUndoAction() 
     203                stc.AddText(uchar) 
     204                self.reindentLine(stc, dedent_only=True) 
     205                stc.EndUndoAction() 
     206                return True 
     207        return False 
     208 
    218209 
    219210class PythonMode(JobControlMixin, SimpleFoldFunctionMatchMixin, 
     
    296287 
    297288    def getActions(self): 
    298         return [SamplePython, ElectricColon] 
     289        return [SamplePython]