[pyrepl-checkins] r5471 - in pyrepl/branch/pyrepl-rework-n: . pyrepl pyrepl/dfa test/unit

mwh at codespeak.net mwh at codespeak.net
Wed Jul 7 13:34:18 MEST 2004


Author: mwh
Date: Wed Jul  7 13:34:17 2004
New Revision: 5471

Removed:
   pyrepl/branch/pyrepl-rework-n/pyrepl/.cvsignore
   pyrepl/branch/pyrepl-rework-n/pyrepl/copy_code.py
Modified:
   pyrepl/branch/pyrepl-rework-n/LICENSE
   pyrepl/branch/pyrepl-rework-n/TODO
   pyrepl/branch/pyrepl-rework-n/pyrepl/commands.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/completing_reader.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/console.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/commandsm.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/unicodesm.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/historical_reader.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/keymap.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/keymaps.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/python_reader.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/reader.py
   pyrepl/branch/pyrepl-rework-n/pyrepl/unix_console.py
   pyrepl/branch/pyrepl-rework-n/test/unit/test_commandsm.py
   pyrepl/branch/pyrepl-rework-n/test/unit/test_unicodesm.py
Log:
the result of a couple of days of failing to be productive at maths:

+ all the readers now use the new machinery
+ the old state machine code is removed
+ implement describe-key-briefly (this is cool!)
+ bits and pieces towards vi-mode
+ yet another new way of building the keymaps
+ note some problems in TODO
+ VILE HACK in reader.use_keymap
+ the odd bugfix and cleanup
+ improvements on how unrecognized key sequences are reported



Modified: pyrepl/branch/pyrepl-rework-n/LICENSE
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/LICENSE	(original)
+++ pyrepl/branch/pyrepl-rework-n/LICENSE	Wed Jul  7 13:34:17 2004
@@ -1,4 +1,4 @@
-  Copyright 2000-2002 Michael Hudson mwh at python.net
+  Copyright 2000-2004 Michael Hudson mwh at python.net
 
                        All Rights Reserved
 

Modified: pyrepl/branch/pyrepl-rework-n/TODO
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/TODO	(original)
+++ pyrepl/branch/pyrepl-rework-n/TODO	Wed Jul  7 13:34:17 2004
@@ -1,19 +1,40 @@
-In no particular order:
-+ vi-mode
-+ GUI toolkit friendliness (done for tk)
-+ point-and-mark?
-+ user customization support (maybe even try to read $INPUTRC?)
-+ in general, implement more readline functions (just a matter of 
-  typing, for the most part)
-+ a more incremental way of updating the screen.
-+ unicode support
-+ undo support
-+ port to windows
-
-+ reduce verbosity
-+ tabs
-+ look up delete in terminfo? tcsetattr(self.fd).cc[termios.VERASE]
-+ mention license?
+Rambling about current problems (or problems that were at one point
+current):
 
-+ find a font.  maybe I can bundle andale mono?
+    There are scary suboptimalities in the area of keys known by
+    multiple names (the tab key probably being the winner for having
+    the most names).  Also possibly but not probably relatedly,
+    getting vi insert mode to recognize `escape' as a distinct
+    keystroke and not as a precursor to, say, one of the arrow keys is
+    a pain.
 
+    It may turn out that my neat character-> unicode-> keystroke->
+    command process may not work out as well as I had hoped.  Bugrit.
+
+Things to hack on, in no particular order:
+
+    + vi-mode (this has mostly reached the 'typing' point, too, though
+      'knowing how vi-mode is supposed to work' would be handy)
+
+    + GUI toolkit friendliness (done for tk)
+
+    + point-and-mark?
+
+    + user customization support (maybe even try to read $INPUTRC?)
+
+    + in general, implement more readline functions (just a matter of
+      typing, for the most part)
+
+    + a more incremental way of updating the screen.
+
+    + undo support
+
+    + port to windows
+
+    + reduce verbosity
+
+    + tabs
+
+    + resurrect pygame console
+
+    + integrate with rlcompleter, ipython

Deleted: /pyrepl/branch/pyrepl-rework-n/pyrepl/.cvsignore
==============================================================================
--- /pyrepl/branch/pyrepl-rework-n/pyrepl/.cvsignore	Wed Jul  7 13:34:17 2004
+++ (empty file)
@@ -1 +0,0 @@
-*.pyc

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/commands.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/commands.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/commands.py	Wed Jul  7 13:34:17 2004
@@ -82,7 +82,7 @@
     kills_digit_arg = 0
     def do(self):
         r = self.reader
-        c = self.event[-1]
+        c = self.event[-1].raw
         if c == "-":
             if r.arg is not None:
                 r.arg = -r.arg
@@ -325,7 +325,7 @@
         r = self.reader
         b = r.buffer
         if  ( r.pos == 0 and len(b) == 0 # this is something of a hack
-              and self.event[-1] == "\004"):
+              and self.event[-1].raw == "\004"):
             r.console.finish()
             raise EOFError
         for i in range(r.get_arg()):
@@ -346,9 +346,17 @@
 
 class invalid_key(Command):
     def do(self):
+        from curses.ascii import unctrl
+        mu = self.reader.console.keys.maybe_untranslate
         pending = self.reader.console.getpending()
-        s = ''.join([e.raw for e in self.event]) + pending.raw
-        self.reader.error("`%r' not bound"%s)
+        l = []
+        for e in self.event:
+            n = e.name
+            if len(n) == 1 and ord(n) < 32:
+                n = 'C-' + unctrl(ord(n))[1:].lower()
+            l.append(n)
+        s = ' '.join(l)
+        self.reader.error(u"`%s' not bound"%s)
 
 class invalid_command(Command):
     def do(self):
