Пример #1
0
class PythonEdit(widget.Edit):  # flow
    """An editbox that colorizes python code.
    A FLOW widget."""

    def __init__(
        self,
        edit_text="",
        multiline=True,
        align="left",
        wrap="space",
        allow_tab=True,
        edit_pos=None,
        layout=None,
        lexer=None,
        formatter=None,
    ):

        if lexer is not None:
            self.lexer = lexer
        else:
            self.lexer = pygments.lexers.get_lexer_by_name("python")

        if formatter is not None:
            self.formatter = formatter
        else:
            self.formatter = UrwidFormatter()

        # note: captions not allowed
        widget.Edit.__init__(self, "", edit_text, multiline, align, wrap, allow_tab, edit_pos, layout)

        if edit_text:
            self.colorize()

        self.enterpressed = False

    def handlekey(self, size, key):
        """Extra magic for a python editor"""
        # deal with double enter - return it
        if key == "enter" and self.multiline and not self.enterpressed:
            self.enterpressed = True
            return urwid.Edit.keypress(self, size, key)

        elif key == "enter" and self.multiline and self.enterpressed:
            return key
        else:
            self.enterpressed = False

        return widget.Edit.keypress(self, size, key)

    def keypress(self, size, key):
        """Handles colorpress"""
        retval = self.handlekey(size, key)
        self.colorize()
        return retval

    @property
    def markup(self):
        return self.get_text()

    def colorize(self):
        text = self.edit_text
        assert hasattr(self, "formatter")
        assert hasattr(self, "lexer")
        tkns = self.lexer.get_tokens(text)
        markup = list(self.formatter.formatgenerator(tkns))
        widget.Text.set_text(self, markup)
Пример #2
0
class InterpreterWidget(urwid.Pile):
    """A widget that looks like an interpreter.

    Note that this is simply a widget, and has no extra functionality;
    it exists to organize the inner widgets."""
    def __init__(self, inputlines=4, caption='>>> '):
        # make inner widgets
        # first the input widgets
        # the input widgets are a 'captionwidget' for the prompt, next
        # to the inputwidget.
        # this means that the prompt is completely uneditable without
        # trying, and also takes care of indenting past the
        # prompt
        
        self.formatter = UrwidFormatter()
        self.lexer = pygments.lexers.get_lexer_by_name('python', stripall='True', ensurenl='False')
        self.errlexer = pygments.lexers.get_lexer_by_name('pytb', stripall='True', ensurenl='False')

        self.inputbox = PromptPyEdit(multiline=True,lexer = self.lexer, formatter = self.formatter)
        self.inputwidget = urwid.Filler(self.inputbox, valign='top')
        
        # the completion box
        self.completionbox = TextGrid()
        
        # the 'upper' box, which can be switched to completions, help, etc.
        self.upperbox = UpperBox(self.completionbox)
        
        # now the output widgets
        self.outputbox = OutputBox()    # Box widget
        self.outputwidget = self.outputbox
        #self.outputwidget = urwid.Filler(self.outputbox, valign='top')
                    # Box widget
        
        # now initialize as a pile
        urwid.Pile.__init__(self, [
            ('flow', self.upperbox),
            self.outputwidget,
            ('fixed', inputlines, self.inputwidget)]
        )
        self.set_focus(self.inputwidget)
    
    def set_input_caption(self, caption):
        self.inputbox.set_prompt(caption)
    
    def highlight(self, txt):
        tkns = self.lexer.get_tokens(txt)
        return list(self.formatter.formatgenerator(tkns))

    def highlight_err(self, txt):
        tkns = self.errlexer.get_tokens(txt)
        return list(self.formatter.formatgenerator(tkns))

    @property
    def input_text(self):
        return self.inputbox.text
    
    @input_text.setter
    def input_text(self, newtxt):
        self.inputbox.text = u''
        
    def set_style(self, s):
        if isinstance(s, basestring):
            s = pygments.styles.get_style_by_name(s)
        self.formatter.style = s
    
    def add_to_output(self, markup):
        self.outputbox.add_stdout(markup)
        return
        
    def _get_widget_size(self, widget, selfsize):
        item_rows = None
        if len(selfsize)==2: # Box widget
            item_rows = self.get_item_rows( selfsize, focus=True )
        i = self.widget_list.index(widget)
        return self.get_item_size(selfsize,i,True,item_rows)
    
    def _passkey(self, widget, size, key):
        """Pass the key along to an inner widget."""
        tsize = self._get_widget_size(widget, size)
        key = widget.keypress( tsize, key )
        return key
    
    def keypress(self, size, key):
        """We do not want the normal urwid.Pile keypress stuff to happen..."""
        # let the focus item use the key, if it can...
        if (self.focus_item.selectable() and 
                self.focus_item is not self.outputwidget):
            key = self._passkey(self.focus_item, size, key)
        
        # try it on the outputbox
    
        origkey = key
        if key in ('up','page up', 'home'):
            self.outputbox.jumptobottom = False
            key = None
        key = self._passkey(self.outputwidget, size, origkey)
        tsize = self._get_widget_size(self.outputwidget, size)
        if (origkey in ('down', 'page down', 'end')
                and self.outputbox.atbottom(tsize)):
            self.outputbox.jumptobottom = True
            key = None
        
        if key == 'ctrl k':
            # switch focus widget
            if self.focus_item is self.outputwidget:
                self.set_focus(self.inputwidget)
            else:
                self.set_focus(self.outputwidget)
            return
        return key