Example #1
0
 def _process_incremental_search_keyevent(self, keyinfo):
     keytuple = keyinfo.tuple()
     log(u"IncrementalSearchPromptMode %s %s"%(keyinfo, keytuple))
     if keyinfo.keyname == u'backspace':
         self.subsearch_query = self.subsearch_query[:-1]
         if len(self.subsearch_query) > 0:
             self.line=self.subsearch_fun(self.subsearch_query)                
         else:
             self._bell()
             self.line = ""   #empty query means no search result
     elif keyinfo.keyname in [u'return', u'escape']:
         self._bell()
         self.prompt = self.subsearch_oldprompt
         self.process_keyevent_queue = self.process_keyevent_queue[:-1]
         self._history.history_cursor = len(self._history.history)
         if keyinfo.keyname == u'escape':
             self.l_buffer.set_line(self.subsearch_old_line)
         return False
     elif keyinfo.keyname:
         pass
     elif keytuple == self.subsearch_init_event:
         self._history.history_cursor += self.subsearch_direction
         self.line = self.subsearch_fun(self.subsearch_query)                
     elif keyinfo.control == False and keyinfo.meta == False :
         self.subsearch_query += keyinfo.char
         self.line=self.subsearch_fun(self.subsearch_query)
     else:
         pass
     self.prompt = self.subsearch_prompt%self.subsearch_query
     self.l_buffer.set_line(self.line)
Example #2
0
 def forward_search_history(self, e):  # (C-s)
     u"""Search forward starting at the current line and moving down
     through the the history as necessary. This is an incremental
     search."""
     log("fwd_search_history")
     self._init_incremental_search(self._history.forward_search_history, e)
     self.finalize()
Example #3
0
 def reverse_search_history(self, e):  # (C-r)
     '''Search backward starting at the current line and moving up
     through the history as necessary. This is an incremental search.'''
     log("rev_search_history")
     self._init_incremental_search(self._history.reverse_search_history, e)
     self.l_buffer.selection_mark = -1
     self.finalize()
Example #4
0
 def clear_range(self, pos_range):
     u'''Clears range that may span to multiple lines
     pos_range is (x1,y1, x2,y2) including
     y2 >= y1
     x2 == -1 means end of line
     '''
     log("clearRange(%s)" % str(pos_range))
     (x1,y1, x2,y2) = pos_range
     if y2 < y1:
         return
     elif y2 == y1 and x2>=0:
         self.pos(x1,y1)
         self._write(' '*(x2-x1+1))
     else:
         start = y1
         end = y2+1
         if x1 > 0:
             self.pos(x1,y1)
             self._write("\033[0K")
             start = y1+1
         if 0 <= x2 < w-1:
             self.pos(x2,y2)
             self._write("\033[1K")
             end = y2
         for line in range(start, end):
             self.pos(0,line)
             self._write("\033[2K")
     self.position = None
     self.pos(x1,y1)
Example #5
0
    def _process_non_incremental_search_keyevent(self, keyinfo):
        keytuple = keyinfo.tuple()
        log(u"SearchPromptMode %s %s" % (keyinfo, keytuple))
        history = self._history

        if keyinfo.keyname == u"backspace":
            self.non_inc_query = self.non_inc_query[:-1]
        elif keyinfo.keyname in [u"return", u"escape"]:
            if self.non_inc_query:
                if self.non_inc_direction == -1:
                    res = history.reverse_search_history(self.non_inc_query)
                else:
                    res = history.forward_search_history(self.non_inc_query)

            self._bell()
            self.prompt = self.non_inc_oldprompt
            self.process_keyevent_queue = self.process_keyevent_queue[:-1]
            self._history.history_cursor = len(self._history.history)
            if keyinfo.keyname == u"escape":
                self.l_buffer = self.non_inc_oldline
            else:
                self.l_buffer.set_line(res)
            return False
        elif keyinfo.keyname:
            pass
        elif keyinfo.control == False and keyinfo.meta == False:
            self.non_inc_query += keyinfo.char
        else:
            pass
        self.prompt = self.non_inc_oldprompt + u":" + self.non_inc_query
Example #6
0
    def reverse_search_history(self, searchfor, startpos=None):
        if startpos is None:
            startpos = self.history_cursor
        origpos = startpos

        result =  lineobj.ReadLineTextBuffer("")

        for idx, line in list(enumerate(self.history))[startpos:0:-1]:
            if searchfor in line:
                startpos = idx
                break

        #If we get a new search without change in search term it means
        #someone pushed ctrl-r and we should find the next match
        if self.last_search_for == searchfor and startpos > 0:
            startpos -= 1
            for idx, line in list(enumerate(self.history))[startpos:0:-1]:
                if searchfor in line:
                    startpos = idx
                    break

        if self.history:                    
            result = self.history[startpos].get_line_text()
        else:
            result = ""
        self.history_cursor = startpos
        self.last_search_for = searchfor
        log("reverse_search_history: old:%d new:%d result:%r"%(origpos, self.history_cursor, result))
        return result
Example #7
0
 def size(self):
     log("size()")
     if self.windowSize:
         log("# returned cached value %s" % str(self.windowSize))
         return self.windowSize
     self._querySize()
     return self.windowSize
Example #8
0
    def test_complete (self):
        import rlcompleter
        logger.sock_silent = False

        log("-" * 50)
        r = EmacsModeTest()
        completerobj = rlcompleter.Completer()
        def _nop(val, word):
            return word
        completerobj._callable_postfix = _nop
        r.completer = completerobj.complete
        r._bind_key("tab", r.complete)
        r.input(u'"exi(ksdjksjd)"')
        r.input(u'Control-a')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Tab')
        self.assert_line(r, u"exit(ksdjksjd)", 4)

        r.input(u'Escape')
        r.input(u'"exi"')
        r.input(u'Control-a')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Tab')
        self.assert_line(r, u"exit", 4)
Example #9
0
 def _setPos(self, x, y):
     if self.positionIsSynchronized and self.position == (x, y):
         return
     self._write("\033[%d;%dH"%(y+1,x+1))
     self.position = (x,y)
     self.positionIsSynchronized = True
     log("_setPos%s" % str(self.position))
