[pyrepl-checkins] pyrepl/pyrepl input.py,NONE,1.1 keymap.py,NONE,1.1
unix_eventqueue.py,NONE,1.1 commands.py,1.6,1.7
completing_reader.py,1.4,1.5 console.py,1.3,1.4
historical_reader.py,1.4,1.5 python_reader.py,1.7,1.8
reader.py,1.7,1.8 unix_console.py,1.8,1.9 unix_keymap.py,1.2,NONE
mwh@codespeak.net
mwh@codespeak.net
Fri, 16 May 2003 15:45:11 +0200 (MEST)
- Previous message: [pyrepl-checkins]
pyrepl/pyrepl python_reader.py,1.6,1.7 unix_console.py,1.7,1.8
- Next message: [pyrepl-checkins]
pyrepl/pyrepl historical_reader.py,1.5,1.6 python_reader.py,1.8,1.9
reader.py,1.8,1.9
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/pyrepl/pyrepl/pyrepl
In directory thoth.codespeak.net:/tmp/cvs-serv14466
Modified Files:
commands.py completing_reader.py console.py
historical_reader.py python_reader.py reader.py
unix_console.py
Added Files:
input.py keymap.py unix_eventqueue.py
Removed Files:
unix_keymap.py
Log Message:
Input handling refactoring, as discussed on pyrepl-dev.
Consider this a work-in-progress -- it seems to work, but some things
are probably a little broken.
If you want a detailed explanation of any change feel free to bug me
about it -- I may even be able to remember why I did something!
--- NEW FILE: input.py ---
# (naming modules after builtin functions is not such a hot idea...)
# an KeyTrans instance translates Event objects into Command objects
# hmm, at what level do we want [C-i] and [tab] to be equivalent?
# [meta-a] and [esc a]? obviously, these are going to be equivalent
# for the UnixConsole, but should they be for PygameConsole?
# it would in any situation seem to be a bad idea to bind, say, [tab]
# and [C-i] to *different* things... but should binding one bind the
# other?
# executive, temporary decision: [tab] and [C-i] are distinct, but
# [meta-key] is identified with [esc key]. We demand that any console
# class does quite a lot towards emulating a unix terminal.
class InputTranslator(object):
def push(self, evt):
pass
def get(self):
pass
def empty(self):
pass
class KeymapTranslator(InputTranslator):
def __init__(self, keymap, verbose=0, invalid_cls=None):
self.verbose = verbose
from pyrepl.keymap import compile_keymap, parse_keys
self.keymap = keymap
self.invalid_cls = invalid_cls
d = {}
for keyspec, command in keymap:
keyseq = tuple(parse_keys(keyspec))
d[keyseq] = command
if self.verbose:
print d
self.k = self.ck = compile_keymap(d, ())
self.results = []
self.stack = []
def push(self, evt):
if self.verbose:
print "pushed", evt.data,
key = evt.data
d = self.k.get(key)
if isinstance(d, dict):
if self.verbose:
print "transition"
self.stack.append((key, self.stack + [key]))
self.k = d
else:
if d is None:
if self.verbose:
print "invalid"
self.results.append(
(self.invalid_cls,
self.stack + [key]))
else:
if self.verbose:
print "matched", d
self.results.append((d,
self.stack + [key]))
self.stack = []
self.k = self.ck
def get(self):
if self.results:
return self.results.pop(0)
else:
return None
def empty(self):
return not self.results
--- NEW FILE: keymap.py ---
# Copyright 2000-2003 Michael Hudson mwh@python.net
#
# All Rights Reserved
#
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation.
#
# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
functions for parsing keyspecs
Support for turning keyspecs into appropriate sequences.
pyrepl uses it's own bastardized keyspec format, which is meant to be
a strict superset of readline's \"KEYSEQ\" format (which is to say
that if you can come up with a spec readline accepts that this
doesn't, you've found a bug and should tell me about it).
Note that this is the `\\C-o' style of readline keyspec, not the
`Control-o' sort.
A keyspec is a string representing a sequence of keypresses that can
be bound to a command.
All characters other than the backslash represent themselves. In the
traditional manner, a backslash introduces a escape sequence.
The extension to readline is that the sequence \\<KEY> denotes the
sequence of charaters produced by hitting KEY. This gets a bit messy
because the results of such depend on your terminal. If your terminal's
terminfo entry doesn't describe KEY, trying to parse any keyspec
containing \\<KEY> will return None.
Examples:
`a' - what you get when you hit the `a' key
`\\EOA' - Escape - O - A (up, on my terminal)
`\\<UP>' - the up arrow key
`\\<up>' - ditto (keynames are case insensitive)
`\\C-o', `\\c-o' - control-o
`\\M-.' - meta-period
`\\E.' - ditto (that's how meta works for pyrepl)
`\\<tab>', `\\<TAB>', `\\t', `\\011', '\\x09', '\\X09', '\\C-i', '\\C-I'
- all of these are the tab character. Can you think of any more?
"""
# XXX it's actually possible to test this module, so it should have a
# XXX test suite.
from curses import ascii
_escapes = {
'\\':'\\',
"'":"'",
'"':'"',
'a':'\a',
'b':'\h',
'e':'\033',
'f':'\f',
'n':'\n',
'r':'\r',
't':'\t',
'v':'\v'
}
_keynames = {
'backspace': 'backspace',
'delete': 'delete',
'down': 'down',
'end': 'end',
'enter': '\r',
'escape': '\033',
'f1' : 'f1', 'f2' : 'f2', 'f3' : 'f3', 'f4' : 'f4',
'f5' : 'f5', 'f6' : 'f6', 'f7' : 'f7', 'f8' : 'f8',
'f9' : 'f9', 'f10': 'f10', 'f11': 'f11', 'f12': 'f12',
'f13': 'f13', 'f14': 'f14', 'f15': 'f15', 'f16': 'f16',
'f17': 'f17', 'f18': 'f18', 'f19': 'f19', 'f20': 'f20',
'home': 'home',
'insert': 'insert',
'left': 'left',
'page down': 'page down',
'page up': 'page up',
'return': '\r',
'right': 'right',
'space': ' ',
'tab': '\t',
'up': 'up',
}
class KeySpecError(Exception):
pass
def _parse_key1(key, s):
ctrl = 0
meta = 0
ret = ''
while not ret and s < len(key):
if key[s] == '\\':
c = key[s+1].lower()
if _escapes.has_key(c):
ret = _escapes[c]
s += 2
elif c == "c":
if key[s + 2] != '-':
raise KeySpecError, \
"\\C must be followed by `-' (char %d of %s)"%(
s + 2, repr(key))
if ctrl:
raise KeySpecError, "doubled \\C- (char %d of %s)"%(
s + 1, repr(key))
ctrl = 1
s += 3
elif c == "m":
if key[s + 2] != '-':
raise KeySpecError, \
"\\M must be followed by `-' (char %d of %s)"%(
s + 2, repr(key))
if meta:
raise KeySpecError, "doubled \\M- (char %d of %s)"%(
s + 1, repr(key))
meta = 1
s += 3
elif c.isdigit():
n = key[s+1:s+4]
ret = chr(int(n, 8))
s += 4
elif c == 'x':
n = key[s+2:s+4]
ret = chr(int(n, 16))
s += 4
elif c == '<':
t = key.find('>', s)
if t == -1:
raise KeySpecError, \
"unterminated \\< starting at char %d of %s"%(
s + 1, repr(key))
ret = key[s+2:t].lower()
if ret not in _keynames:
raise KeySpecError, \
"unrecognised keyname `%s' at char %d of %s"%(
ret, s + 2, repr(key))
ret = _keynames[ret]
s = t + 1
else:
raise KeySpecError, \
"unknown backslash escape %s at char %d of %s"%(
`c`, s + 2, repr(key))
else:
ret = key[s]
s += 1
if ctrl:
if len(ret) > 2:
raise KeySpecError, "\\C- must be followed by a character"
ret = ascii.ctrl(ret)
if meta:
ret = ['\033', ret]
else:
ret = [ret]
return ret, s
def parse_keys(key):
s = 0
r = []
while s < len(key):
k, s = _parse_key1(key, s)
r.extend(k)
return r
def compile_keymap(keymap, empty=''):
r = {}
for key, value in keymap.items():
r.setdefault(key[0], {})[key[1:]] = value
for key, value in r.items():
if empty in value:
if len(value) <> 1:
raise KeySpecError, \
"key definitions for %s clash"%(value.values(),)
else:
r[key] = value[empty]
else:
r[key] = compile_keymap(value, empty)
return r
--- NEW FILE: unix_eventqueue.py ---
# Bah, this would be easier to test if curses/terminfo didn't have so
# much non-introspectable global state.
from pyrepl import keymap
from pyrepl.console import Event
import curses, termios
_keynames = {
"delete" : "kdch1",
"down" : "kcud1",
"end" : "kend",
"enter" : "kent",
"f1" : "kf1", "f2" : "kf2", "f3" : "kf3", "f4" : "kf4",
"f5" : "kf5", "f6" : "kf6", "f7" : "kf7", "f8" : "kf8",
"f9" : "kf9", "f10" : "kf10", "f11" : "kf11", "f12" : "kf12",
"f13" : "kf13", "f14" : "kf14", "f15" : "kf15", "f16" : "kf16",
"f17" : "kf17", "f18" : "kf18", "f19" : "kf19", "f20" : "kf20",
"home" : "khome",
"insert" : "kich1",
"left" : "kcub1",
"page down" : "knp",
"page up" : "kpp",
"right" : "kcuf1",
"up" : "kcuu1",
}
class EventQueue(object):
def __init__(self, fd):
our_keycodes = {}
for key, tiname in _keynames.items():
keycode = curses.tigetstr(tiname)
if keycode:
our_keycodes[keycode] = unicode(key)
our_keycodes[termios.tcgetattr(fd)[6][termios.VERASE]] = \
u'backspace'
self.k = self.ck = keymap.compile_keymap(our_keycodes)
self.events = []
self.buf = []
def get(self):
if self.events:
return self.events.pop(0)
else:
return None
def empty(self):
return not self.events
def insert(self, event):
self.events.append(event)
def push(self, char):
if char in self.k:
k = self.k[char]
if isinstance(k, dict):
self.buf.append(char)
self.k = k
else:
self.events.append(Event('key', k))
self.buf = []
self.k = self.ck
elif self.buf:
self.events.extend([Event('key', c) for c in self.buf])
self.buf = []
self.k = self.ck
self.push(char)
else:
self.events.append(Event('key', char))
Index: commands.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/commands.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** commands.py 16 May 2003 13:18:00 -0000 1.6
--- commands.py 16 May 2003 13:45:09 -0000 1.7
***************
*** 30,34 ****
# [completion]
! class Command:
finish = 0
kills_digit_arg = 1
--- 30,34 ----
# [completion]
! class Command(object):
finish = 0
kills_digit_arg = 1
***************
*** 82,86 ****
def do(self):
r = self.reader
! c = self.event.chars[-1]
if c == "-":
if r.arg is not None:
--- 82,86 ----
def do(self):
r = self.reader
! c = self.event[-1]
if c == "-":
if r.arg is not None:
***************
*** 284,288 ****
def do(self):
r = self.reader
! r.insert(self.event.chars * r.get_arg())
class insert_nl(EditCommand):
--- 284,288 ----
def do(self):
r = self.reader
! r.insert(self.event * r.get_arg())
class insert_nl(EditCommand):
***************
*** 325,329 ****
b = r.buffer
if ( r.pos == 0 and len(b) == 0 # this is something of a hack
! and self.event.chars[-1] == "\004"):
r.console.finish()
raise EOFError
--- 325,329 ----
b = r.buffer
if ( r.pos == 0 and len(b) == 0 # this is something of a hack
! and self.event[-1] == "\004"):
r.console.finish()
raise EOFError
***************
*** 339,368 ****
pass
! class qIHelp(Command):
! def do(self):
! r = self.reader
! r.insert((self.event.chars + r.console.getpending()) * r.get_arg())
! self.reader.install_keymap()
!
! class DefaultDict:
! def __contains__(self, whatever):
! return True
! def __getitem__(self, whatever):
! return 'qIHelp'
!
! class quoted_insert(Command):
! kills_digit_arg = 0
def do(self):
! self.reader.console.k = self.reader.console.keymap = DefaultDict()
class invalid_key(Command):
def do(self):
! s = self.reader.console.describe_event(self.event)
self.reader.error("`%s' not bound"%s)
! class help(Command):
def do(self):
! self.reader.msg = self.reader.help_text
! self.reader.dirty = 1
--- 339,369 ----
pass
! class help(Command):
def do(self):
! self.reader.msg = self.reader.help_text
! self.reader.dirty = 1
class invalid_key(Command):
def do(self):
! s = self.event
self.reader.error("`%s' not bound"%s)
! class qIHelp(Command):
def do(self):
! r = self.reader
! #r.insert((self.event + r.console.getpending()) * r.get_arg())
! r.insert((self.event ) * r.get_arg())
! r.pop_input_trans()
+ from pyrepl import input
+ class QITrans(object):
+ def push(self, evt):
+ self.chars = evt.data
+ def get(self):
+ return ('qIHelp', self.chars)
+
+ class quoted_insert(Command):
+ kills_digit_arg = 0
+ def do(self):
+ self.reader.push_input_trans(QITrans())
Index: completing_reader.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/completing_reader.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** completing_reader.py 16 May 2003 13:18:01 -0000 1.4
--- completing_reader.py 16 May 2003 13:45:09 -0000 1.5
***************
*** 179,185 ****
self.commands[c.__name__.replace('_', '-')] = c
- def install_keymap(self):
- self.console.install_keymap(self.keymap)
-
HR_after_command = HR.after_command
def after_command(self, cmd):
--- 179,182 ----
Index: console.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/console.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** console.py 4 Feb 2003 18:46:35 -0000 1.3
--- console.py 16 May 2003 13:45:09 -0000 1.4
***************
*** 19,44 ****
class Event:
! """An Event. Attributes include:
! * name:
! the assigned name for this event (e.g. 'self-insert' or
! 'prefix-arg')
! * chars:
! a string containing the characters read leading up to this
! event (e.g. 'a' or '\\x1b0').
! * _con_desc:
! a console specific description of what caused this event
! (used for producing 'M-foo not bound' messages)."""
! def __init__(self, name, chars='', con_desc=None):
! self.name = name
! self.chars = chars
! self._con_desc = con_desc
class Console:
"""Attributes:
- (keymap),
- (fd),
screen,
height,
--- 19,34 ----
class Event:
! """An Event. `evt' is 'key' or somesuch."""
! def __init__(self, evt, data):
! self.evt = evt
! self.data = data
! def __repr__(self):
! return 'Event(%r, %r)'%(self.evt, self.data)
class Console:
"""Attributes:
screen,
height,
***************
*** 46,63 ****
"""
- def install_keymap(self, keymap):
- """Install a given keymap.
-
- keymap is a tuple of 2-element tuples; each small tuple is a
- pair (keyspec, event-name). The format for keyspec is
- modelled on that used by readline (so read that manual for
- now!)."""
- pass
-
- def describe_event(self, event):
- """Return a description of an event, suitable for error messages.
-
- This method should..."""
-
def refresh(self, screen, xy):
pass
--- 36,39 ----
***************
*** 100,104 ****
def flushoutput(self):
"""Flush all output to the screen (assuming there's some
! buffering going on somewhere)"""
pass
--- 76,80 ----
def flushoutput(self):
"""Flush all output to the screen (assuming there's some
! buffering going on somewhere)."""
pass
Index: historical_reader.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/historical_reader.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** historical_reader.py 16 May 2003 13:18:01 -0000 1.4
--- historical_reader.py 16 May 2003 13:45:09 -0000 1.5
***************
*** 120,124 ****
r.isearch_term = ''
r.dirty = 1
! r.console.install_keymap(isearch_keymap)
--- 120,124 ----
r.isearch_term = ''
r.dirty = 1
! r.push_input_trans(r.isearch_trans)
***************
*** 129,133 ****
r.dirty = 1
r.isearch_term = ''
! r.console.install_keymap(isearch_keymap)
r.isearch_start = r.historyi, r.pos
--- 129,133 ----
r.dirty = 1
r.isearch_term = ''
! r.push_input_trans(r.isearch_trans)
r.isearch_start = r.historyi, r.pos
***************
*** 136,140 ****
r = self.reader
r.isearch_direction = ISEARCH_DIRECTION_NONE
! r.install_keymap()
r.select_item(r.isearch_start[0])
r.pos = r.isearch_start[1]
--- 136,140 ----
r = self.reader
r.isearch_direction = ISEARCH_DIRECTION_NONE
! r.pop_input_trans()
r.select_item(r.isearch_start[0])
r.pos = r.isearch_start[1]
***************
*** 145,149 ****
r = self.reader
b = r.buffer
! r.isearch_term += self.event.chars[-1]
r.dirty = 1
p = r.pos + len(r.isearch_term) - 1
--- 145,149 ----
r = self.reader
b = r.buffer
! r.isearch_term += self.event[-1]
r.dirty = 1
p = r.pos + len(r.isearch_term) - 1
***************
*** 177,181 ****
r.isearch_direction = ISEARCH_DIRECTION_NONE
r.console.forgetinput()
! r.install_keymap()
r.dirty = 1
--- 177,181 ----
r.isearch_direction = ISEARCH_DIRECTION_NONE
r.console.forgetinput()
! r.pop_input_trans()
r.dirty = 1
***************
*** 214,221 ****
self.commands[c.__name__] = c
self.commands[c.__name__.replace('_', '-')] = c
- def install_keymap(self):
- self.console.install_keymap(history_keymap)
-
def select_item(self, i):
self.transient_history[self.historyi] = self.get_buffer()
--- 214,221 ----
self.commands[c.__name__] = c
self.commands[c.__name__.replace('_', '-')] = c
+ from pyrepl import input
+ self.isearch_trans = input.KeymapTranslator(
+ isearch_keymap, invalid_cls=isearch_end)
def select_item(self, i):
self.transient_history[self.historyi] = self.get_buffer()
***************
*** 301,305 ****
def test():
from pyrepl.unix_console import UnixConsole
! reader = HistoricalReader(UnixConsole(1, None))
reader.ps1 = "h**> "
reader.ps2 = "h/*> "
--- 301,305 ----
def test():
from pyrepl.unix_console import UnixConsole
! reader = HistoricalReader(UnixConsole())
reader.ps1 = "h**> "
reader.ps2 = "h/*> "
Index: python_reader.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/python_reader.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** python_reader.py 16 May 2003 13:31:48 -0000 1.7
--- python_reader.py 16 May 2003 13:45:09 -0000 1.8
***************
*** 118,124 ****
self.commands[c.__name__.replace('_', '-')] = c
- def install_keymap(self):
- self.console.install_keymap(self.keymap)
-
def get_completions(self, stem):
b = self.get_buffer()
--- 118,121 ----
***************
*** 171,175 ****
execfile(initfile, self.locals, self.locals)
except:
! traceback.print_exc()
def execute(self, text):
--- 168,173 ----
execfile(initfile, self.locals, self.locals)
except:
! traceback.print_exception(sys.exc_type, sys.exc_value,
! sys.exc_traceback.tb_next)
def execute(self, text):
***************
*** 335,345 ****
con = UnixConsole(0, 1, None, encoding)
print "Python", sys.version, "on", sys.platform
! print 'Type "copyright", "credits" or "license" for more information.'
sys.path.insert(0, os.getcwd())
module_lister._make_module_list()
! mainmod = new.module('__main__')
! sys.modules['__main__'] = mainmod
rc = ReaderConsole(con, mainmod.__dict__)
--- 333,347 ----
con = UnixConsole(0, 1, None, encoding)
print "Python", sys.version, "on", sys.platform
! print 'Type "help", "copyright", "credits" or "license" '\
! 'for more information.'
sys.path.insert(0, os.getcwd())
module_lister._make_module_list()
! if __name__ != '__main__':
! mainmod = new.module('__main__')
! sys.modules['__main__'] = mainmod
! else:
! mainmod = sys.modules['__main__']
rc = ReaderConsole(con, mainmod.__dict__)
Index: reader.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/reader.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** reader.py 16 May 2003 13:18:01 -0000 1.7
--- reader.py 16 May 2003 13:45:09 -0000 1.8
***************
*** 21,24 ****
--- 21,25 ----
from pyrepl import commands
from curses import ascii
+ from pyrepl import input
def _make_unctrl_map():
***************
*** 103,111 ****
(r'\C-g', 'cancel'),
(r'\C-h', 'backspace'),
! (r'\C-j', 'self-insert'),
(r'\<return>', 'accept'),
(r'\C-k', 'kill-line'),
(r'\C-l', 'clear-screen'),
! # (r'\C-m', 'accept'),
(r'\C-q', 'quoted-insert'),
(r'\C-t', 'transpose-characters'),
--- 104,112 ----
(r'\C-g', 'cancel'),
(r'\C-h', 'backspace'),
! (r'\C-j', 'accept'),
(r'\<return>', 'accept'),
(r'\C-k', 'kill-line'),
(r'\C-l', 'clear-screen'),
! (r'\C-m', 'accept'),
(r'\C-q', 'quoted-insert'),
(r'\C-t', 'transpose-characters'),
***************
*** 233,241 ****
self.finished = 0
self.console = console
- self.install_keymap()
self.commands = {}
self.msg = ''
for v in vars(commands).values():
! if ( isinstance(v, types.ClassType)
and issubclass(v, commands.Command)
and v.__name__[0].islower() ):
--- 234,241 ----
self.finished = 0
self.console = console
self.commands = {}
self.msg = ''
for v in vars(commands).values():
! if ( isinstance(v, type)
and issubclass(v, commands.Command)
and v.__name__[0].islower() ):
***************
*** 243,246 ****
--- 243,249 ----
self.commands[v.__name__.replace('_', '-')] = v
self.syntax_table = make_default_syntax_table()
+ self.input_trans_stack = []
+ self.input_trans = input.KeymapTranslator(
+ self.keymap, invalid_cls='invalid-key')
def calc_screen(self):
***************
*** 282,286 ****
self.cxy = self.pos2xy(self.pos)
return screen
!
def bow(self, p=None):
"""Return the 0-based index of the word break preceding p most
--- 285,289 ----
self.cxy = self.pos2xy(self.pos)
return screen
!
def bow(self, p=None):
"""Return the 0-based index of the word break preceding p most
***************
*** 366,375 ****
return self._ps1
! def install_keymap(self):
! self.console.install_keymap(default_keymap)
def pos2xy(self, pos):
"""Return the x, y coordinates of position 'pos'."""
! # this is incomprehensible, yes.
y = 0
assert 0 <= pos <= len(self.buffer)
--- 369,382 ----
return self._ps1
! def push_input_trans(self, itrans):
! self.input_trans_stack.append(self.input_trans)
! self.input_trans = itrans
!
! def pop_input_trans(self):
! self.input_trans = self.input_trans_stack.pop()
def pos2xy(self, pos):
"""Return the x, y coordinates of position 'pos'."""
! # this *is* incomprehensible, yes.
y = 0
assert 0 <= pos <= len(self.buffer)
***************
*** 457,481 ****
self.dirty = 0 # forgot this for a while (blush)
! def handle1(self, block=1):
! """Handle a single event. Wait as long as it takes if block
! is true (the default), otherwise return None if no event is
! pending."""
!
! if self.msg:
! self.msg = ''
! self.dirty = 1
!
! event = self.console.get_event(block)
! if not event: # can only happen if we're not blocking
! return
! try:
! cmd_class = self.commands[event.name]
! except KeyError:
! self.msg = " %s not written yet"%(event.name,)
! self.refresh()
! self.console.beep()
! return
! cmd = cmd_class(self, event)
!
cmd.do()
--- 464,474 ----
self.dirty = 0 # forgot this for a while (blush)
! def do_cmd(self, cmd):
! #print cmd
! if isinstance(cmd[0], str):
! cmd = self.commands[cmd[0]](self, cmd[1])
! elif isinstance(cmd[0], type):
! cmd = cmd[0](self, cmd[1])
!
cmd.do()
***************
*** 483,502 ****
if self.dirty:
! if 0:
! from profile import Profile
! import sys
! p = Profile()
! p.runcall(self.refresh)
! so = sys.stdout
! sys.stdout = open("/dev/pts/2", "w")
! p.print_stats()
! sys.stdout = so
! else:
! self.refresh()
else:
self.update_cursor()
if not isinstance(cmd, commands.digit_arg):
! self.last_command = cmd_class
self.finished = cmd.finish
--- 476,485 ----
if self.dirty:
! self.refresh()
else:
self.update_cursor()
if not isinstance(cmd, commands.digit_arg):
! self.last_command = cmd.__class__
self.finished = cmd.finish
***************
*** 505,508 ****
--- 488,525 ----
self.finish()
+ def handle1(self, block=1):
+ """Handle a single event. Wait as long as it takes if block
+ is true (the default), otherwise return None if no event is
+ pending."""
+
+ if self.msg:
+ self.msg = ''
+ self.dirty = 1
+
+ while 1:
+ event = self.console.get_event(block)
+ if not event: # can only happen if we're not blocking
+ return
+
+ if event.evt == 'key':
+ self.input_trans.push(event)
+ elif event.evt == 'scroll':
+ self.refresh()
+ elif event.evt == 'resize':
+ self.refresh()
+ else:
+ pass
+
+ cmd = self.input_trans.get()
+
+ if cmd is None:
+ if block:
+ continue
+ else:
+ return
+
+ self.do_cmd(cmd)
+ return
+
def readline(self):
"""Read a line. The implementation of this method also shows
***************
*** 519,524 ****
def bind(self, spec, command):
! self.keymap += ((spec, command),)
! self.install_keymap()
def get_buffer(self):
--- 536,550 ----
def bind(self, spec, command):
! self.keymap = self.keymap + ((spec, command),)
! self.input_trans = input.KeymapTranslator(self.keymap)
!
! def get_buffer(self, encoding=None):
! if encoding is None:
! encoding = self.console.encoding
! return u''.join(self.buffer).encode(self.console.encoding)
!
! def get_unicode(self):
! """Return the current buffer as a unicode string."""
! return u''.join(self.buffer)
def get_buffer(self):
Index: unix_console.py
===================================================================
RCS file: /cvs/pyrepl/pyrepl/pyrepl/unix_console.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** unix_console.py 16 May 2003 13:31:48 -0000 1.8
--- unix_console.py 16 May 2003 13:45:09 -0000 1.9
***************
*** 18,27 ****
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! import termios, curses, select, os, struct, types, errno, signal
! import re, time, sys, codecs, unicodedata
from fcntl import ioctl
from pyrepl.fancy_termios import tcgetattr, tcsetattr
from pyrepl.console import Console, Event
! from pyrepl import unix_keymap
# there are arguments for changing this to "refresh"
--- 18,27 ----
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! import termios, curses, select, os, struct, types, errno
! import signal, re, time, sys, codecs, unicodedata
from fcntl import ioctl
from pyrepl.fancy_termios import tcgetattr, tcsetattr
from pyrepl.console import Console, Event
! from pyrepl import unix_eventqueue
# there are arguments for changing this to "refresh"
***************
*** 31,39 ****
TIOCGWINSZ = getattr(termios, "TIOCGWINSZ", None)
- if sys.version[:3] == '2.1' and sys.platform == 'linux2':
- # 2.1's termios module was bust wrt. *lots* of constants...
- TIOCGWINSZ = getattr(termios, "TIOCGWINSZ", 0x5413)
- FIONREAD = getattr(termios, "FIONREAD", 0x541B)
-
def _my_getstr(cap, optional=0):
r = curses.tigetstr(cap)
--- 31,34 ----
***************
*** 43,66 ****
return r
- _keynames = {
- # "backspace" : "kbs", # dig this out of tcgetattr instead
- "delete" : "kdch1",
- "down" : "kcud1",
- "end" : "kend",
- "enter" : "kent",
- "f1" : "kf1", "f2" : "kf2", "f3" : "kf3", "f4" : "kf4",
- "f5" : "kf5", "f6" : "kf6", "f7" : "kf7", "f8" : "kf8",
- "f9" : "kf9", "f10" : "kf10", "f11" : "kf11", "f12" : "kf12",
- "f13" : "kf13", "f14" : "kf14", "f15" : "kf15", "f16" : "kf16",
- "f17" : "kf17", "f18" : "kf18", "f19" : "kf19", "f20" : "kf20",
- "home" : "khome",
- "insert" : "kich1",
- "left" : "kcub1",
- "pgdown" : "knp", "page down" : "knp",
- "pgup" : "kpp", "page up" : "kpp",
- "right" : "kcuf1",
- "up" : "kcuu1",
- }
-
_keysets = {}
--- 38,41 ----
***************
*** 195,199 ****
self.__move = self.__move_short
! self.keymap = {}
def change_encoding(self, encoding):
--- 170,174 ----
self.__move = self.__move_short
! self.event_queue = unix_eventqueue.EventQueue(self.input_fd)
def change_encoding(self, encoding):
***************
*** 201,211 ****
self.encoding = encoding
- def install_keymap(self, new_keymap):
- self.k = self.keymap = \
- unix_keymap.compile_keymap(new_keymap, keyset(self))
-
- def describe_event(self, event):
- return unix_keymap.unparse_keyf(event.chars, keyset(self))
-
def refresh(self, screen, (cx, cy)):
# this function is still too long (over 90 lines)
--- 176,179 ----
***************
*** 382,386 ****
def move_cursor(self, x, y):
if y < self.__offset or y >= self.__offset + self.height:
! self.__event_queue.append(Event('refresh', '', ''))
else:
self.__move(x, y)
--- 350,354 ----
def move_cursor(self, x, y):
if y < self.__offset or y >= self.__offset + self.height:
! self.event_queue.insert(Event('scroll', None))
else:
self.__move(x, y)
***************
*** 417,425 ****
self.old_sigwinch = signal.signal(
signal.SIGWINCH, self.__sigwinch)
- self.__event_queue = []
-
- # per-event preparations:
- self.__cmd_buf = ''
- self.k = self.keymap
def restore(self):
--- 385,388 ----
***************
*** 432,473 ****
def __sigwinch(self, signum, frame):
self.height, self.width = self.getheightwidth()
! self.__event_queue.append(Event(SIGWINCH_EVENT, '', ''))
def get_event(self, block=1):
! if self.__event_queue:
! return self.__event_queue.pop(0)
! while 1:
! if block or self.pollob.poll(0):
! while 1: # All hail Unix!
! try:
! c = self.input.read(1)
! except IOError, err:
! if err.errno == errno.EINTR:
! if self.__event_queue:
! return self.__event_queue.pop(0)
! else:
! continue # be explicit
else:
! raise
! else:
! break
! self.__cmd_buf += c
! if c not in self.k:
! for c2 in self.__cmd_buf:
! if unicodedata.category(c2).startswith('C'):
! self.__cmd_buf += self.getpending()
! k = "invalid-key"
! break
else:
! k = "self-insert"
else:
! k = self.k = self.k[c]
! if not isinstance(k, dict):
! e = Event(k, self.__cmd_buf, self.__cmd_buf)
! self.k = self.keymap
! self.__cmd_buf = ''
! return e
if not block:
! return None
def wait(self):
--- 395,419 ----
def __sigwinch(self, signum, frame):
self.height, self.width = self.getheightwidth()
! self.event_queue.insert(Event('resize', None))
def get_event(self, block=1):
! while self.event_queue.empty():
! while 1: # All hail Unix!
! try:
! c = self.input.read(1)
! except IOError, err:
! if err.errno == errno.EINTR:
! if not self.event_queue.empty():
! return self.event_queue.get()
else:
! continue # be explicit
else:
! raise
else:
! break
! self.event_queue.push(c)
if not block:
! break
! return self.event_queue.get()
def wait(self):
***************
*** 560,563 ****
--- 506,510 ----
if FIONREAD:
def getpending(self):
+ return self.input.read()
amount = struct.unpack(
"i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0]
***************
*** 573,574 ****
--- 520,522 ----
self.__posxy = 0, 0
self.screen = []
+
--- unix_keymap.py DELETED ---
- Previous message: [pyrepl-checkins]
pyrepl/pyrepl python_reader.py,1.6,1.7 unix_console.py,1.7,1.8
- Next message: [pyrepl-checkins]
pyrepl/pyrepl historical_reader.py,1.5,1.6 python_reader.py,1.8,1.9
reader.py,1.8,1.9
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]