@@ -358,18 +366,66 @@
 class qIHelp(Command):
     def do(self):
         r = self.reader
-        r.insert((self.event + r.console.getpending().data) * r.get_arg())
+        r.insert((self.event.raw + r.console.getpending().raw) * r.get_arg())
         r.pop_input_trans()
 
-from pyrepl import input
-
 class QITrans(object):
     def push(self, evt):
         self.evt = evt
     def get(self):
-        return ('qIHelp', self.evt.raw)
+        from pyrepl.console import Command
+        return Command('qIHelp', self.evt)
 
 class quoted_insert(Command):
     kills_digit_arg = 0
     def do(self):
         self.reader.push_input_trans(QITrans())
+
+class vi_editing_mode(Command):
+    def do(self):
+        self.reader.use_keymap(self.reader.vi_insert_keymap)
+        self.reader.msg = 'entering vi-edit mode'
+        self.reader.dirty = 1
+
+class vi_command_mode(Command):
+    def do(self):
+        self.reader.use_keymap(self.reader.vi_command_keymap)
+        self.reader.msg = 'entering vi-command mode'
+        self.reader.dirty = 1
+
+class emacs_editing_mode(Command):
+    def do(self):
+        self.reader.use_keymap(self.reader.emacs_keymap)
+        self.reader.msg = 'entering emacs mode'
+        self.reader.dirty = 1
+
+class DKBTrans(object):
+    def __init__(self, wrapped):
+        self.wrapped = wrapped
+    def push(self, evt):
+        self.wrapped.push(evt)
+    def get(self):
+        e = self.wrapped.get()
+        if e is None:
+            return e
+        from pyrepl.console import Command
+        return Command('dkbHelp', e)
+
+class describe_key_briefly(Command):
+    def do(self):
+        self.reader.push_input_trans(DKBTrans(self.reader.input_trans))
+
+class dkbHelp(Command):
+    def do(self):
+        from curses.ascii import unctrl
+        s = []
+        for k in self.event.keystrokes:
+            n = k.name
+            if len(n) == 1 and ord(n) < 32:
+                n = 'C-' + unctrl(ord(n))[1:].lower()
+            s.append(n)
+        
+        self.reader.msg = "`%s' runs the command `%s'"%(' '.join(s),
+                                                       self.event.cmd)
+        self.reader.dirty = 1
+        self.reader.pop_input_trans()

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/completing_reader.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/completing_reader.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/completing_reader.py	Wed Jul  7 13:34:17 2004
@@ -163,10 +163,8 @@
       *
     """
 
-    def collect_keymap(self):
-        return super(CompletingReader, self).collect_keymap() + (
-            (r'\t', 'complete'),)
-    
+    _emacs_keymap = ((r'\<tab>', 'complete'),)
+
     def __init__(self, console):
         super(CompletingReader, self).__init__(console)
         self.cmpltn_menu = ["[ menu 1 ]", "[ menu 2 ]"]
@@ -213,11 +211,13 @@
         return []
 
 def test():
+    from unix_console import UnixConsole
+    words = ['a', 'bb', 'abc']
     class TestReader(CompletingReader):
         def get_completions(self, stem):
-            return [s for l in map(lambda x:x.split(),self.history)
+            return [s for l in map(lambda x:x.split(), words)
                     for s in l if s and s.startswith(stem)]
-    reader = TestReader()
+    reader = TestReader(UnixConsole())
     reader.ps1 = "c**> "
     reader.ps2 = "c/*> "
     reader.ps3 = "c|*> "

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/console.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/console.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/console.py	Wed Jul  7 13:34:17 2004
@@ -46,18 +46,7 @@
         return "%s(%r, %r)"%(self.__class__.__name__,
                              self.cmd, self.keystrokes)
 
-class Event:
-    """An Event.  `evt' is 'key' or somesuch."""
-
-    def __init__(self, evt, data, raw=''):
-        self.evt = evt
-        self.data = data
-        self.raw = raw
-
-    def __repr__(self):
-        return 'Event(%r, %r)'%(self.evt, self.data)
-
-class Console:
+class Console(object):
     """Attributes:
 
     screen,
@@ -86,8 +75,8 @@
         pass
 
     def get_event(self, block=1):
-        """Return an Event instance.  Returns None if |block| is false
-        and there is no event pending, otherwise waits for the
+        """Return an Command instance.  Returns None if |block| is
+        false and there is no event pending, otherwise waits for the
         completion of an event."""
         pass
 

Deleted: /pyrepl/branch/pyrepl-rework-n/pyrepl/copy_code.py
==============================================================================
--- /pyrepl/branch/pyrepl-rework-n/pyrepl/copy_code.py	Wed Jul  7 13:34:17 2004
+++ (empty file)
@@ -1,73 +0,0 @@
-#   Copyright 2000-2004 Michael Hudson mwh at 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.
-
-import new
-
-def copy_code_with_changes(codeobject,
-                           argcount=None,
-                           nlocals=None,
-                           stacksize=None,
-                           flags=None,
-                           code=None,
-                           consts=None,
-                           names=None,
-                           varnames=None,
-                           filename=None,
-                           name=None,
-                           firstlineno=None,
-                           lnotab=None):
-    if argcount    is None: argcount    = codeobject.co_argcount
-    if nlocals     is None: nlocals     = codeobject.co_nlocals
-    if stacksize   is None: stacksize   = codeobject.co_stacksize
-    if flags       is None: flags       = codeobject.co_flags
-    if code        is None: code        = codeobject.co_code
-    if consts      is None: consts      = codeobject.co_consts
-    if names       is None: names       = codeobject.co_names
-    if varnames    is None: varnames    = codeobject.co_varnames
-    if filename    is None: filename    = codeobject.co_filename
-    if name        is None: name        = codeobject.co_name
-    if firstlineno is None: firstlineno = codeobject.co_firstlineno
-    if lnotab      is None: lnotab      = codeobject.co_lnotab
-    return new.code(argcount,
-                    nlocals,
-                    stacksize,
-                    flags,
-                    code,
-                    consts,
-                    names,
-                    varnames,
-                    filename,
-                    name,
-                    firstlineno,
-                    lnotab)
-
-code_attrs=['argcount',
-            'nlocals',
-            'stacksize',
-            'flags',
-            'code',
-            'consts',
-            'names',
-            'varnames',
-            'filename',
-            'name',
-            'firstlineno',
-            'lnotab']
-
-

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/commandsm.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/commandsm.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/commandsm.py	Wed Jul  7 13:34:17 2004
@@ -30,6 +30,8 @@
                 self.output.append(Command(k, self.buf))
                 self.buf = []
                 self.k = self.ck
+            else:
+                self.k = k
         else:
             if (len(self.buf) > 1
                 or len(keystroke.raw) > 1

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/unicodesm.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/unicodesm.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/dfa/unicodesm.py	Wed Jul  7 13:34:17 2004
@@ -52,7 +52,11 @@
         if not self.l:
             c = self.chars
             self.chars = ''
-            self.output.append(c.decode('utf-8'))
+            try:
+                self.output.append(c.decode('utf-8'))
+            except UnicodeError:
+                self.output.append(u'<invalid utf-8 data>')
+                
 
 def unicodesm_for_encoding(encoding):
     if codecs.lookup(encoding) == codecs.lookup('utf-8'):

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/historical_reader.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/historical_reader.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/historical_reader.py	Wed Jul  7 13:34:17 2004
@@ -20,6 +20,8 @@
 from pyrepl import reader, commands
 from pyrepl.reader import Reader as R
 
+from pyrepl.dfa import commandsm 
+
 isearch_keymap = tuple(
     [('\\%03o'%c, 'isearch-end') for c in range(256) if chr(c) != '\\'] + \
     [(c, 'isearch-add-character')
@@ -135,7 +137,7 @@
     def do(self):
         r = self.reader
         b = r.buffer
-        r.isearch_term += self.event[-1]
+        r.isearch_term += self.event[-1].raw
         r.dirty = 1
         p = r.pos + len(r.isearch_term) - 1
         if b[p:p+1] != [r.isearch_term[-1]]:
@@ -186,18 +188,16 @@
         HistoricalReader instance methods.
     """
 
-    def collect_keymap(self):
-        return super(HistoricalReader, self).collect_keymap() + (
-            (r'\C-n', 'next-history'),
-            (r'\C-p', 'previous-history'),
-            (r'\C-o', 'operate-and-get-next'),
-            (r'\C-r', 'reverse-history-isearch'),
-            (r'\C-s', 'forward-history-isearch'),
-            (r'\M-r', 'restore-history'),
-            (r'\M-.', 'yank-arg'),
-            (r'\<page down>', 'last-history'),
-            (r'\<page up>', 'first-history'))
-
+    _emacs_keymap = (
+        (r'\C-n', 'next-history'),
+        (r'\C-p', 'previous-history'),
+        (r'\C-o', 'operate-and-get-next'),
+        (r'\C-r', 'reverse-history-isearch'),
+        (r'\C-s', 'forward-history-isearch'),
+        (r'\M-r', 'restore-history'),
+        (r'\M-.', 'yank-arg'),
+        (r'\<page down>', 'last-history'),
+        (r'\<page up>', 'first-history'))
 
     def __init__(self, console):
         super(HistoricalReader, self).__init__(console)
@@ -214,8 +214,8 @@
                   isearch_forwards, isearch_backwards, operate_and_get_next]:
             self.commands[c.__name__] = c
             self.commands[c.__name__.replace('_', '-')] = c
-        from pyrepl import input
-        self.isearch_trans = input.KeymapTranslator(
+        self.isearch_trans = commandsm.CommandSM(
+            None, self.console.keys,
             isearch_keymap, invalid_cls=isearch_end,
             character_cls=isearch_add_character)
         

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/keymap.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/keymap.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/keymap.py	Wed Jul  7 13:34:17 2004
@@ -120,7 +120,7 @@
                     raise KeySpecError, \
                               "unrecognised keyname `%s' at char %d of %s"%(
                         ret, s + 2, repr(key))
