0
|
1 |
# Copyright 2000-2004 Michael Hudson mwh@python.net
|
|
2 |
#
|
|
3 |
# All Rights Reserved
|
|
4 |
#
|
|
5 |
# Portions Copyright (c) 2005 Nokia Corporation
|
|
6 |
#
|
|
7 |
# Permission to use, copy, modify, and distribute this software and
|
|
8 |
# its documentation for any purpose is hereby granted without fee,
|
|
9 |
# provided that the above copyright notice appear in all copies and
|
|
10 |
# that both that copyright notice and this permission notice appear in
|
|
11 |
# supporting documentation.
|
|
12 |
#
|
|
13 |
# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
|
14 |
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
15 |
# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
|
|
16 |
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
|
17 |
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
18 |
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
19 |
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
20 |
|
|
21 |
# (naming modules after builtin functions is not such a hot idea...)
|
|
22 |
|
|
23 |
# an KeyTrans instance translates Event objects into Command objects
|
|
24 |
|
|
25 |
# hmm, at what level do we want [C-i] and [tab] to be equivalent?
|
|
26 |
# [meta-a] and [esc a]? obviously, these are going to be equivalent
|
|
27 |
# for the UnixConsole, but should they be for PygameConsole?
|
|
28 |
|
|
29 |
# it would in any situation seem to be a bad idea to bind, say, [tab]
|
|
30 |
# and [C-i] to *different* things... but should binding one bind the
|
|
31 |
# other?
|
|
32 |
|
|
33 |
# executive, temporary decision: [tab] and [C-i] are distinct, but
|
|
34 |
# [meta-key] is identified with [esc key]. We demand that any console
|
|
35 |
# class does quite a lot towards emulating a unix terminal.
|
|
36 |
|
|
37 |
try:
|
|
38 |
import unicodedata
|
|
39 |
except ImportError:
|
|
40 |
import dumbunicodedata as unicodedata
|
|
41 |
|
|
42 |
class InputTranslator(object):
|
|
43 |
def push(self, evt):
|
|
44 |
pass
|
|
45 |
def get(self):
|
|
46 |
pass
|
|
47 |
def empty(self):
|
|
48 |
pass
|
|
49 |
|
|
50 |
class KeymapTranslator(InputTranslator):
|
|
51 |
def __init__(self, keymap, verbose=0,
|
|
52 |
invalid_cls=None, character_cls=None):
|
|
53 |
self.verbose = verbose
|
|
54 |
from pyrepl.keymap import compile_keymap, parse_keys
|
|
55 |
self.keymap = keymap
|
|
56 |
self.invalid_cls = invalid_cls
|
|
57 |
self.character_cls = character_cls
|
|
58 |
d = {}
|
|
59 |
for keyspec, command in keymap:
|
|
60 |
keyseq = tuple(parse_keys(keyspec))
|
|
61 |
d[keyseq] = command
|
|
62 |
if self.verbose:
|
|
63 |
print d
|
|
64 |
self.k = self.ck = compile_keymap(d, ())
|
|
65 |
self.results = []
|
|
66 |
self.stack = []
|
|
67 |
def push(self, evt):
|
|
68 |
if self.verbose:
|
|
69 |
print "pushed", evt.data,
|
|
70 |
key = evt.data
|
|
71 |
d = self.k.get(key)
|
|
72 |
if isinstance(d, dict):
|
|
73 |
if self.verbose:
|
|
74 |
print "transition"
|
|
75 |
self.stack.append(key)
|
|
76 |
self.k = d
|
|
77 |
else:
|
|
78 |
if d is None:
|
|
79 |
if self.verbose:
|
|
80 |
print "invalid"
|
|
81 |
if self.stack or len(key) > 1 or (unicodedata.category(key) and unicodedata.category(key).startswith('C')):
|
|
82 |
self.results.append(
|
|
83 |
(self.invalid_cls, self.stack + [key]))
|
|
84 |
else:
|
|
85 |
# small optimization:
|
|
86 |
self.k[key] = self.character_cls
|
|
87 |
self.results.append(
|
|
88 |
(self.character_cls, [key]))
|
|
89 |
else:
|
|
90 |
if self.verbose:
|
|
91 |
print "matched", d
|
|
92 |
self.results.append((d, self.stack + [key]))
|
|
93 |
self.stack = []
|
|
94 |
self.k = self.ck
|
|
95 |
def get(self):
|
|
96 |
if self.results:
|
|
97 |
return self.results.pop(0)
|
|
98 |
else:
|
|
99 |
return None
|
|
100 |
def empty(self):
|
|
101 |
return not self.results
|