class CommandLineHandler(object): def __init__(self): self.command = '' self.history = HistoryList() self.execute = EventHook() def line_changed(self, line): if callable(line): line = line() self.command = line self.history.reset() def previous(self): try: self.history.previous() finally: self.command = self.history.current def next(self): try: self.history.next() finally: self.command = self.history.current def finish(self): if self.command == '': return self.history.append(self.command) self.execute.fire(self.command)
class CommandLineControl(wx.TextCtrl): def __init__(self, *args, **kwargs): style = kwargs.get('style', 0) style |= wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB | wx.TE_RICH2 # TE_RICH2 for windows kwargs ['style'] = style wx.TextCtrl.__init__(self, *args, **kwargs) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.handler = CommandLineHandler() self.handler.line_changed('') style = self.DefaultStyle if wx.Platform == '__WXMSW__': font = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) else: font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) style.SetFont(font) self.style = style self.SetDefaultStyle(style) self.unfocus = EventHook() def Flash(self): wx.Bell() def ChangeValue(self, v): wx.TextCtrl.ChangeValue(self, v) self.SetStyle(0, len(v), self.style) def OnKeyDown(self, event): key = event.GetKeyCode() if key in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER): self.handler.finish() self.ChangeValue('') elif key == wx.WXK_DOWN: try: self.handler.next() self.ChangeValue(self.handler.command) self.SetInsertionPoint(len(self.handler.command)) except IndexError: self.handler.line_changed('') self.ChangeValue('') elif key == wx.WXK_UP: try: self.handler.previous() except IndexError: self.Flash() self.ChangeValue(self.handler.command) self.SetInsertionPoint(len(self.handler.command)) elif key == wx.WXK_ESCAPE: self.handler.line_changed('') self.ChangeValue('') self.unfocus.fire() else: event.Skip() wx.CallAfter(self.handler.line_changed, self.GetValue)
def __init__(self, name): self.name = name self._lines = [u''] self._obs_lines = ObservedList(self._lines, self._observe_list) self._curpos = 0 self._anchor = 0 self.pos_changed = EventHook() self.inserted = EventHook() self.deleted = EventHook() self.events = [] self.read_pos = 0
class BufferManager(object): def __init__(self): self._buffers = [] self._names_to_bufs = {} self._bufs_to_indexes = {} self.buffer_created = EventHook() @property def buffers(self): return self._buffers def _register_buffer(self, b): self._buffers.append(b) self._bufs_to_indexes[b] = len(self._buffers) - 1 self._names_to_bufs[b.name] = b self.buffer_created.fire(b) def visit(self, *args, **kwargs): b = FileBuffer(*args, **kwargs) self._register_buffer(b) return b def new(self, *args, **kwargs): b = Buffer(*args, **kwargs) self._register_buffer(b) return b def __getitem__(self, item): if isinstance(item, int): return self._buffers[item] else: return self._names_to_bufs[item] def __len__(self): return len(self._buffers) def __iter__(self): return iter(self._buffers) def __repr__(self): return 'BufferManager: <%r>' % self._buffers def next(self, frombuf): fromidx = self._bufs_to_indexes[frombuf] if fromidx >= len(self._buffers) - 1: # end of list return self._buffers[0] return self._buffers[fromidx + 1] def previous(self, frombuf): fromidx = self._bufs_to_indexes[frombuf] if fromidx <= 0: # start of list return self._buffers[-1] return self._buffers[fromidx - 1]
def __init__(self, *args, **kwargs): style = kwargs.get('style', 0) style |= wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB | wx.TE_RICH2 # TE_RICH2 for windows kwargs ['style'] = style wx.TextCtrl.__init__(self, *args, **kwargs) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.handler = CommandLineHandler() self.handler.line_changed('') style = self.DefaultStyle if wx.Platform == '__WXMSW__': font = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) else: font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) style.SetFont(font) self.style = style self.SetDefaultStyle(style) self.unfocus = EventHook()
def __init__(self, session): wx.Frame.__init__(self, None, wx.ID_ANY, 'title', size=(800, 600)) self.session = session self._setup() self.buffer_changed = EventHook() self.session.buffers.buffer_created += self.OnNewBuffer for b in session.buffers: self.OnNewBuffer(b) ed = PythonEditor(self._nb, wx.NewId(), b, session.keydown) self._nb.AddPage(ed, b.name) self.current_window_index = self._nb.Selection self.CurrentBufferChanged(self.current_window.buffer) self.session.keymap['m-x'] = lambda _: self.commandLine.SetFocus() self.commandLine.handler.execute += self.session.execute self.commandLine.unfocus += lambda: self.current_window.SetFocus() self.Show(True)
def __init__(self): self.command = '' self.history = HistoryList() self.execute = EventHook()
class Frame(wx.Frame): def _setup(self): self.CreateMenu() mainPanel = wx.Panel(self, wx.ID_ANY) mainPanel.SetBackgroundColour(wx.RED) notebookstyle = ( wx.aui.AUI_NB_DEFAULT_STYLE | wx.aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.aui.AUI_NB_WINDOWLIST_BUTTON | wx.aui.AUI_NB_SCROLL_BUTTONS | wx.aui.AUI_NB_TAB_FIXED_WIDTH ) self._nb= wx.aui.AuiNotebook(mainPanel, style=notebookstyle) self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged) self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClose) self.commandLine = CommandLineControl(mainPanel, wx.ID_ANY, size=(125, -1)) box = wx.BoxSizer(wx.VERTICAL) box.Add(self._nb, proportion=1, flag=wx.EXPAND) box.Add(self.commandLine, proportion=0, flag=wx.EXPAND) mainPanel.SetSizer(box) mainPanel.SetAutoLayout(True) self.CreateStatusBar() def __init__(self, session): wx.Frame.__init__(self, None, wx.ID_ANY, 'title', size=(800, 600)) self.session = session self._setup() self.buffer_changed = EventHook() self.session.buffers.buffer_created += self.OnNewBuffer for b in session.buffers: self.OnNewBuffer(b) ed = PythonEditor(self._nb, wx.NewId(), b, session.keydown) self._nb.AddPage(ed, b.name) self.current_window_index = self._nb.Selection self.CurrentBufferChanged(self.current_window.buffer) self.session.keymap['m-x'] = lambda _: self.commandLine.SetFocus() self.commandLine.handler.execute += self.session.execute self.commandLine.unfocus += lambda: self.current_window.SetFocus() self.Show(True) @property def current_window(self): return self._nb.GetPage(self.current_window_index) def OnPageClose(self, event): ed = self._nb.GetPage(event.Selection) self.windows.remove(ed) event.Skip() def OnPageChanged(self, event): sel = self._nb.GetSelection() self.current_window_index = sel self.Title = self.current_window.buffer.name self.buffer_changed.fire(self.current_window.buffer) event.Skip() def OnPreviousBuffer(self, _): newbuf = self.buffers.previous(frombuf=self.current_window.buffer) self.CurrentBufferChanged(newbuf) def OnNextBuffer(self, _): newbuf = self.buffers.next(frombuf=self.current_window.buffer) self.CurrentBufferChanged(newbuf) def CurrentBufferChanged(self, newbuffer): self.Title = newbuffer.name self.current_window.buffer = newbuffer self._nb.SetPageText(self.current_window_index, newbuffer.name) self.current_window.SetFocus() self.buffer_changed.fire(newbuffer) def OnNewBuffer(self, newbuf): mb = self.GetMenuBar() theid = mb.FindMenu('Buffers') menu = mb.GetMenu(theid) menuitem = menu.Append(wx.NewId(), newbuf.name) self.Bind(wx.EVT_MENU, lambda _: self.CurrentBufferChanged(newbuf), menuitem) def CreateMenu(self): filemenu = wx.Menu() filemenu.Append(wx.ID_OPEN, "&Open", "Open file...") filemenu.AppendSeparator() filemenu.Append(wx.ID_ABOUT, "&About", "info") filemenu.AppendSeparator() filemenu.Append(wx.ID_EXIT, "E&xit", "exit") wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout) wx.EVT_MENU(self, wx.ID_EXIT, self.OnExit) evalMenu = wx.Menu() evalMenu.Append(201, "Eval buffer") self.Bind(wx.EVT_MENU, self.OnEvalBuffer, id=201) bufferMenu = wx.Menu() bufferMenu.Append(301, "&Next buffer") bufferMenu.Append(302, "&Previous buffer") bufferMenu.AppendSeparator() self.Bind(wx.EVT_MENU, self.OnNextBuffer, id=301) self.Bind(wx.EVT_MENU, self.OnPreviousBuffer, id=302) menuBar = wx.MenuBar() menuBar.Append(filemenu, "&File") menuBar.Append(evalMenu, "E&val") menuBar.Append(bufferMenu, "&Buffers") self.SetMenuBar(menuBar) def OnAbout(self, e): d = wx.MessageDialog(self, "Wicked!", 'About Wixed', wx.OK) d.ShowModal() d.Destroy() def OnExit(self, e): self.Close(True) def OnEvalBuffer(self, e): text = self.current_window.buffer.text exec(text.replace('\r\n', '\n'), self.session.context)
class Buffer(object): def __init__(self, name): self.name = name self._lines = [u''] self._obs_lines = ObservedList(self._lines, self._observe_list) self._curpos = 0 self._anchor = 0 self.pos_changed = EventHook() self.inserted = EventHook() self.deleted = EventHook() self.events = [] self.read_pos = 0 def _observe_list(self, method, *args): if method == '__setitem__': lineno, line = args self.delete(lineno, 0, self._lines[lineno], 0) self.insert(lineno, 0, line, 0) elif method == '__delslice__': start, end = args if end > len(self._lines) - 1: end = len(self._lines) - 1 for idx in range(end, start - 1, -1): self.delete(idx, 0, self._lines[idx], -1) elif method == 'extend': iterable = args[0] lineno = len(self._lines) - 1 for idx, line in enumerate(iterable): self.insert(lineno + idx, 0, line+'\n', 1) elif method == 'insert': lineno, line = args self.insert(lineno, 0, line+'\n', 1) elif method == 'append': line = args[0] self.insert(len(self._lines) - 1, 0, line+'\n', 1) else: raise Exception('Sorry; Unknown modification to list: %s' % method) curpos = observed('_curpos', lambda s: s.pos_changed) anchor = observed('_anchor', lambda s: s.pos_changed) @property def text(self): return '\n'.join(self._lines) @property def lines(self): return self._obs_lines def read(self, length): text = self.text[self.read_pos:length] self.read_pos += len(text) return text def write(self, v): u_v = v.decode('utf-8').replace('\r\n', '\n') self.insert(len(self._lines) - 1, # last line len(self._lines[-1]), # after the last character u_v, u_v.count('\n')) self.scroll_to_end() def scroll_to_end(self): self._anchor = len(self.text) self.curpos = len(self.text) def insert(self, lineno, col, text, linesadded, where=None): self._insert(lineno, col, text, linesadded, where) self.inserted.fire((lineno, col, text, where)) def _insert(self, lineno, col, text, linesadded, where): self.events.append(('insert', self.text, self._lines, locals())) line = self._lines[lineno] front, back = line[:col], line[col:] if linesadded == 0: newline = u''.join([front, text, back]) self._lines[lineno] = newline else: middle = text.split('\n') # splitlines doesn't return an empty new line first, rest = middle[0], middle[1:] newline = u''.join([front, first]) self._lines[lineno] = newline if back: rest[-1] = u''.join([rest[-1], back]) for i, line in enumerate(rest): self._lines.insert(i + lineno + 1, line) def delete(self, lineno, col, text, linesremoved, where=None): self._delete(lineno, col, text, linesremoved, where) self.deleted.fire((lineno, col, text, where)) def _delete(self, lineno, col, text, linesremoved, where): self.events.append(('delete', self.text, self._lines, locals())) length = len(text) if linesremoved == 0: line = self._lines[lineno] front, back = line[:col], line[col+length:] self._lines[lineno] = front + back else: changedlines = self._lines[lineno : lineno + abs(linesremoved) + 1] afterlines = self._lines[lineno + abs(linesremoved) + 1:] text = u'\n'.join(changedlines) front, back = text[:col], text[col+length:] newtext = front + back newlines = newtext.splitlines() if not newlines: newlines.append(u'') del self._lines[lineno:] self._lines.extend(newlines) self._lines.extend(afterlines) if not self._lines: self._lines.append(u'') def __repr__(self): return 'Buffer <%r>' % self.name
def __init__(self): self._buffers = [] self._names_to_bufs = {} self._bufs_to_indexes = {} self.buffer_created = EventHook()