-                #ret = keys.translate(ret)
+                #ret = keys.maybe_untranslate(ret)
                 s = t + 1
             else:
                 raise KeySpecError, \
@@ -133,6 +133,7 @@
         if len(ret) > 1:
             raise KeySpecError, "\\C- must be followed by a character"
         ret = ascii.ctrl(ret)
+    ret = keys.maybe_untranslate(ret)
     if meta:
         ret = ['\033', ret]
     else:

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/keymaps.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/keymaps.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/keymaps.py	Wed Jul  7 13:34:17 2004
@@ -25,12 +25,11 @@
      (r'\C-e', 'end-of-line'),
      (r'\C-f', 'right'),
      (r'\C-g', 'cancel'),
-     (r'\C-h', 'backspace'),
-     (r'\C-j', 'self-insert'),
+     (r'\C-hc', 'describe-key-briefly'),
      (r'\<return>', 'accept'),
      (r'\C-k', 'kill-line'),
      (r'\C-l', 'clear-screen'),
-#     (r'\C-m', 'accept'),
+     (r'\C-m', 'accept'),
      (r'\C-q', 'quoted-insert'),
      (r'\C-t', 'transpose-characters'),
      (r'\C-u', 'unix-line-discard'),
@@ -59,7 +58,7 @@
      (r'\M-7', 'digit-arg'),
      (r'\M-8', 'digit-arg'),
      (r'\M-9', 'digit-arg'),