Example #10
0
def install_readline(hook):
    log("Installing ansi_console")
    global _old_raw_input
    if _old_raw_input is not None:
        return # don't run _setup twice

    try:
        f_in = sys.stdin.fileno()
        f_out = sys.stdout.fileno()
    except (AttributeError, ValueError):
        return
    if not os.isatty(f_in) or not os.isatty(f_out):
        return

    if '__pypy__' in sys.builtin_module_names:    # PyPy

        def _old_raw_input(prompt=''):
            # sys.__raw_input__() is only called when stdin and stdout are
            # as expected and are ttys.  If it is the case, then get_reader()
            # should not really fail in _wrapper.raw_input().  If it still
            # does, then we will just cancel the redirection and call again
            # the built-in raw_input().
            try:
                del sys.__raw_input__
            except AttributeError:
                pass
            return raw_input(prompt)
        sys.__raw_input__ = hook

    else:
        # this is not really what readline.c does.  Better than nothing I guess
        import __builtin__
        _old_raw_input = __builtin__.raw_input
        __builtin__.raw_input = hook
Example #11
0
 def get_current_history_length(self):
     '''Return the number of lines currently in the history.
     (This is different from get_history_length(), which returns 
     the maximum number of lines that will be written to a history file.)'''
     value = len(self.history)
     log("get_current_history_length:%d"%value)
     return value
Example #12
0
    def _init_incremental_search(self, searchfun, init_event):
        u"""Initialize search prompt
        """
        log("init_incremental_search")
        self.subsearch_query = u""
        self.subsearch_fun = searchfun
        self.subsearch_old_line = self.l_buffer.get_line_text()

        queue = self.process_keyevent_queue
        queue.append(self._process_incremental_search_keyevent)

        self.subsearch_oldprompt = self.prompt

        if self.previous_func != self.reverse_search_history and self.previous_func != self.forward_search_history:
            self.subsearch_query = self.l_buffer[0:Point].get_line_text()

        if self.subsearch_fun == self.reverse_search_history:
            self.subsearch_prompt = u"reverse-i-search%d`%s': "
        else:
            self.subsearch_prompt = u"forward-i-search%d`%s': "

        self.prompt = self.subsearch_prompt % (self._history.history_cursor, "")

        if self.subsearch_query:
            self.line = self._process_incremental_search_keyevent(init_event)
        else:
            self.line = u""
Example #13
0
 def cursor(self, visible=None, size=None):
     log("cursor(visible='%s')" % visible)
     if visible is not None:
         if visible:
             self._write("\033[?25h")
         else:
             self._write("\033[?25l")
Example #14
0
    def _readline_from_keyboard(self):
        c = self.console
        while 1:
            self._update_line()
            event = c.getkeypress()
            if self.next_meta:
                self.next_meta = False
                control, meta, shift, code = event.keyinfo
                event.keyinfo = (control, True, shift, code)

            # Process exit keys. Only exit on empty line
            if event.keyinfo in self.exit_dispatch:
                if lineobj.EndOfLine(self.l_buffer) == 0:
                    raise EOFError

            dispatch_func = self.key_dispatch.get(event.keyinfo, self.self_insert)
            log("readline from keyboard:%s" % (event.keyinfo,))
            r = None
            if dispatch_func:
                r = dispatch_func(event)
                self.l_buffer.push_undo()

            self.previous_func = dispatch_func
            if r:
                self._update_line()
                break
Example #15
0
 def paste(self,e):
     '''Paste windows clipboard.
     Assume single line strip other lines and end of line markers and trailing spaces''' #(Control-v)
     if self.enable_win32_clipboard:
             txt=clipboard.get_clipboard_text_and_convert(False)
             txt=txt.split("\n")[0].strip("\r").strip("\n")
             log("paste: >%s<"%map(ord,txt))
             self.insert_text(txt)
Example #16
0
 def _bind_key(self, key, func):
     '''setup the mapping from key to call the function.'''
     if type(func) != type(self._bind_key):
         print "Trying to bind non method to keystroke:%s,%s"%(key,func)
         raise PyreadlineError("Trying to bind non method to keystroke:%s,%s,%s,%s"%(key,func,type(func),type(self._bind_key)))
     keyinfo = make_KeyPress_from_keydescr(key.lower()).tuple()
     log(">>>%s -> %s<<<"%(keyinfo,func.__name__))
     self.key_dispatch[keyinfo] = func
Example #17
0
 def forward_search_history(self, e):  # (C-s)
     '''Search forward starting at the current line and moving down
     through the the history as necessary. This is an incremental
     search.'''
     log("fwd_search_history")
     self._init_incremental_search(self._history.forward_search_history, e)
     self.l_buffer.selection_mark = -1
     self.finalize()
Example #18
0
    def _readline_from_keyboard(self):
        c = self.console

        def nop(e):
            pass

        while 1:
            self._update_line()
            lbuf = self.l_buffer
            log_sock("point:%d mark:%d selection_mark:%d" % (lbuf.point, lbuf.mark, lbuf.selection_mark))
            try:
                event = c.getkeypress()
                log_sock(u">>%s" % event)
            except KeyboardInterrupt:
                from pyreadline.keysyms.common import KeyPress
                from pyreadline.console.event import Event
                event = Event(0, 0)
                event.char = "c"
                event.keyinfo = KeyPress("c", shift=False, control=True, meta=False, keyname=None)
                log_sock("KBDIRQ")
                if self.allow_ctrl_c:
                    now = time.time()
                    if (now - self.ctrl_c_timeout) < self.ctrl_c_tap_time_interval:
                        raise
                    else:
                        self.ctrl_c_timeout = now
                    pass
                else:
                    raise
            if self.next_meta:
                self.next_meta = False
                control, meta, shift, code = event.keyinfo
                event.keyinfo = (control, True, shift, code)

            # Process exit keys. Only exit on empty line
            keyinfo = event.keyinfo.tuple()
            if keyinfo in self.exit_dispatch:
                if lineobj.EndOfLine(self.l_buffer) == 0:
                    raise EOFError
            if len(keyinfo[-1]) > 1:
                default = nop
            else:
                default = self.self_insert
            dispatch_func = self.key_dispatch.get(keyinfo, default)

            log("readline from keyboard:%s,%s" % (keyinfo, dispatch_func))
            log_sock((u"%s|%s" % (ensure_unicode(format(keyinfo)), dispatch_func.__name__)), "bound_function")
            r = None
            if dispatch_func:
                r = dispatch_func(event)
                self._keylog(dispatch_func, self.l_buffer)
                self.l_buffer.push_undo()

            self.previous_func = dispatch_func
            if r:
                self._update_line()
                break
