def __init__(self, parent, *args, **kwargs): super(Editor, self).__init__(parent, *args, **kwargs) self.load_configuration() self.parent = parent # The panel that contains the editor. self.filename = "" self.dirname = "" self.indent_level = 0 self.SetLexer(wx.stc.STC_LEX_PYTHON) self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) #set mono spacing here! self.set_styles() self.autocomp = CodeCompletion() self.logger = wx.GetApp().logger # Handle input so smart_indent can be implemented self.Bind(wx.EVT_KEY_DOWN, self.on_key_down) # Handle character input for AutoComp self.Bind(wx.EVT_CHAR, self.on_evt_char) # Handle autocompletion self.Bind(wx.stc.EVT_STC_AUTOCOMP_SELECTION, self.on_autocomp)
def __init__(self, parent, *args, **kwargs): super(Editor, self).__init__(parent,*args, **kwargs) self.load_configuration() self.parent = parent # The panel that contains the editor. self.filename = "" self.dirname = "" self.indent_level = 0 self.SetLexer(wx.stc.STC_LEX_PYTHON) self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) #set mono spacing here! self.set_styles() self.autocomp = CodeCompletion() self.logger = wx.GetApp().logger # Handle input so smart_indent can be implemented self.Bind(wx.EVT_KEY_DOWN, self.on_key_down) # Handle character input for AutoComp self.Bind(wx.EVT_CHAR, self.on_evt_char) # Handle autocompletion self.Bind(wx.stc.EVT_STC_AUTOCOMP_SELECTION, self.on_autocomp)
class Editor(wx.stc.StyledTextCtrl): """ The editor represents the actual StyledTextCtrl and all event handling on the Text level should be done here. """ def __init__(self, parent, *args, **kwargs): super(Editor, self).__init__(parent, *args, **kwargs) self.load_configuration() self.parent = parent # The panel that contains the editor. self.filename = "" self.dirname = "" self.indent_level = 0 self.SetLexer(wx.stc.STC_LEX_PYTHON) self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) #set mono spacing here! self.set_styles() self.autocomp = CodeCompletion() self.logger = wx.GetApp().logger # Handle input so smart_indent can be implemented self.Bind(wx.EVT_KEY_DOWN, self.on_key_down) # Handle character input for AutoComp self.Bind(wx.EVT_CHAR, self.on_evt_char) # Handle autocompletion self.Bind(wx.stc.EVT_STC_AUTOCOMP_SELECTION, self.on_autocomp) def load_configuration(self): """Apply all configuration settings""" config = wx.GetApp().config self.SetTabWidth(config.getint('editing', 'indent')) self.SetIndent(config.getint('editing', 'indent')) self.SetUseTabs(config.getboolean('editing', 'usetab')) def colon_indent(self): for keyword in ["else", "elif", "except", "finally"]: current_line_no = self.GetCurrentLine() (current_line, _) = self.GetCurLine() #if keyword in current_line: if current_line.lstrip().startswith(keyword): previous_line_no = max([0, current_line_no - 1]) previous_indent = self.GetLineIndentation(previous_line_no) new_indent = previous_indent - self.GetIndent() self.SetLineIndentation(current_line_no, new_indent) def newline_indent(self): """Handles smart indentation for the editor when a newline is pressed""" # Read settings from the config file # Determine how to indent if self.GetUseTabs(): indent_amount = self.GetTabWidth() indent = "\t" else: indent_amount = self.GetIndent() indent = indent_amount * " " self.GetCurrentLine() cursorpos = self.GetColumn(self.GetCurrentPos()) last_line_no = self.GetCurrentLine() #previous_line, cursorpos = self.GetCurLine() last_line = split_comments(self.GetLine(last_line_no))[0] indent_level = self.GetLineIndentation(last_line_no) // indent_amount # Should we increase or decrease the indent level colonpos = last_line.find(":") if 0 <= colonpos < cursorpos: indent_level += 1 else: # Unindent after certain keywords for token in [ "return", "break", "yield", "continue", "pass", "raise" ]: tokenpos = last_line.find(token) if (last_line.lstrip().startswith(token) and tokenpos > 0 and cursorpos >= tokenpos + len(token)): indent_level = max([indent_level - 1, 0]) # Perform the actual smartindent self.NewLine() self.AddText(indent * indent_level) def on_key_down(self, event): """This function should only handle key presses which cannot be handled by on_evt_char. Eg, newline, backspace. """ key = event.GetKeyCode() control = event.ControlDown() alt = event.AltDown() shift = event.ShiftDown() # If the AutoComplete menu is showing, hitting return merely # closes it and autocompletes; we shouldn't indent in this case. autocomp_showing = self.AutoCompActive() if key == wx.WXK_RETURN and not control and not alt and not autocomp_showing: # order of these calls is important self.code_complete(event) event.Skip(False) # prevent character from being printed # other than in newline_indent() self.newline_indent() elif key == wx.WXK_BACK and not control and not alt: self.code_complete(event) else: event.Skip() def on_evt_char(self, event): """This should handle most key presses, as the event passed to this function allows us to more accurately determine what the character is. """ key = event.GetKeyCode() char = chr(event.GetUniChar()) ctrl = event.ControlDown() alt = event.AltDown() autocomp_showing = self.AutoCompActive() if char == ':': self.colon_indent() self.code_complete(event) def save_as(self): save_dialog = wx.FileDialog(self, "Choose a file", "", "", "*.*", wx.SAVE) if save_dialog.ShowModal() == wx.ID_OK: self.filename = save_dialog.GetFilename() self.dirname = save_dialog.GetDirectory() with open(os.path.join(self.dirname, self.filename), 'w') as output: output.write(self.GetTextRaw()) # Ugh. Hack to rename the tab. root = wx.GetApp().frame root.editor_tab_panel.notebook.SetPageText( root.editor_tab_panel.notebook.GetSelection() - 1, self.filename) save_dialog.Destroy() def run(self): self.logger.msg("Told to run script.") stdout_tab_panel = wx.GetApp().frame.stdout_tab_panel # is the current file saved? if not any((self.dirname, self.filename)): # The script isn't saved. Thats okay though script = StringIO() stream = (token for token in self.GetText() if token != "\r") for token in stream: script.write(token) script.seek(0) args = ["python", "-c", script.read()] else: # So the script is saved, great just get the path! path = os.path.join(self.dirname, self.filename) args = ["python", path] stdout_tab_panel.run_script(args) def set_styles(self, lang='python'): """""" #INDICATOR STYLES FOR ERRORS (self.errorMark) self.IndicatorSetStyle(2, wx.stc.STC_INDIC_SQUIGGLE) self.IndicatorSetForeground(2, wx.RED) self.StyleSetSpec(wx.stc.STC_P_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) # Python styles # White space self.StyleSetSpec(wx.stc.STC_P_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) # Comment self.StyleSetSpec( wx.stc.STC_P_COMMENTLINE, "face:%(mono)s,fore:#007F00,back:#E8FFE8,italic,size:%(size)d" % faces) # Number self.StyleSetSpec(wx.stc.STC_P_NUMBER, "face:%(mono)s,fore:#007F7F,size:%(size)d" % faces) # String self.StyleSetSpec(wx.stc.STC_P_STRING, "face:%(mono)s,fore:#7F007F,size:%(size)d" % faces) # Single quoted string self.StyleSetSpec(wx.stc.STC_P_CHARACTER, "face:%(mono)s,fore:#7F007F,size:%(size)d" % faces) # Keyword self.StyleSetSpec( wx.stc.STC_P_WORD, "face:%(mono)s,fore:#00007F,bold,size:%(size)d" % faces) # Triple quotes self.StyleSetSpec(wx.stc.STC_P_TRIPLE, "face:%(mono)s,fore:#7F0000,size:%(size)d" % faces) # Triple double quotes self.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, "face:%(mono)s,fore:#7F0000,size:%(size)d" % faces) # Class name definition self.StyleSetSpec( wx.stc.STC_P_CLASSNAME, "face:%(mono)s,fore:#0000FF,bold,underline,size:%(size)d" % faces) # Function or method name definition self.StyleSetSpec( wx.stc.STC_P_DEFNAME, "face:%(mono)s,fore:#007F7F,bold,size:%(size)d" % faces) # Operators self.StyleSetSpec(wx.stc.STC_P_OPERATOR, "face:%(mono)s,bold,size:%(size)d" % faces) # Identifiers self.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, "") # Comment-blocks self.StyleSetSpec( wx.stc.STC_P_COMMENTBLOCK, "face:%(mono)s,fore:#990000,back:#C0C0C0,italic,size:%(size)d" % faces) # End of line where string is not closed self.StyleSetSpec( wx.stc.STC_P_STRINGEOL, "face:%(mono)s,fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces) def on_autocomp(self, event): """This is called when the user selects an option from the AutoComp meny.""" self.autocomp.key = event.Text def code_complete(self, event): """TODO: - Properly handle uppercase; the current implementation ignores caps lock. """ if event.GetKeyCode() == wx.WXK_BACK: self.autocomp.back() else: try: # this isn't perfect, doesn't handle caps lock #if event.ShiftDown(): # ch = chr(event.GetUniChar()) #else: # ch = chr(event.GetUniChar()).lower() ch = chr(event.GetUniChar()) self.autocomp.update_key(ch) except ValueError: self.autocomp.clear() return choices = list(self.autocomp.suggest()) if choices: choices.sort() self.AutoCompShow(self.autocomp.len_entered - 1, ' '.join(choices)) elif self.AutoCompActive(): self.AutoCompCancel() # Skip the event so the character will be printed. event.Skip()
class Editor(wx.stc.StyledTextCtrl): """ The editor represents the actual StyledTextCtrl and all event handling on the Text level should be done here. """ def __init__(self, parent, *args, **kwargs): super(Editor, self).__init__(parent,*args, **kwargs) self.load_configuration() self.parent = parent # The panel that contains the editor. self.filename = "" self.dirname = "" self.indent_level = 0 self.SetLexer(wx.stc.STC_LEX_PYTHON) self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) #set mono spacing here! self.set_styles() self.autocomp = CodeCompletion() self.logger = wx.GetApp().logger # Handle input so smart_indent can be implemented self.Bind(wx.EVT_KEY_DOWN, self.on_key_down) # Handle character input for AutoComp self.Bind(wx.EVT_CHAR, self.on_evt_char) # Handle autocompletion self.Bind(wx.stc.EVT_STC_AUTOCOMP_SELECTION, self.on_autocomp) def load_configuration(self): """Apply all configuration settings""" config = wx.GetApp().config self.SetTabWidth(config.getint('editing', 'indent')) self.SetIndent(config.getint('editing', 'indent')) self.SetUseTabs(config.getboolean('editing', 'usetab')) def colon_indent(self): for keyword in ["else", "elif", "except", "finally"]: current_line_no = self.GetCurrentLine() (current_line, _) = self.GetCurLine() #if keyword in current_line: if current_line.lstrip().startswith(keyword): previous_line_no = max([0, current_line_no - 1]) previous_indent = self.GetLineIndentation(previous_line_no) new_indent = previous_indent - self.GetIndent() self.SetLineIndentation(current_line_no, new_indent) def newline_indent(self): """Handles smart indentation for the editor when a newline is pressed""" # Read settings from the config file # Determine how to indent if self.GetUseTabs(): indent_amount = self.GetTabWidth() indent = "\t" else: indent_amount = self.GetIndent() indent = indent_amount * " " self.GetCurrentLine() cursorpos = self.GetColumn(self.GetCurrentPos()) last_line_no = self.GetCurrentLine() #previous_line, cursorpos = self.GetCurLine() last_line = split_comments(self.GetLine(last_line_no))[0] indent_level = self.GetLineIndentation(last_line_no) // indent_amount # Should we increase or decrease the indent level colonpos = last_line.find(":") if 0 <= colonpos < cursorpos: indent_level += 1 else: # Unindent after certain keywords for token in ["return", "break", "yield", "continue", "pass", "raise"]: tokenpos = last_line.find(token) if (last_line.lstrip().startswith(token) and tokenpos > 0 and cursorpos >= tokenpos + len(token)): indent_level = max([indent_level - 1, 0]) # Perform the actual smartindent self.NewLine() self.AddText(indent * indent_level) def on_key_down(self, event): """This function should only handle key presses which cannot be handled by on_evt_char. Eg, newline, backspace. """ key = event.GetKeyCode() control = event.ControlDown() alt = event.AltDown() shift = event.ShiftDown() # If the AutoComplete menu is showing, hitting return merely # closes it and autocompletes; we shouldn't indent in this case. autocomp_showing = self.AutoCompActive() if key == wx.WXK_RETURN and not control and not alt and not autocomp_showing: # order of these calls is important self.code_complete(event) event.Skip(False) # prevent character from being printed # other than in newline_indent() self.newline_indent() elif key == wx.WXK_BACK and not control and not alt: self.code_complete(event) else: event.Skip() def on_evt_char(self, event): """This should handle most key presses, as the event passed to this function allows us to more accurately determine what the character is. """ key = event.GetKeyCode() char = chr(event.GetUniChar()) ctrl = event.ControlDown() alt = event.AltDown() autocomp_showing = self.AutoCompActive() if char == ':': self.colon_indent() self.code_complete(event) def save_as(self): save_dialog = wx.FileDialog(self, "Choose a file", "", "", "*.*", wx.SAVE) if save_dialog.ShowModal() == wx.ID_OK: self.filename = save_dialog.GetFilename() self.dirname = save_dialog.GetDirectory() with open(os.path.join(self.dirname, self.filename),'w') as output: output.write(self.GetTextRaw()) # Ugh. Hack to rename the tab. root = wx.GetApp().frame root.editor_tab_panel.notebook.SetPageText(root.editor_tab_panel.notebook.GetSelection()-1, self.filename) save_dialog.Destroy() def run(self): self.logger.msg("Told to run script.") stdout_tab_panel = wx.GetApp().frame.stdout_tab_panel # is the current file saved? if not any((self.dirname, self.filename)): # The script isn't saved. Thats okay though script = StringIO() stream = (token for token in self.GetText() if token != "\r") for token in stream: script.write(token) script.seek(0) args = ["python", "-c", script.read()] else: # So the script is saved, great just get the path! path = os.path.join(self.dirname, self.filename) args = ["python", path] stdout_tab_panel.run_script(args) def set_styles(self, lang='python'): """""" #INDICATOR STYLES FOR ERRORS (self.errorMark) self.IndicatorSetStyle(2, wx.stc.STC_INDIC_SQUIGGLE) self.IndicatorSetForeground(2, wx.RED) self.StyleSetSpec(wx.stc.STC_P_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) # Python styles # White space self.StyleSetSpec(wx.stc.STC_P_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) # Comment self.StyleSetSpec(wx.stc.STC_P_COMMENTLINE, "face:%(mono)s,fore:#007F00,back:#E8FFE8,italic,size:%(size)d" % faces) # Number self.StyleSetSpec(wx.stc.STC_P_NUMBER, "face:%(mono)s,fore:#007F7F,size:%(size)d" % faces) # String self.StyleSetSpec(wx.stc.STC_P_STRING, "face:%(mono)s,fore:#7F007F,size:%(size)d" % faces) # Single quoted string self.StyleSetSpec(wx.stc.STC_P_CHARACTER, "face:%(mono)s,fore:#7F007F,size:%(size)d" % faces) # Keyword self.StyleSetSpec(wx.stc.STC_P_WORD, "face:%(mono)s,fore:#00007F,bold,size:%(size)d" % faces) # Triple quotes self.StyleSetSpec(wx.stc.STC_P_TRIPLE, "face:%(mono)s,fore:#7F0000,size:%(size)d" % faces) # Triple double quotes self.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, "face:%(mono)s,fore:#7F0000,size:%(size)d" % faces) # Class name definition self.StyleSetSpec(wx.stc.STC_P_CLASSNAME, "face:%(mono)s,fore:#0000FF,bold,underline,size:%(size)d" % faces) # Function or method name definition self.StyleSetSpec(wx.stc.STC_P_DEFNAME, "face:%(mono)s,fore:#007F7F,bold,size:%(size)d" % faces) # Operators self.StyleSetSpec(wx.stc.STC_P_OPERATOR, "face:%(mono)s,bold,size:%(size)d" % faces) # Identifiers self.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, "") # Comment-blocks self.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, "face:%(mono)s,fore:#990000,back:#C0C0C0,italic,size:%(size)d" % faces) # End of line where string is not closed self.StyleSetSpec(wx.stc.STC_P_STRINGEOL, "face:%(mono)s,fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces) def on_autocomp(self, event): """This is called when the user selects an option from the AutoComp meny.""" self.autocomp.key = event.Text def code_complete(self, event): """TODO: - Properly handle uppercase; the current implementation ignores caps lock. """ if event.GetKeyCode() == wx.WXK_BACK: self.autocomp.back() else: try: # this isn't perfect, doesn't handle caps lock #if event.ShiftDown(): # ch = chr(event.GetUniChar()) #else: # ch = chr(event.GetUniChar()).lower() ch = chr(event.GetUniChar()) self.autocomp.update_key(ch) except ValueError: self.autocomp.clear() return choices = list(self.autocomp.suggest()) if choices: choices.sort() self.AutoCompShow(self.autocomp.len_entered-1, ' '.join(choices)) elif self.AutoCompActive(): self.AutoCompCancel() # Skip the event so the character will be printed. event.Skip()