-     (r'\M-\n', 'self-insert'),
+#     (r'\M-\n', 'insert-nl'),
      (r'\<backslash>', 'self-insert')] + \
     [(c, 'self-insert')
      for c in map(chr, range(32, 127)) if c <> '\\'] + \
@@ -79,6 +78,8 @@
      (r'\EOF', 'end'),  # the entries in the terminfo database for xterms
      (r'\EOH', 'home'), # seem to be wrong.  this is a less than ideal
                         # workaround
+     (r'\M-\<return>', 'vi-editing-mode'),
+     (r'\C-x\C-v',  'vi-editing-mode'),
      ])
 
 hist_emacs_keymap = reader_emacs_keymap + (
@@ -90,7 +91,7 @@
     (r'\M-r', 'restore-history'),
     (r'\M-.', 'yank-arg'),
     (r'\<page down>', 'last-history'),
-    (r'\<page up>', 'first-history'))
+    (r'\<page up>', 'first-history'),)
 
 comp_emacs_keymap = hist_emacs_keymap + (
     (r'\t', 'complete'),)
@@ -98,7 +99,7 @@
 python_emacs_keymap = comp_emacs_keymap + (
     (r'\n', 'maybe-accept'),
     (r'\M-\n', 'self-insert'))
-    
+
 reader_vi_insert_keymap = tuple(
     [(c, 'self-insert')
      for c in map(chr, range(32, 127)) if c <> '\\'] + \
@@ -106,17 +107,20 @@
      for c in map(chr, range(128, 256)) if c.isalpha()] + \
     [(r'\C-d', 'delete'),
      (r'\<backspace>', 'backspace'),
-     ('')])
+     (r'\C-t', 'transpose-characters'),
+     ('\033', 'vi-command-mode'),
+     #(r'\C-\M-j', 'emacs-editing-mode'),
+     ])
 
 reader_vi_command_keymap = tuple(
     [
-    ('E', 'enter-emacs-mode'),
+    ('E', 'end-of-word'),
     ('R', 'enter-replace-mode'),
     ('dw', 'delete-word'),
     ('dd', 'delete-line'),
-    
+    (r'\M-\<return>', 'emacs-editing-mode'),
     ('h', 'left'),
-    ('i', 'enter-insert-mode'),
+    ('i', 'vi-editing-mode'),
     ('j', 'down'),
     ('k', 'up'),
     ('l', 'right'),
@@ -129,12 +133,5 @@
     [(c, 'digit-arg') for c in '01234567689'] +
     [])
    
-
-reader_keymaps = {
-    'emacs' : reader_emacs_keymap,
-    'vi-insert' : reader_vi_insert_keymap,
-    'vi-command' : reader_vi_command_keymap
-    }
-
 del c # from the listcomps
 

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/python_reader.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/python_reader.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/python_reader.py	Wed Jul  7 13:34:17 2004
@@ -21,7 +21,7 @@
 from pyrepl.completing_reader import CompletingReader
 from pyrepl.historical_reader import HistoricalReader
 from pyrepl import completing_reader, reader
-from pyrepl import copy_code, commands, completer
+from pyrepl import commands, completer
 from pyrepl import module_lister
 import new, sys, os, re, code, traceback
 import atexit, warnings
@@ -30,8 +30,6 @@
 except ImportError:
     import pickle
 
-CommandCompiler = code.CommandCompiler
-
 def eat_it(*args):
     """this function eats warnings, if you were wondering"""
     pass
@@ -68,10 +66,12 @@
     return saver
 
 class PythonicReader(CompletingReader, HistoricalReader):
-    def collect_keymap(self):
-        return super(PythonicReader, self).collect_keymap() + (
-            (r'\n', 'maybe-accept'),
-            (r'\M-\n', 'insert-nl'))
+    _emacs_keymap = (
+        (r'\n', 'maybe-accept'),
+        (r'\M-\n', 'insert-nl'))
+    _vi_insert_keymap = (
+        (r'\n', 'maybe-accept'),)
+        
     
     def __init__(self, console, locals,
                  compiler=None):
@@ -82,7 +82,7 @@
             st[c] = reader.SYNTAX_WORD
         self.locals = locals
         if compiler is None:
-            self.compiler = CommandCompiler()
+            self.compiler = code.CommandCompiler()
         else:
             self.compiler = compiler
         try:
@@ -136,7 +136,7 @@
         if locals is None:
             locals = {}
         self.II_init(locals)
-        self.compiler = CommandCompiler()
+        self.compiler = code.CommandCompiler()
         self.compile = self.compiler.compiler
         self.reader = PythonicReader(console, locals, self.compiler)
         locals['Reader'] = self.reader
@@ -309,7 +309,7 @@
                                 signal.default_int_handler)
         self.prepare()
         try:
-            reactor.run()
+            reactor.run(installSignalHandlers=0)
         finally:
             self.restore()
         
@@ -321,7 +321,7 @@
         self.cocoainteracter = CocoaInteracter.alloc().init(self, inputfilehandle, outputfilehandle)
         
         
-def main(use_pygame_console=0, interactmethod="twistedinteract"):
+def main(use_pygame_console=0, interactmethod="interact"):
     si, se, so = sys.stdin, sys.stderr, sys.stdout
     try:
         if 0 and use_pygame_console: # pygame currently borked
@@ -359,7 +359,7 @@
               'for more information.'
         sys.path.insert(0, os.getcwd())
 
-        module_lister._make_module_list()
+        #module_lister._make_module_list()
 
         if __name__ != '__main__':
             mainmod = new.module('__main__')

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/reader.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/reader.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/reader.py	Wed Jul  7 13:34:17 2004
@@ -21,6 +21,7 @@
 from pyrepl import commands
 from curses import ascii
 from pyrepl.dfa import commandsm
+from pyrepl import keymaps
 
 def _make_unctrl_map():
     uc_map = {}
@@ -94,72 +95,6 @@
     st[u'\n'] = st[u' '] = SYNTAX_WHITESPACE
     return st
 
-default_keymap = tuple(
-    [(r'\C-a', 'beginning-of-line'),
-     (r'\C-b', 'left'),
-     (r'\C-c', 'interrupt'),
-     (r'\C-d', 'delete'),
-     (r'\C-e', 'end-of-line'),
-     (r'\C-f', 'right'),
-     (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'),
-     (r'\C-u', 'unix-line-discard'),
-     (r'\C-v', 'quoted-insert'),
-     (r'\C-w', 'unix-word-rubout'),
-     (r'\C-x\C-u', 'upcase-region'),
-     (r'\C-y', 'yank'),
-     (r'\C-z', 'suspend'),
-     
-     (r'\M-b', 'backward-word'),
-     (r'\M-c', 'capitalize-word'),
-     (r'\M-d', 'kill-word'),
-     (r'\M-f', 'forward-word'),
-     (r'\M-l', 'downcase-word'),
-     (r'\M-t', 'transpose-words'),
-     (r'\M-u', 'upcase-word'),
-     (r'\M-y', 'yank-pop'),
-     (r'\M--', 'digit-arg'),
-     (r'\M-0', 'digit-arg'),
-     (r'\M-1', 'digit-arg'),
-     (r'\M-2', 'digit-arg'),
-     (r'\M-3', 'digit-arg'),
-     (r'\M-4', 'digit-arg'),
-     (r'\M-5', 'digit-arg'),
-     (r'\M-6', 'digit-arg'),
-     (r'\M-7', 'digit-arg'),
-     (r'\M-8', 'digit-arg'),
-     (r'\M-9', 'digit-arg'),
-     (r'\M-\n', 'insert-nl'),
-     ('\\\\', 'self-insert')] + \
-    [(c, 'self-insert')
-     for c in map(chr, range(32, 127)) if c <> '\\'] + \
-    [(c, 'self-insert')
-     for c in map(chr, range(128, 256)) if c.isalpha()] + \
-    [(r'\<up>', 'up'),
-     (r'\<down>', 'down'),
-     (r'\<left>', 'left'),
-     (r'\<right>', 'right'),
-     (r'\<insert>', 'quoted-insert'),
-     (r'\<delete>', 'delete'),
-     (r'\<backspace>', 'backspace'),
-     (r'\M-\<backspace>', 'backward-kill-word'),
-     (r'\<end>', 'end'),
-     (r'\<home>', 'home'),
-     (r'\<f1>', 'help'),
-     (r'\EOF', 'end'),  # the entries in the terminfo database for xterms
-     (r'\EOH', 'home'), # seem to be wrong.  this is a less than ideal
-                        # workaround
-     ])
-
-del c # from the listcomps
-
 class Reader(object):
     """The Reader class implements the bare bones of a command reader,
     handling such details as editing and cursor motion.  What it does
@@ -241,14 +176,31 @@
                 self.commands[v.__name__.replace('_', '-')] = v
         self.syntax_table = make_default_syntax_table()
         self.input_trans_stack = []
-        self.keymap = self.collect_keymap()
         self.input_trans = commandsm.CommandSM(
-            None, self.console.keys, self.keymap,
+            None, self.console.keys, self.emacs_keymap,
             invalid_cls='invalid-key',
             character_cls='self-insert')
 
-    def collect_keymap(self):
-        return default_keymap
+
+    def make_keymap_getter(km):
+        attr = '_%s_keymap'%km
+        class KeymapDescr(object):
+            def __get__(self, ob, cls):
+                mro = list(cls.__mro__)
+                mro.reverse()
+                r = ()
+                for c in mro:
+                    r += getattr(c, attr, ())
+                return r
+        return KeymapDescr()
+
+    emacs_keymap = make_keymap_getter('emacs')
+    vi_insert_keymap = make_keymap_getter('vi_insert')
+    vi_command_keymap = make_keymap_getter('vi_command')
+
+    _emacs_keymap = keymaps.reader_emacs_keymap
+    _vi_insert_keymap = keymaps.reader_vi_insert_keymap
+    _vi_command_keymap = keymaps.reader_vi_command_keymap
 
     def calc_screen(self):
         """The purpose of this method is to translate changes in
@@ -472,8 +424,8 @@
         if isinstance(cmd.cmd, str):
             cmd = self.commands.get(cmd.cmd,
                                     commands.invalid_command)(self, (cmd.cmd, cmd.keystrokes))
-        elif isinstance(cmd[0], type):
-            cmd = cmd.cmd(self, cmd)
+        elif isinstance(cmd.cmd, type):
+            cmd = cmd.cmd(self, (cmd.cmd, cmd.keystrokes))
 
         cmd.do()
 
@@ -506,7 +458,7 @@
             if keystroke is None: # can only happen if we're not blocking
                 return None
 
-            if keystroke.name[0] != '<':
+            if keystroke.name[0] != '<<':
                 self.input_trans.push(keystroke)
             elif keystroke.name == '<scroll>':
                 self.refresh()
@@ -543,12 +495,64 @@
         finally:
             self.restore()
 
-    def bind(self, spec, command):
-        self.keymap = self.keymap + ((spec, command),)
+    def use_keymap(self, keymap):
+        assert not self.input_trans_stack
+        self.keymap = keymap
         self.input_trans = commandsm.CommandSM(
             None, self.console.keys, self.keymap,
             invalid_cls='invalid-key',
             character_cls='self-insert')
+        from pyrepl.dfa import keystrokesm
+        if isinstance(self.input_trans.k['\033'], dict):
+            self.console.keystrokesm = keystrokesm.KeystrokeSM(
+                None, self.console.keys)
+        else:
+            class CursesKeys(object):
+                _curses_keynames = {
+                    "delete" : "kdch1",
+                    }
+                _simple_keys = {
+#                    'escape':    '\033',
+                    'return':    '\n',
+                    'space':     ' ',
+                    'tab':       '\t',
+                    'backslash': '\\',
+                    }
+
+                def translate(self, key):
+                    if key in self._curses_keynames:
+                        from curses import tigetstr
+                        return tigetstr(self._curses_keynames[key])
+                    elif key in self._simple_keys:
+                        return self._simple_keys[key]
+                def maybe_untranslate(self, key):
+                    for k, v in self._simple_keys.items():
+                        if v == key:
+                            return k
+                    return key
+                def all_keys(self):
+                    r = []
+                    for k in self.keynames():
+                        v = self.translate(k)
+                        if v is not None:
+                            r.append((v, k))
+                    # XXX ick
+                    from fancy_termios import tcgetattr
+                    import termios
+                    r.append((tcgetattr(0).cc[termios.VERASE], 'backspace'))
+                    return r
+                def keynames(self):
+                    return self._curses_keynames.keys() + self._simple_keys.keys() + ['backspace']
+            self.console.keystrokesm = keystrokesm.KeystrokeSM(
+                None, CursesKeys())
+        self.console.unicodesm.parent = self.console.keystrokesm
+            
+    def bind(self, spec, command):
+        self.emacs_keymap += ((spec, command),)
+        self.input_trans = commandsm.CommandSM(
+            None, self.console.keys, self.emacs_keymap,
+            invalid_cls='invalid-key',
+            character_cls='self-insert')
 
     def get_buffer(self, encoding=None):
         if encoding is None:
@@ -566,6 +570,7 @@
     reader.ps2 = "/*> "
     reader.ps3 = "|*> "
     reader.ps4 = "\*> "
+#    print reader.input_trans.k['\n']
     while reader.readline():
         pass
 

Modified: pyrepl/branch/pyrepl-rework-n/pyrepl/unix_console.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/pyrepl/unix_console.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/pyrepl/unix_console.py	Wed Jul  7 13:34:17 2004
@@ -90,11 +90,11 @@
         "up" : "kcuu1",
         }
     _simple_keys = {
-        'enter':     '\r',
 #        'escape':    '\033',
-        'return':    '\r',
+        'return':    '\n',
         'space':     ' ',
         'tab':       '\t',
+        'backslash': '\\',
         }
         
     def translate(self, key):