Example #19
0
 def write_plain(self, text, attr=None):
     '''write text at current cursor position.'''
     log('write("%s", %s)' %(text,attr))
     if attr is None:
         attr = self.attr
     n = c_int(0)
     self.SetConsoleTextAttribute(self.hout, attr)
     self.WriteConsoleW(self.hout, ensure_unicode(chunk), len(chunk), byref(junk), None)
     return len(text)
Example #20
0
 def write_plain(self, text, attr=None):
     u'''write text at current cursor position.'''
     log(u'write("%s", %s)' %(text, attr))
     if attr is None:
         attr = self.attr
     n = c_int(0)
     self.SetConsoleTextAttribute(self.hout, attr)
     self.WriteConsoleA(self.hout, text, len(text), byref(n), None)
     return len(text)
Example #21
0
    def write_scrolling(self, text, attr=None):
        '''write text at current cursor position while watching for scrolling.

        If the window scrolls because you are at the bottom of the screen
        buffer, all positions that you are storing will be shifted by the
        scroll amount. For example, I remember the cursor position of the
        prompt so that I can redraw the line but if the window scrolls,
        the remembered position is off.

        This variant of write tries to keep track of the cursor position
        so that it will know when the screen buffer is scrolled. It
        returns the number of lines that the buffer scrolled.

        '''
        x, y = self.pos()
        w, h = self.size()
        scroll = 0 # the result

        # split the string into ordinary characters and funny characters
        chunks = self.motion_char_re.split(text)
        for chunk in chunks:
            log('C:'+chunk)
            n = self.write_color(chunk, attr)
            if len(chunk) == 1: # the funny characters will be alone
                if chunk[0] == '\n': # newline
                    x = 0
                    y += 1
                elif chunk[0] == '\r': # carriage return
                    x = 0
                elif chunk[0] == '\t': # tab
                    x = 8*(int(x/8)+1)
                    if x > w: # newline
                        x -= w
                        y += 1
                elif chunk[0] == '\007': # bell
                    pass
                elif chunk[0] == '\010':
                    x -= 1
                    if x < 0:
                        y -= 1 # backed up 1 line
                else: # ordinary character
                    x += 1
                if x == w: # wrap
                    x = 0
                    y += 1
                if y == h: # scroll
                    scroll += 1
                    y = h - 1
            else: # chunk of ordinary characters
                x += n
                l = int(x / w) # lines we advanced
                x = x % w # new x value
                y += l
                if y >= h: # scroll
                    scroll += y - h + 1
                    y = h - 1
        return scroll
Example #22
0
 def apply_attrs(self, attrs):
     if attrs is None:
         attrs = 0
     if attrs == self.saveattr:
         return
     attrs_str = self.get_attrs_str(attrs)
     log("new attribute string is: %s", attrs_str)
     self._write("\033[%sm" % attrs_str)
     self.saveattr = attrs
Example #23
0
 def _querySize(self):
     try:
         w = self._readIntFromCmd("tput cols")
         h = self._readIntFromCmd("tput lines")
         self.windowSize = (w,h)
         log("size() # = " + str(self.windowSize))
     except:
         print "Get terminal size failed, exitting"
         sys.exit(1)
Example #24
0
 def write(self, s):
     if s == "\r\n":
         log("write('\\r\\n')")
         # reset window size each time we enter new line
         self.windowSize = None
     else:
         log("write('%s')" % s)
     
     self.position = None
     return self._write(s)
Example #25
0
 def write_color(self, text, attr=None):
     text = ensure_unicode(text)
     n,res= self.ansiwriter.write_color(text,attr)
     junk = c_int(0)
     for attr,chunk in res:
         log(unicode(attr))
         log(unicode(chunk))
         self.SetConsoleTextAttribute(self.hout, attr.winattr)
         self.WriteConsoleW(self.hout, chunk, len(chunk), byref(junk), None)
     return n
Example #26
0
 def write_color(self, text, attr=None):
     text = ensure_unicode(text)
     n, res = self.ansiwriter.write_color(text, attr)
     junk = DWORD(0)
     for attr, chunk in res:
         log(u"console.attr:%s" % unicode(attr))
         log(u"console.chunk:%s" % unicode(chunk))
         self.SetConsoleTextAttribute(self.hout, attr.winattr)
         for short_chunk in split_block(chunk):
             self.WriteConsoleW(self.hout, short_chunk, len(short_chunk), byref(junk), None)
     return n
Example #27
0
 def write_plain(self, text, attr=None):
     u"""write text at current cursor position."""
     text = ensure_unicode(text)
     log(u'write("%s", %s)' % (text, attr))
     if attr is None:
         attr = self.attr
     junk = DWORD(0)
     self.SetConsoleTextAttribute(self.hout, attr)
     for short_chunk in split_block(chunk):
         self.WriteConsoleW(self.hout, ensure_unicode(short_chunk), len(short_chunk), byref(junk), None)
     return len(text)
Example #28
0
    def __init__(self, newbuffer=0):
        '''Initialize the Console object.

        newbuffer=1 will allocate a new buffer so the old content will be restored
        on exit.
        '''
        self.serial = 0
        self.attr = System.Console.ForegroundColor
        self.saveattr = winattr[str(System.Console.ForegroundColor).lower()]
        self.savebg = System.Console.BackgroundColor
        log('initial attr=%s' % self.attr)
