about summary refs log tree commit diff stats
path: root/html/console.mu.html
blob: 97304cc9627bc317690c1009d23082e31e17bafa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - console.mu</title>
<meta name="Generator" content="Vim/8.0">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="none">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #aaaaaa; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #aaaaaa; background-color: #080808; }
a { color:#eeeeee; text-decoration: none; }
a:hover { text-decoration: underline; }
* { font-size: 12pt; font-size: 1em; }
.Conceal { color: #4e4e4e; }
.LineNr { color: #444444; }
.Delimiter { color: #800080; }
.Comment { color: #9090ff; }
.Comment a { color:#0000ee; text-decoration:underline; }
.Constant { color: #00a0a0; }
.Special { color: #c00000; }
.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-->
</style>

<script type='text/javascript'>
<!--

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="Comment"># example program: reading events from keyboard or mouse</span>
<span id="L2" class="LineNr"> 2 </span><span class="Comment">#</span>
<span id="L3" class="LineNr"> 3 </span><span class="Comment"># Keeps printing 'a' until you press a key or click on the mouse.</span>
<span id="L4" class="LineNr"> 4 </span>
<span id="L5" class="LineNr"> 5 </span><span class="muRecipe">def</span> <a href='console.mu.html#L5'>main</a> [
<span id="L6" class="LineNr"> 6 </span>  <span class="Constant">local-scope</span>
<span id="L7" class="LineNr"> 7 </span>  open-console
<span id="L8" class="LineNr"> 8 </span>  <span class="Delimiter">{</span>
<span id="L9" class="LineNr"> 9 </span>  <span class="Conceal">¦</span> e:<a href='084console.mu.html#L4'>event</a>, found?:bool <span class="Special">&lt;-</span> check-for-interaction
<span id="L10" class="LineNr">10 </span>  <span class="Conceal">¦</span> <span class="muControl">break-if</span> found?
<span id="L11" class="LineNr">11 </span>  <span class="Conceal">¦</span> print-character-to-display<span class="Constant"> 97</span>, <span class="Constant">7/white</span>
<span id="L12" class="LineNr">12 </span>  <span class="Conceal">¦</span><span class="muControl"> loop</span>
<span id="L13" class="LineNr">13 </span>  <span class="Delimiter">}</span>
<span id="L14" class="LineNr">14 </span>  close-console
<span id="L15" class="LineNr">15 </span>  $print e, <span class="Constant">10/newline</span>
<span id="L16" class="LineNr">16 </span>]
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->
clear() simulate_press(kb, keys) self.assertTrue(kb.failure, "Keypress did not fail as expected") kb.clear() def assertPressIncomplete(self, kb, keys): kb.clear() simulate_press(kb, keys) self.assertFalse(kb.failure, "Keypress failed, expected incomplete") self.assertFalse(kb.done, "Keypress done which was unexpected") kb.clear() class Test(PressTestCase): """The test cases""" def test_passive_action(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) def n(value): """return n or value""" def fnc(arg=None): if arg is None or arg.n is None: return value return arg.n return fnc km.map('ppp', n(5)) km.map('pp<bg>', n(8)) km.map('pp<dir>', n(2)) directions.map('j', dir=Direction(down=1)) press = self._mkpress(kb, km) self.assertEqual(5, press('ppp')) self.assertEqual(3, press('3ppp')) self.assertEqual(2, press('ppj')) kb.clear() match = simulate_press(kb, 'pp') args = CommandArgs(0, 0, kb) self.assert_(match) self.assert_(match.function) self.assertEqual(8, match.function(args)) def test_translate_keys(self): def test(string, *args): if not args: args = (string, ) self.assertEqual(ordtuple(*args), tuple(parse_keybinding(string))) def ordtuple(*args): lst = [] for arg in args: if isinstance(arg, str): lst.extend(ord(c) for c in arg) else: lst.append(arg) return tuple(lst) # 1 argument means: assume nothing is translated. test('k') test('kj') test('k<dir>', 'k', DIRKEY) test('k<ANY>z<any>', 'k', ANYKEY, 'z', ANYKEY) test('k<anY>z<dir>', 'k', ANYKEY, 'z', DIRKEY) test('<cr>', "\n") test('<tab><tab><cr>', "\t\t\n") test('<') test('>') test('<C-a>', 1) test('<C-b>', 2) for i in range(1, 26): test('<C-' + chr(i+ord('a')-1) + '>', i) test('<A-x>', 27, ord('x')) test('<a-o>', 27, ord('o')) test('k<a') test('k<anz>') test('k<a<nz>') test('k<a<nz>') test('k<a<>nz>') test('>nz>') def test_alias(self): def add_dirs(arg): return sum(dir.down() for dir in arg.directions) def return5(_): return 5 directions = KeyMap() directions.map('j', dir=Direction(down=1)) directions.map('k', dir=Direction(down=-1)) directions.map('<CR>', alias='j') directions.map('@', alias='<CR>') base = KeyMap() base.map('a<dir>', add_dirs) base.map('b<dir>', add_dirs) base.map('x<dir>x<dir>', add_dirs) base.map('f', return5) base.map('yy', alias='y') base.map('!', alias='!') other = KeyMap() other.map('b<dir>b<dir>', alias='x<dir>x<dir>') other.map('c<dir>', add_dirs) other.map('g', alias='f') km = base.merge(other, copy=True) kb = KeyBuffer(km, directions) press = self._mkpress(kb, km) self.assertEqual(1, press('aj')) self.assertEqual(2, press('bjbj')) self.assertEqual(1, press('cj')) self.assertEqual(1, press('c<CR>')) self.assertEqual(5, press('f')) self.assertEqual(5, press('g')) self.assertEqual(press('c<CR>'), press('c@')) self.assertEqual(press('c<CR>'), press('c@')) self.assertEqual(press('c<CR>'), press('c@')) for n in range(1, 10): self.assertPressIncomplete(kb, 'y' * n) for n in range(1, 5): self.assertPressFails(kb, '!' * n) def test_tree(self): t = Tree() t.set('abcd', "Yes") self.assertEqual("Yes", t.traverse('abcd')) self.assertRaises(KeyError, t.traverse, 'abcde') self.assertRaises(KeyError, t.traverse, 'xyz') self.assert_(isinstance(t.traverse('abc'), Tree)) t2 = Tree() self.assertRaises(KeyError, t2.set, 'axy', "Lol", force=False) t2.set('axx', 'ololol') t2.set('axyy', "Lol") self.assertEqual("Yes", t.traverse('abcd')) self.assertRaises(KeyError, t2.traverse, 'abcd') self.assertEqual("Lol", t2.traverse('axyy')) self.assertEqual("ololol", t2.traverse('axx')) t2.unset('axyy') self.assertEqual("ololol", t2.traverse('axx')) self.assertRaises(KeyError, t2.traverse, 'axyy') self.assertRaises(KeyError, t2.traverse, 'axy') t2.unset('a') self.assertRaises(KeyError, t2.traverse, 'abcd') self.assertRaises(KeyError, t2.traverse, 'a') self.assert_(t2.empty()) def test_merge_trees(self): def makeTreeA(): t = Tree() t.set('aaaX', 1) t.set('aaaY', 2) t.set('aaaZ', 3) t.set('bbbA', 11) t.set('bbbB', 12) t.set('bbbC', 13) t.set('bbbD', 14) t.set('bP', 21) t.set('bQ', 22) return t def makeTreeB(): u = Tree() u.set('aaaX', 0) u.set('bbbC', 'Yes') u.set('bbbD', None) u.set('bbbE', 15) u.set('bbbF', 16) u.set('bQ', 22) u.set('bR', 23) u.set('ffff', 1337) return u # test 1 t = Tree('a') u = Tree('b') merged = t.merge(u, copy=True) self.assertEqual('b', merged._tree) # test 2 t = Tree('a') u = makeTreeA() merged = t.merge(u, copy=True) self.assertEqual(u._tree, merged._tree) # test 3 t = makeTreeA() u = makeTreeB() v = t.merge(u, copy=True) self.assertEqual(0, v['aaaX']) self.assertEqual(2, v['aaaY']) self.assertEqual(3, v['aaaZ']) self.assertEqual(11, v['bbbA']) self.assertEqual('Yes', v['bbbC']) self.assertEqual(None, v['bbbD']) self.assertEqual(15, v['bbbE']) self.assertEqual(16, v['bbbF']) self.assertRaises(KeyError, t.__getitem__, 'bbbG') self.assertEqual(21, v['bP']) self.assertEqual(22, v['bQ']) self.assertEqual(23, v['bR']) self.assertEqual(1337, v['ffff']) # merge shouldn't be destructive self.assertEqual(makeTreeA()._tree, t._tree) self.assertEqual(makeTreeB()._tree, u._tree) v['fff'].replace('Lolz') self.assertEqual('Lolz', v['fff']) v['aaa'].replace('Very bad') v.plow('qqqqqqq').replace('eww.') self.assertEqual(makeTreeA()._tree, t._tree) self.assertEqual(makeTreeB()._tree, u._tree) def test_add(self): c = KeyMap() c.map('aa', 'b', lambda *_: 'lolz') self.assert_(c['aa'].function(), 'lolz') @c.map('a', 'c') def test(): return 5 self.assert_(c['b'].function(), 'lolz') self.assert_(c['c'].function(), 5) self.assert_(c['a'].function(), 5) def test_quantifier(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) def n(value): """return n or value""" def fnc(arg=None): if arg is None or arg.n is None: return value return arg.n return fnc km.map('p', n(5)) press = self._mkpress(kb, km) self.assertEqual(5, press('p')) self.assertEqual(3, press('3p')) self.assertEqual(6223, press('6223p')) def test_direction(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) directions.map('j', dir=Direction(down=1)) directions.map('k', dir=Direction(down=-1)) def nd(arg): """ n * direction """ n = arg.n is None and 1 or arg.n dir = arg.direction is None and Direction(down=1) \ or arg.direction return n * dir.down() km.map('d<dir>', nd) km.map('dd', func=nd) press = self._mkpress(kb, km) self.assertPressIncomplete(kb, 'd') self.assertEqual( 1, press('dj')) self.assertEqual( 3, press('3ddj')) self.assertEqual( 15, press('3d5j')) self.assertEqual(-15, press('3d5k')) # supporting this kind of key combination would be too confusing: # self.assertEqual( 15, press('3d5d')) self.assertEqual( 3, press('3dd')) self.assertEqual( 33, press('33dd')) self.assertEqual( 1, press('dd')) km.map('x<dir>', nd) km.map('xxxx', func=nd) self.assertEqual(1, press('xxxxj')) self.assertEqual(1, press('xxxxjsomeinvalitchars')) # these combinations should break: self.assertPressFails(kb, 'xxxj') self.assertPressFails(kb, 'xxj') self.assertPressFails(kb, 'xxkldfjalksdjklsfsldkj') self.assertPressFails(kb, 'xyj') self.assertPressIncomplete(kb, 'x') # direction missing def test_any_key(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) directions.map('j', dir=Direction(down=1)) directions.map('k', dir=Direction(down=-1)) directions.map('g<any>', dir=Direction(down=-1)) def cat(arg): n = arg.n is None and 1 or arg.n return ''.join(chr(c) for c in arg.matches) * n km.map('return<any>', cat) km.map('cat4<any><any><any><any>', cat) km.map('foo<dir><any>', cat) press = self._mkpress(kb, km) self.assertEqual('x', press('returnx')) self.assertEqual('abcd', press('cat4abcd')) self.assertEqual('abcdabcd', press('2cat4abcd')) self.assertEqual('55555', press('5return5')) self.assertEqual('x', press('foojx')) self.assertPressFails(kb, 'fooggx') # ANYKEY forbidden in DIRECTION km.map('<any>', lambda _: Ellipsis) self.assertEqual('x', press('returnx')) self.assertEqual('abcd', press('cat4abcd')) self.assertEqual(Ellipsis, press('2cat4abcd')) self.assertEqual(Ellipsis, press('5return5')) self.assertEqual(Ellipsis, press('g')) self.assertEqual(Ellipsis, press('ß')) self.assertEqual(Ellipsis, press('ア')) self.assertEqual(Ellipsis, press('9')) def test_multiple_directions(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) directions.map('j', dir=Direction(down=1)) directions.map('k', dir=Direction(down=-1)) def add_dirs(arg): return sum(dir.down() for dir in arg.directions) km.map('x<dir>y<dir>', add_dirs) km.map('four<dir><dir><dir><dir>', add_dirs) press = self._mkpress(kb, km) self.assertEqual(2, press('xjyj')) self.assertEqual(0, press('fourjkkj')) self.assertEqual(2, press('four2j4k2j2j')) self.assertEqual(10, press('four1j2j3j4j')) self.assertEqual(10, press('four1j2j3j4jafslkdfjkldj')) def test_corruptions(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) press = self._mkpress(kb, km) directions.map('j', dir=Direction(down=1)) directions.map('k', dir=Direction(down=-1)) km.map('xxx', lambda _: 1) self.assertEqual(1, press('xxx')) # corrupt the tree tup = tuple(parse_keybinding('xxx')) x = ord('x') km._tree[x][x][x] = "Boo" self.assertPressFails(kb, 'xxy') self.assertPressFails(kb, 'xzy') self.assertPressIncomplete(kb, 'xx') self.assertPressIncomplete(kb, 'x') if not sys.flags.optimize: self.assertRaises(AssertionError, simulate_press, kb, 'xxx') kb.clear() def test_directions_as_functions(self): km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) press = self._mkpress(kb, km) def move(arg): return arg.direction.down() directions.map('j', dir=Direction(down=1)) directions.map('s', alias='j') directions.map('k', dir=Direction(down=-1)) km.map('<dir>', func=move) self.assertEqual(1, press('j')) self.assertEqual(1, press('j')) self.assertEqual(1, press('j')) self.assertEqual(1, press('j')) self.assertEqual(1, press('j')) self.assertEqual(1, press('s')) self.assertEqual(1, press('s')) self.assertEqual(1, press('s')) self.assertEqual(1, press('s')) self.assertEqual(1, press('s')) self.assertEqual(-1, press('k')) self.assertEqual(-1, press('k')) self.assertEqual(-1, press('k')) km.map('k', func=lambda _: 'love') self.assertEqual(1, press('j')) self.assertEqual('love', press('k')) self.assertEqual(1, press('40j')) self.assertEqual(40, kb.quant) km.map('<dir><dir><any><any>', func=move) self.assertEqual(1, press('40jkhl')) self.assertEqual(40, kb.quant) def test_tree_deep_copy(self): t = Tree() s = t.plow('abcd') s.replace('X') u = t.copy() self.assertEqual(t._tree, u._tree) s = t.traverse('abc') s.replace('Y') self.assertNotEqual(t._tree, u._tree) def test_keymanager(self): def func(arg): return 5 def getdown(arg): return arg.direction.down() buffer = KeyBuffer(None, None) press = self._mkpress(buffer) keymanager = KeyManager(buffer, ['foo', 'bar']) map = keymanager.get_context('foo') map('a', func) map('b', func) map = keymanager.get_context('bar') map('c', func) map('<dir>', getdown) keymanager.dir('foo', 'j', down=1) keymanager.dir('bar', 'j', down=1) keymanager.use_context('foo') self.assertEqual(5, press('a')) self.assertEqual(5, press('b')) self.assertPressFails(buffer, 'c') keymanager.use_context('bar') self.assertPressFails(buffer, 'a') self.assertPressFails(buffer, 'b') self.assertEqual(5, press('c')) self.assertEqual(1, press('j')) keymanager.use_context('foo') keymanager.use_context('foo') keymanager.use_context('foo') keymanager.use_context('bar') keymanager.use_context('foo') keymanager.use_context('bar') keymanager.use_context('bar') self.assertEqual(1, press('j')) def test_alias_to_direction(self): def func(arg): return arg.direction.down() km = KeyMapWithDirections() kb = KeyBuffer(km, km.directions) press = self._mkpress(kb) km.map('<dir>', func) km.map('d<dir>', func) km.dir('j', down=42) km.dir('k', alias='j') self.assertEqual(42, press('j')) km.dir('o', alias='j') km.dir('ick', alias='j') self.assertEqual(42, press('o')) self.assertEqual(42, press('dj')) self.assertEqual(42, press('dk')) self.assertEqual(42, press('do')) self.assertEqual(42, press('dick')) self.assertPressFails(kb, 'dioo') def test_both_directory_and_any_key(self): def func(arg): return arg.direction.down() def func2(arg): return "yay" km = KeyMap() directions = KeyMap() kb = KeyBuffer(km, directions) press = self._mkpress(kb) km.map('abc<dir>', func) directions.map('j', dir=Direction(down=42)) self.assertEqual(42, press('abcj')) km.unmap('abc<dir>') km.map('abc<any>', func2) self.assertEqual("yay", press('abcd')) km.map('abc<dir>', func) km.map('abc<any>', func2) self.assertEqual("yay", press('abcd')) def test_map_collision(self): def add_dirs(arg): return sum(dir.down() for dir in arg.directions) def return5(_): return 5 directions = KeyMap() directions.map('gg', dir=Direction(down=1)) km = KeyMap() km.map('gh', return5) km.map('agh', return5) km.map('a<dir>', add_dirs) kb = KeyBuffer(km, directions) press = self._mkpress(kb, km) self.assertEqual(5, press('gh')) self.assertEqual(5, press('agh')) # self.assertPressFails(kb, 'agh') # TODO: Make the next line work! For now, skip it. # self.assertEqual(1, press('agg')) def test_keymap_with_dir(self): def func(arg): return arg.direction.down() km = KeyMapWithDirections() kb = KeyBuffer(km, km.directions) press = self._mkpress(kb) km.map('abc<dir>', func) km.dir('j', down=42) self.assertEqual(42, press('abcj')) if __name__ == '__main__': main()