@@ -103,6 +103,11 @@
             return tigetstr(self._curses_keynames[key])
         elif key in self._simple_keys:
             return self._simple_keys[key]
+    def maybe_untranslate(self, key):
+        for k, v in self._simple_keys.items():
+            if v == key:
+                return k
+        return key
     def all_keys(self):
         r = []
         for k in self.keynames():
@@ -122,7 +127,7 @@
         if encoding is None:
             encoding = sys.getdefaultencoding()
             
-        self.encoding = encoding
+        self._encoding = encoding
 
         if isinstance(f_in, int):
             self.input_fd = f_in
@@ -143,7 +148,6 @@
         self.keystrokesm = keystrokesm.KeystrokeSM(None, self.keys)
         self.unicodesm.parent = self.keystrokesm
 
-        print self.keystrokesm.k
         
         self._bel   = _my_getstr("bel")
         self._civis = _my_getstr("civis", optional=1)
@@ -205,8 +209,15 @@
 
         self.partial_char = ''
 
+    def get_encoding(self):
+        return self._encoding
+
     def change_encoding(self, encoding):
-        self.encoding = encoding
+        self.unicodesm = unicodesm.unicodesm_for_encoding(encoding)
+        self.unicodesm.parent = self.keystrokesm
+        self._encoding = encoding
+
+    encoding = property(get_encoding, change_encoding)
     
     def refresh(self, screen, (cx, cy)):
         # this function is still too long (over 90 lines)