Example #29
0
 def input (self, keytext):
     if keytext[0:1] == u'"' and keytext[-1:] == u'"':
         lst_key = [u'"%s"' % c for c in keytext[1:-1]]
     else:
         lst_key = [keytext]
     for key in lst_key:
         keyinfo, event = keytext_to_keyinfo_and_event (key)
         dispatch_func = self.key_dispatch.get(keyinfo.tuple(),self.self_insert)
         self.tested_commands[dispatch_func.__name__]=dispatch_func
         log(u"keydisp: %s %s"%( key,dispatch_func.__name__))
         dispatch_func (event)
         self.previous_func=dispatch_func
Example #30
0
    def getKey(self, timeout=365*24*3600):
        if not self.sequence:
            self._updateSequence(timeout)
            if not self.sequence:
                return None
        log("Key Sequence len=%d" % len(self.sequence))
        res = convertSequence(self.sequence, offset=self.offset)
        self.offset = res[1]

        if self.offset == len(self.sequence):
            self._resetSequence()
        
        return res[0]
Example #31
0
 def getkeypress(self):
     """Return next key press event from the queue, ignoring others."""
     while 1:
         e = self.get()
         if e.type == "KeyPress" and e.keycode not in key_modifiers:
             log("console.getkeypress %s" % e)
             if e.keyinfo.keyname == "next":
                 self.scroll_window(12)
             elif e.keyinfo.keyname == "prior":
                 self.scroll_window(-12)
             else:
                 return e
         elif (e.type == "KeyRelease") and (
             e.keyinfo == KeyPress("S", False, True, False, "S")
         ):
             log("getKeypress:%s,%s,%s" % (e.keyinfo, e.keycode, e.type))
             return e
Example #32
0
 def paste_mulitline_code(self,e):
     """Paste windows clipboard as multiline code.
     Removes any empty lines in the code"""
     reg=re.compile("\r?\n")
     if self.enable_win32_clipboard:
             txt=clipboard.get_clipboard_text_and_convert(False)
             t=reg.split(txt)
             t=[row for row in t if row.strip()!=""] #remove empty lines
             if t!=[""]:
                 self.insert_text(t[0])
                 self.add_history(self.l_buffer.copy())
                 self.paste_line_buffer=t[1:]
                 log("multi: >%s<"%self.paste_line_buffer)
                 return True
             else:
                 return False
     self.finalize()
Example #33
0
    def _process_incremental_search_keyevent(self, keyinfo):
        log("_process_incremental_search_keyevent")
        keytuple = keyinfo.tuple()
        #dispatch_func = self.key_dispatch.get(keytuple, default)
        revtuples = []
        fwdtuples = []
        for ktuple, func in self.key_dispatch.iteritems():
            if func == self.reverse_search_history:
                revtuples.append(ktuple)
            elif func == self.forward_search_history:
                fwdtuples.append(ktuple)

        log(u"IncrementalSearchPromptMode %s %s" % (keyinfo, keytuple))
        if keyinfo.keyname == u'backspace':
            self.subsearch_query = self.subsearch_query[:-1]
            if len(self.subsearch_query) > 0:
                self.line = self.subsearch_fun(self.subsearch_query)
            else:
                self._bell()
                self.line = ""  # empty query means no search result
        elif keyinfo.keyname in [u'return', u'escape']:
            self._bell()
            self.prompt = self.subsearch_oldprompt
            self.process_keyevent_queue = self.process_keyevent_queue[:-1]
            self._history.history_cursor = len(self._history.history)
            if keyinfo.keyname == u'escape':
                self.l_buffer.set_line(self.subsearch_old_line)
            return True
        elif keyinfo.keyname:
            pass
        elif keytuple in revtuples:
            self.subsearch_fun = self._history.reverse_search_history
            self.subsearch_prompt = u"reverse-i-search%d`%s': "
            self.line = self.subsearch_fun(self.subsearch_query)
        elif keytuple in fwdtuples:
            self.subsearch_fun = self._history.forward_search_history
            self.subsearch_prompt = u"forward-i-search%d`%s': "
            self.line = self.subsearch_fun(self.subsearch_query)
        elif keyinfo.control == False and keyinfo.meta == False:
            self.subsearch_query += keyinfo.char
            self.line = self.subsearch_fun(self.subsearch_query)
        else:
            pass
        self.prompt = self.subsearch_prompt % (self._history.history_cursor,
                                               self.subsearch_query)
        self.l_buffer.set_line(self.line)
Example #34
0
    def _init_digit_argument(self, keyinfo):
        """Initialize search prompt
        """
        c = self.console
        line = self.l_buffer.get_line_text()
        self._digit_argument_oldprompt = self.prompt
        queue = self.process_keyevent_queue
        queue = self.process_keyevent_queue
        queue.append(self._process_digit_argument_keyevent)

        if keyinfo.char == "-":
            self.argument = -1
        elif keyinfo.char in "0123456789":
            self.argument = int(keyinfo.char)
        log("<%s> %s" % (self.argument, type(self.argument)))
        self.prompt = "(arg: %s) " % self.argument
        log("arg-init %s %s" % (self.argument, keyinfo.char))
Example #35
0
    def __init__(self, newbuffer=0):
        '''Initialize the Console object.

        newbuffer=1 will allocate a new buffer so the old content will be restored
        on exit.
        '''
        #Do I need the following line? It causes a console to be created whenever
        #readline is imported into a pythonw application which seems wrong. Things
        #seem to work without it...
        #self.AllocConsole()

        if newbuffer:
            self.hout = self.CreateConsoleScreenBuffer(
                             GENERIC_READ | GENERIC_WRITE,
                             0, None, 1, None)
            self.SetConsoleActiveScreenBuffer(self.hout)
        else:
            self.hout = self.GetStdHandle(STD_OUTPUT_HANDLE)

        self.hin = self.GetStdHandle(STD_INPUT_HANDLE)
        self.inmode = DWORD(0)
        self.GetConsoleMode(self.hin, byref(self.inmode))
        self.SetConsoleMode(self.hin, 0xf)
        info = CONSOLE_SCREEN_BUFFER_INFO()
        self.GetConsoleScreenBufferInfo(self.hout, byref(info))
        self.attr = info.wAttributes
        self.saveattr = info.wAttributes # remember the initial colors
        self.defaultstate = AnsiState()
        self.defaultstate.winattr = info.wAttributes
        self.ansiwriter = AnsiWriter(self.defaultstate)
        
        background = self.attr & 0xf0
        for escape in self.escape_to_color:
            if self.escape_to_color[escape] is not None:
                self.escape_to_color[escape] |= background
        log('initial attr=%x' % self.attr)
        self.softspace = 0 # this is for using it as a file-like object
        self.serial = 0

        self.pythondll = \
            CDLL('python%s%s' % (sys.version[0], sys.version[2]))
        self.pythondll.PyMem_Malloc.restype = c_size_t
        self.pythondll.PyMem_Malloc.argtypes = [c_size_t]
        self.inputHookPtr = \
            c_void_p.from_address(addressof(self.pythondll.PyOS_InputHook)).value
        setattr(Console, 'PyMem_Malloc', self.pythondll.PyMem_Malloc)
Example #36
0
 def write_plain(self, text, attr=None):
     """Write text at current cursor position."""
     text = ensure_unicode(text)
     log('write("%s", %s)' % (text, attr))
     if attr is None:
         attr = self.attr
     junk = DWORD(0)
     self.SetConsoleTextAttribute(self.hout, attr)
     for short_chunk in split_block(chunk):
         self.WriteConsoleW(
             self.hout,
             ensure_unicode(short_chunk),
             len(short_chunk),
             byref(junk),
             None,
         )
     return len(text)
Example #37
0
 def pos(self, x=None, y=None):
     log(u"ansi_console.pos(%s, %s)" % (x, y))
     if x is not None and y is not None:
         self._setPos(x, y)
         return (x, y)
     else:
         (oldX, oldY) = self._queryPos()
         if x is not None or y is not None:
             needToUpdate = True
         else:
             needToUpdate = False
         if x is None:
             x = oldX
         if y is None:
             y = oldY
         if needToUpdate:
             self._setPos(x, y)
         return (x, y)
Example #38
0
    def readline(self, prompt=""):
        """Prompt the user for a line of text.

        Clear the console as necessary, redraw according to user actions
        and report exceptions as they're raised.
        """
        # handle startup_hook
        if self.first_prompt:
            self.first_prompt = False
            if self.startup_hook:
                try:
                    self.startup_hook()
                except:
                    print("startup hook failed")
                    traceback.print_exc()

        c = self.console
        self.l_buffer.reset_line()
        self.prompt = prompt
        self._print_prompt()

        if self.pre_input_hook:
            try:
                self.pre_input_hook()
            except:
                print("pre_input_hook failed")
                traceback.print_exc()
                self.pre_input_hook = None

        log("in readline: %s" % self.paste_line_buffer)
        if len(self.paste_line_buffer) > 0:
            self.l_buffer = lineobj.ReadlineTextBuffer(
                self.paste_line_buffer[0])
            self._update_line()
            self.paste_line_buffer = self.paste_line_buffer[1:]
            c.write("\r\n")
        else:
            self._readline_from_keyboard()
            c.write("\r\n")

        self.add_history(self.l_buffer.copy())

        log("returning(%s)" % self.l_buffer.get_line_text())
        return self.l_buffer.get_line_text() + "\n"
Example #39
0
    def _readline_from_keyboard_poll(self):
        c = self.console

        def nop(e):
            pass

        try:
            event = c.getkeypress()
        except KeyboardInterrupt:
            event = self.handle_ctrl_c()
            self._update_line()
            return False

        if self.next_meta:
            self.next_meta = False
            control, meta, shift, code = event.keyinfo
            event.keyinfo = (control, True, shift, code)

        #Process exit keys. Only exit on empty line
        keyinfo = event.keyinfo.tuple()
        if keyinfo in self.exit_dispatch:
            if lineobj.EndOfLine(self.l_buffer) == 0:
                raise EOFError
        if len(keyinfo[-1]) > 1:
            default = nop
        else:
            default = self.self_insert
        dispatch_func = self.key_dispatch.get(keyinfo, default)

        log("readline from keyboard:%s,%s" % (keyinfo, dispatch_func))
        log_sock("%s|%s" % (format(keyinfo), dispatch_func.__name__),
                 "bound_function")
        r = None
        if dispatch_func:
            r = dispatch_func(event)
            self._keylog(dispatch_func, self.l_buffer)
            self.l_buffer.push_undo()

        self.previous_func = dispatch_func
        self._update_line()
        if r:
            return True
        return False
Example #40
0
    def process_keyevent(self, keyinfo):
        def nop(e):
            pass

        keytuple = keyinfo.tuple()
        if keytuple in self.exit_dispatch:
            if lineobj.EndOfLine(self.l_buffer) == 0:
                raise EOFError
        dispatch_func = self.key_dispatch.get(keytuple, self.vi_key)
        log('readline from keyboard:%s->%s' % (keytuple, dispatch_func))
        r = None
        if dispatch_func:
            r = dispatch_func(keyinfo)
            self.l_buffer.push_undo()
        self.previous_func = dispatch_func
        if r:
            self._update_line()
            return True
        return False
Example #41
0
 def _init_incremental_search(self, searchfun, init_event):
     log('init_incremental_search')
     self.subsearch_query = ''
     self.subsearch_fun = searchfun
     self.subsearch_old_line = self.l_buffer.get_line_text()
     queue = self.process_keyevent_queue
     queue.append(self._process_incremental_search_keyevent)
     self.subsearch_oldprompt = self.prompt
     if self.previous_func != self.reverse_search_history and self.previous_func != self.forward_search_history:
         self.subsearch_query = self.l_buffer[0:Point].get_line_text()
     if self.subsearch_fun == self.reverse_search_history:
         self.subsearch_prompt = "reverse-i-search%d`%s': "
     else:
         self.subsearch_prompt = "forward-i-search%d`%s': "
     self.prompt = self.subsearch_prompt % (self._history.history_cursor, '')
     if self.subsearch_query:
         self.line = self._process_incremental_search_keyevent(init_event)
     else:
         self.line = ''