Modified: pyrepl/branch/pyrepl-rework-n/test/unit/test_commandsm.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/test/unit/test_commandsm.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/test/unit/test_commandsm.py	Wed Jul  7 13:34:17 2004
@@ -9,7 +9,8 @@
         assert v == r
 
 test_keymap = [('a', 'cmd'),
-               ('\C-a', 'bol')]
+               ('\C-a', 'bol'),
+               ('\C-x\C-x', 'swop')]
 
 def test_basic():
     m = CommandSM(None, None, test_keymap, None, None)
@@ -17,5 +18,8 @@
     do_feed(m, [a], [Command('cmd', [a])])
     a = Keystroke('\001', '')
     do_feed(m, [a], [Command('bol', [a])])
+    a = Keystroke('\030', '')
+    do_feed(m, [a], [None])
+    do_feed(m, [a], [Command('swop', [a, a])])
     
 

Modified: pyrepl/branch/pyrepl-rework-n/test/unit/test_unicodesm.py
==============================================================================
--- pyrepl/branch/pyrepl-rework-n/test/unit/test_unicodesm.py	(original)
+++ pyrepl/branch/pyrepl-rework-n/test/unit/test_unicodesm.py	Wed Jul  7 13:34:17 2004
@@ -1,6 +1,6 @@
 
 def run_test_fixedwidthsm(encoding):
-    from pyrepl.statemachine import FixedWidthUnicodeSM
+    from pyrepl.dfa.unicodesm import FixedWidthUnicodeSM
     m = FixedWidthUnicodeSM(None, encoding)
     inpu = u'abc\N{latin small letter i with diaeresis}de'
     inp = inpu.encode(encoding)
@@ -11,7 +11,7 @@
     assert m.get() is None
 
 def test_utf8sm():
-    from pyrepl.statemachine import UTF8UnicodeSM
+    from pyrepl.dfa.unicodesm import UTF8UnicodeSM
     m = UTF8UnicodeSM(None)
     inpu = u'abc\N{latin small letter i with diaeresis}de'
     inp = inpu.encode('utf-8')


More information about the pyrepl-checkins mailing list