Example #42
0
    def _process_incremental_search_keyevent(self, keyinfo):
        log('_process_incremental_search_keyevent')
        keytuple = keyinfo.tuple()
        revtuples = []
        fwdtuples = []
        for ktuple, func in self.key_dispatch.iteritems():
            if func == self.reverse_search_history:
                revtuples.append(ktuple)
            elif func == self.forward_search_history:
                fwdtuples.append(ktuple)

        log('IncrementalSearchPromptMode %s %s' % (keyinfo, keytuple))
        if keyinfo.keyname == 'backspace':
            self.subsearch_query = self.subsearch_query[:-1]
            if len(self.subsearch_query) > 0:
                self.line = self.subsearch_fun(self.subsearch_query)
            else:
                self._bell()
                self.line = ''
        else:
            if keyinfo.keyname in ('return', 'escape'):
                self._bell()
                self.prompt = self.subsearch_oldprompt
                self.process_keyevent_queue = self.process_keyevent_queue[:-1]
                self._history.history_cursor = len(self._history.history)
                if keyinfo.keyname == 'escape':
                    self.l_buffer.set_line(self.subsearch_old_line)
                return True
            if keyinfo.keyname:
                pass
            elif keytuple in revtuples:
                self.subsearch_fun = self._history.reverse_search_history
                self.subsearch_prompt = "reverse-i-search%d`%s': "
                self.line = self.subsearch_fun(self.subsearch_query)
            elif keytuple in fwdtuples:
                self.subsearch_fun = self._history.forward_search_history
                self.subsearch_prompt = "forward-i-search%d`%s': "
                self.line = self.subsearch_fun(self.subsearch_query)
            elif keyinfo.control == False and keyinfo.meta == False:
                self.subsearch_query += keyinfo.char
                self.line = self.subsearch_fun(self.subsearch_query)
        self.prompt = self.subsearch_prompt % (self._history.history_cursor, self.subsearch_query)
        self.l_buffer.set_line(self.line)
Example #43
0
 def _get_completions(self):
     """Return a list of possible completions for the string ending at the point.
     Also set begidx and endidx in the process."""
     completions = []
     self.begidx = self.l_buffer.point
     self.endidx = self.l_buffer.point
     buf = self.l_buffer.line_buffer
     if self.completer:
         # get the string to complete
         while self.begidx > 0:
             self.begidx -= 1
             if buf[self.begidx] in self.completer_delims:
                 self.begidx += 1
                 break
         text = ensure_str(''.join(buf[self.begidx:self.endidx]))
         log('complete text="%s"' % ensure_unicode(text))
         i = 0
         while 1:
             try:
                 r = self.completer(ensure_unicode(text), i)
             except IndexError:
                 break
             i += 1
             if r is None:
                 break
             elif r and r not in completions:
                 completions.append(r)
             else:
                 pass
         log('text completions=<%s>' %
             list(map(ensure_unicode, completions)))
     if (self.complete_filesystem == "on") and not completions:
         # get the filename to complete
         while self.begidx > 0:
             self.begidx -= 1
             if buf[self.begidx] in ' \t\n':
                 self.begidx += 1
                 break
         text = ensure_str(''.join(buf[self.begidx:self.endidx]))
         log('file complete text="%s"' % ensure_unicode(text))
         completions = list(
             map(ensure_unicode,
                 glob.glob(os.path.expanduser(text) + '*'.encode('ascii'))))
         if self.mark_directories == 'on':
             mc = []
             for f in completions:
                 if os.path.isdir(f):
                     mc.append(f + os.sep)
                 else:
                     mc.append(f)
             completions = mc
         log('fnames=<%s>' % list(map(ensure_unicode, completions)))
     return completions
Example #44
0
    def readline(self, prompt=''):
        '''Try to act like GNU readline.'''
        # handle startup_hook
        self.ctrl_c_timeout = time.time()
        self.l_buffer.selection_mark = -1
        if self.first_prompt:
            self.first_prompt = False
            if self.startup_hook:
                try:
                    self.startup_hook()
                except:
                    print 'startup hook failed'
                    traceback.print_exc()

        c = self.console
        self.l_buffer.reset_line()
        self.prompt = prompt
        self._print_prompt()

        if self.pre_input_hook:
            try:
                self.pre_input_hook()
            except:
                print 'pre_input_hook failed'
                traceback.print_exc()
                self.pre_input_hook = None

        log("in readline: %s" % self.paste_line_buffer)
        if len(self.paste_line_buffer) > 0:
            self.l_buffer = lineobj.ReadLineTextBuffer(
                self.paste_line_buffer[0])
            self._update_line()
            self.paste_line_buffer = self.paste_line_buffer[1:]
            c.write('\r\n')
        else:
            self._readline_from_keyboard()
            c.write('\r\n')

        self.add_history(self.l_buffer.copy())

        log('returning(%s)' % self.l_buffer.get_line_text())
        return self.l_buffer.get_line_text() + '\n'
Example #45
0
    def readline(self, prompt=""):
        """Callback that returns after every line is sent by the user.

        Returns
        -------
        `get_line_buffer` with a newline after.

        Notes
        -----
        Updates 'ctrl_c_timeout'.

        """
        self.readline_setup(prompt)
        self._readline_from_keyboard()
        self.console.write("\r\n")
        line = self.get_line_buffer()
        if line != "":
            log("Returning. Line Buffer: (%s) " % line)

        return line + "\n"
Example #46
0
    def handle_ctrl_c(self):
        from pyreadline.keysyms.common import KeyPress
        from pyreadline.console.event import Event

        log("KBDIRQ")
        event = Event(0, 0)
        event.char = "c"
        event.keyinfo = KeyPress(
            "c", shift=False, control=True, meta=False, keyname=None
        )
        if self.allow_ctrl_c:
            now = time.time()
            if (now - self.ctrl_c_timeout) < self.ctrl_c_tap_time_interval:
                log("Raise KeyboardInterrupt")
                raise KeyboardInterrupt
            else:
                self.ctrl_c_timeout = now
        else:
            raise KeyboardInterrupt
        return event
Example #47
0
    def _bind_key(self, key, func):
        """Setup the mapping from key to call the function.

        Parameters
        ----------
        func : function
            Must be callable.

        Raises
        ------
        ReadlineError
        """
        if not callable(func):
            print("Trying to bind non method to keystroke:%s,%s" % (key, func))
            raise ReadlineError(
                "Trying to bind non method to keystroke:%s,%s,%s,%s"
                % (key, func, type(func), type(self._bind_key))
            )
        keyinfo = make_KeyPress_from_keydescr(key.lower()).tuple()
        log(">>>%s -> %s<<<" % (keyinfo, func.__name__), logging.DEBUG)
        self.key_dispatch[keyinfo] = func
Example #48
0
    def scroll_window(self, lines):
        '''Scroll the window by the indicated number of lines.'''
        info = CONSOLE_SCREEN_BUFFER_INFO()
        self.GetConsoleScreenBufferInfo(self.hout, byref(info))
        rect = info.srWindow
        log('sw: rtop=%d rbot=%d' % (rect.Top, rect.Bottom))
        top = rect.Top + lines
        bot = rect.Bottom + lines
        h = bot - top
        maxbot = info.dwSize.Y - 1
        if top < 0:
            top = 0
            bot = h
        if bot > maxbot:
            bot = maxbot
            top = bot - h

        nrect = SMALL_RECT()
        nrect.Top = top
        nrect.Bottom = bot
        nrect.Left = rect.Left
        nrect.Right = rect.Right
        log('sn: top=%d bot=%d' % (top, bot))
        r = self.SetConsoleWindowInfo(self.hout, True, byref(nrect))
        log('r=%d' % r)
Example #49
0
    def write_color(self, text, attr=None):
        """write text at current cursor position and interpret color escapes.

        return the number of characters written.
        """
        log('write_color("%s", %s)' % (text, attr))
        chunks = self.terminal_escape.split(text)
        log("chunks=%s" % repr(chunks))
        bg = self.savebg
        n = 0  # count the characters we actually write, omitting the escapes
        if attr is None:  # use attribute from initial console
            attr = self.attr
        try:
            fg = self.trtable[(0x000F & attr)]
            bg = self.trtable[(0x00F0 & attr) >> 4]
        except TypeError:
            fg = attr

        for chunk in chunks:
            m = self.escape_parts.match(chunk)
            if m:
                log(m.group(1))
                attr = ansicolor.get(m.group(1), self.attr)
            n += len(chunk)
            System.Console.ForegroundColor = fg
            System.Console.BackgroundColor = bg
            System.Console.Write(chunk)
        return n
Example #50
0
    def _process_keyevent(self, keyinfo):
        log('_process_keyevent <%s>' % keyinfo)

        def nop(e):
            pass

        if self.next_meta:
            self.next_meta = False
            keyinfo.meta = True
        keytuple = keyinfo.tuple()
        if self._insert_verbatim:
            self.insert_text(keyinfo)
            self._insert_verbatim = False
            self.argument = 0
            return False
        if keytuple in self.exit_dispatch:
            pars = (
             self.l_buffer, lineobj.EndOfLine(self.l_buffer))
            log('exit_dispatch:<%s, %s>' % pars)
            if lineobj.EndOfLine(self.l_buffer) == 0:
                raise EOFError
        if keyinfo.keyname or keyinfo.control or keyinfo.meta:
            default = nop
        else:
            default = self.self_insert
        dispatch_func = self.key_dispatch.get(keytuple, default)
        log('readline from keyboard:<%s,%s>' % (keytuple, dispatch_func))
        r = None
        if dispatch_func:
            r = dispatch_func(keyinfo)
            self._keylog(dispatch_func, self.l_buffer)
            self.l_buffer.push_undo()
        self.previous_func = dispatch_func
        return r
Example #51
0
    def _get_completions(self):
        '''Return a list of possible completions for the string ending at the point.

        Also set begidx and endidx in the process.'''
        completions = []
        self.begidx = self.l_buffer.point
        self.endidx = self.l_buffer.point
        buf = self.l_buffer.line_buffer
        if self.completer:
            # get the string to complete
            while self.begidx > 0:
                self.begidx -= 1
                if buf[self.begidx] in self.completer_delims:
                    self.begidx += 1
                    break
            text = ensure_str(''.join(buf[self.begidx:self.endidx]))
            log('complete text="%s"' % text)
            i = 0
            while 1:
                try:
                    r = ensure_unicode(self.completer(text, i))
                except:
                    break
                i += 1
                if r and r not in completions:
                    completions.append(r)
                else:
                    break
            log('text completions=%s' % completions)
        if not completions:
            # get the filename to complete
            while self.begidx > 0:
                self.begidx -= 1
                if buf[self.begidx] in ' \t\n':
                    self.begidx += 1
                    break
            text = ensure_str(''.join(buf[self.begidx:self.endidx]))
            log('file complete text="%s"' % text)
            completions = map(ensure_unicode,
                              glob.glob(os.path.expanduser(text) + '*'))
            if self.mark_directories == 'on':
                mc = []
                for f in completions:
                    if os.path.isdir(f):
                        mc.append(f + os.sep)
                    else:
                        mc.append(f)
                completions = mc
            log('fnames=%s' % completions)
        return completions
Example #52
0
    def debug_output(self, on, filename="pyreadline_debug_log.txt"):
        """Initialize the loggers used through the repository.

        Parameters
        ----------
        on : str
            One of 'on' or 'on_nologfile'. If is any other value, the
            global logger instance will be stopped.
        filename : str (pathlike)
            Path of the logfile

        """

        if on in ["on", "on_nologfile"]:
            self.debug = True

        if on == "on":
            logger.start_file_log(filename)
            logger.start_socket_log()
            logger.log("STARTING LOG")
        elif on == "on_nologfile":
            logger.start_socket_log()
            logger.log("STARTING LOG")
        else:
            logger.log("STOPING LOG")
            logger.stop_file_log()
            logger.stop_socket_log()
Example #53
0
    def readline(self, prompt=""):
        """Try to act like GNU readline."""
        # handle startup_hook
        if self.first_prompt:
            self.first_prompt = False
            if self.startup_hook:
                try:
                    self.startup_hook()
                except:
                    print "startup hook failed"
                    traceback.print_exc()

        c = self.console
        self.l_buffer.reset_line()
        self.prompt = prompt
        self._print_prompt()

        if self.pre_input_hook:
            try:
                self.pre_input_hook()
            except:
                print "pre_input_hook failed"
                traceback.print_exc()
                self.pre_input_hook = None

        log("in readline: %s" % self.paste_line_buffer)
        if len(self.paste_line_buffer) > 0:
            self.l_buffer = lineobj.ReadlineTextBuffer(
                self.paste_line_buffer[0])
            self._update_line()
            self.paste_line_buffer = self.paste_line_buffer[1:]
            c.write("\r\n")
        else:
            self._readline_from_keyboard()
            c.write("\r\n")

        self.add_history(self.l_buffer.copy())

        log("returning(%s)" % self.l_buffer.get_line_text())
        return self.l_buffer.get_line_text() + "\n"
Example #54
0
 def parse_and_bind(self, string):
     """Parse and execute single line of a readline init file."""
     log('parse_and_bind("%s")' % string, logging.DEBUG)
     if string.startswith("#"):
         return
     try:
         if string.startswith("set"):
             m = re.compile(r"set\s+([-a-zA-Z0-9]+)\s+(.+)\s*$").match(string)
             if m:
                 var_name = m.group(1)
                 val = m.group(2)
                 try:
                     setattr(self.mode, var_name.replace("-", "_"), val)
                 except AttributeError:
                     log('unknown var="%s" val="%s"' % (var_name, val))
             else:
                 log('bad set "%s"' % string)
             return
         m = re.compile(r"\s*(.+)\s*:\s*([-a-zA-Z]+)\s*$").match(string)
         if m:
             key = m.group(1)
             func_name = m.group(2)
             py_name = func_name.replace("-", "_")
             try:
                 func = getattr(self.mode, py_name)
             except AttributeError:
                 log('unknown func key="%s" func="%s"' % (key, func_name))
                 if self.debug:
                     print(
                         'pyreadline parse_and_bind error, unknown function to bind: "%s"'
                         % func_name
                     )
                 return
             self.mode._bind_key(key, func)
     except Exception:
         log("error")
         raise
Example #55
0
    def reverse_search_history(self, searchfor, startpos=None):
        if startpos is None:
            startpos = self.history_cursor
        origpos = startpos

        result = lineobj.ReadLineTextBuffer("")

        find_pos = -1
        for idx, line in list(enumerate(self.history))[startpos:0:-1]:
            find_pos = line.find(searchfor)
            if find_pos >= 0:
                startpos = idx
                break

        #If we get a new search without change in search term it means
        #someone pushed ctrl-r and we should find the next match
        if self.last_search_for == searchfor and startpos > 0:
            startpos -= 1
            for idx, line in list(enumerate(self.history))[startpos:0:-1]:
                find_pos = line.find(searchfor)
                if find_pos >= 0:
                    startpos = idx
                    break

        if self.history:
            result = self.history[startpos]
            if find_pos >= 0:
                result = copy.copy(result)
                result.point = find_pos
        else:
            result = ""
        self.history_cursor = startpos
        self.last_search_for = searchfor
        log("reverse_search_history: old:%d new:%d result:%r" %
            (origpos, self.history_cursor, result))
        return result
Example #56
0
    def test_complete(self):
        import rlcompleter
        logger.sock_silent = False

        log("-" * 50)
        r = EmacsModeTest()
        r.completer = rlcompleter.Completer().complete
        r._bind_key("tab", r.complete)
        r.input(u'"exi(ksdjksjd)"')
        r.input(u'Control-a')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Tab')
        self.assert_line(r, "exit(ksdjksjd)", 4)

        r.input(u'Escape')
        r.input(u'"exi"')
        r.input(u'Control-a')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Right')
        r.input(u'Tab')
        self.assert_line(r, "exit", 4)
Example #57
0
 def size(self):
     log("size()")
     if self.windowSize:
         log("# returned cached value %s" % str(self.windowSize))
         return self.windowSize
     w = self._readIntFromCmd("tput cols")
     h = self._readIntFromCmd("tput lines")
     self.windowSize = (w, h)
     log("size() # = " + str(self.windowSize))
     return (w, h)
Example #58
0
 def debug_output(on, filename='pyreadline_debug_log.txt'):
     if on in ('on', 'on_nologfile'):
         self.debug = True
     if on == 'on':
         logger.start_file_log(filename)
         logger.start_socket_log()
         logger.log('STARTING LOG')
     elif on == 'on_nologfile':
         logger.start_socket_log()
         logger.log('STARTING LOG')
     else:
         logger.log('STOPING LOG')
         logger.stop_file_log()
         logger.stop_socket_log()
Example #59
0
        def debug_output(on, filename=u"pyreadline_debug_log.txt"): #Not implemented yet
            if on in [u"on", u"on_nologfile"]:
                self.debug=True

            if on == "on":
                logger.start_file_log(filename)
                logger.start_socket_log()
                logger.log(u"STARTING LOG")
            elif on == u"on_nologfile":
                logger.start_socket_log()
                logger.log(u"STARTING LOG")
            else:
                logger.log(u"STOPING LOG")
                logger.stop_file_log()
                logger.stop_socket_log()
Example #60
0
 def _process_digit_argument_keyevent(self, keyinfo):
     log('DigitArgumentMode.keyinfo %s' % keyinfo)
     keytuple = keyinfo.tuple()
     log('DigitArgumentMode.keytuple %s %s' % (keyinfo, keytuple))
     if keyinfo.keyname in ('return', ):
         self.prompt = self._digit_argument_oldprompt
         self.process_keyevent_queue = self.process_keyevent_queue[:-1]
         return True
     if keyinfo.keyname:
         pass
     elif keyinfo.char in '0123456789' and keyinfo.control == False and keyinfo.meta == False:
         log('arg %s %s' % (self.argument, keyinfo.char))
         self.argument = self.argument * 10 + int(keyinfo.char)
     else:
         self.prompt = self._digit_argument_oldprompt
         raise LeaveModeTryNext
     self.prompt = '(arg: %s) ' % self.argument