| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6df6a4a commit fa08b74
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -84,6 +84,9 @@ | |||
| 84 | 84 | Press {config.edit_config_key} to edit this config file. | |
| 85 | 85 | """ | |
| 86 | 86 | EXAMPLE_CONFIG_URL = 'https://raw.githubusercontent.com/bpython/bpython/master/bpython/sample-config' | |
| 87 | + MAX_EVENTS_POSSIBLY_NOT_PASTE = 20 # more than this many events will be assumed to | ||
| 88 | + # be a true paste event, i.e. control characters | ||
| 89 | + # like '<Ctrl-a>' will be stripped | ||
| 87 | 90 | ||
| 88 | 91 | # This is needed for is_nop and should be removed once is_nop is fixed. | |
| 89 | 92 | if py3: | |
@@ -545,16 +548,25 @@ def process_control_event(self, e): | |||
| 545 | 548 | ctrl_char = compress_paste_event(e) | |
| 546 | 549 | if ctrl_char is not None: | |
| 547 | 550 | return self.process_event(ctrl_char) | |
| 548 | - simple_events = just_simple_events(e.events) | ||
| 549 | - source = preprocess(''.join(simple_events), | ||
| 550 | - self.interp.compile) | ||
| 551 | - | ||
| 552 | 551 | with self.in_paste_mode(): | |
| 553 | - for ee in source: | ||
| 554 | - if self.stdin.has_focus: | ||
| 555 | - self.stdin.process_event(ee) | ||
| 556 | - else: | ||
| 557 | - self.process_simple_keypress(ee) | ||
| 552 | + # Might not really be a paste, UI might just be lagging | ||
| 553 | + if (len(e.events) <= MAX_EVENTS_POSSIBLY_NOT_PASTE and | ||
| 554 | + any(not is_simple_event(ee) for ee in e.events)): | ||
| 555 | + for ee in e.events: | ||
| 556 | + if self.stdin.has_focus: | ||
| 557 | + self.stdin.process_event(ee) | ||
| 558 | + else: | ||
| 559 | + self.process_event(ee) | ||
| 560 | + else: | ||
| 561 | + simple_events = just_simple_events(e.events) | ||
| 562 | + source = preprocess(''.join(simple_events), | ||
| 563 | + self.interp.compile) | ||
| 564 | + for ee in source: | ||
| 565 | + if self.stdin.has_focus: | ||
| 566 | + self.stdin.process_event(ee) | ||
| 567 | + else: | ||
| 568 | + self.process_simple_keypress(ee) | ||
| 569 | + | ||
| 558 | 570 | ||
| 559 | 571 | elif isinstance(e, bpythonevents.RunStartupFileEvent): | |
| 560 | 572 | try: | |
@@ -1611,11 +1623,24 @@ def just_simple_events(event_list): | |||
| 1611 | 1623 | pass # ignore events | |
| 1612 | 1624 | elif e == '<SPACE>': | |
| 1613 | 1625 | simple_events.append(' ') | |
| 1626 | + elif len(e) > 1: | ||
| 1627 | + pass # get rid of <Ctrl-a> etc. | ||
| 1614 | 1628 | else: | |
| 1615 | 1629 | simple_events.append(e) | |
| 1616 | 1630 | return simple_events | |
| 1617 | 1631 | ||
| 1618 | 1632 | ||
| 1633 | + def is_simple_event(e): | ||
| 1634 | + if isinstance(e, events.Event): | ||
| 1635 | + return False | ||
| 1636 | + if e in ("<Ctrl-j>", "<Ctrl-m>", "<PADENTER>", "\n", "\r", "<SPACE>"): | ||
| 1637 | + return True | ||
| 1638 | + if len(e) > 1: | ||
| 1639 | + return False | ||
| 1640 | + else: | ||
| 1641 | + return True | ||
| 1642 | + | ||
| 1643 | + | ||
| 1619 | 1644 | # TODO this needs some work to function again and be useful for embedding | |
| 1620 | 1645 | def simple_repl(): | |
| 1621 | 1646 | refreshes = [] | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -49,15 +49,15 @@ def tick(self, dt=1): | |||
| 49 | 49 | ||
| 50 | 50 | class TestCurtsiesPasteDetection(TestCase): | |
| 51 | 51 | def test_paste_threshold(self): | |
| 52 | - inputs = combined_events(EventGenerator(list('abc'))) | ||
| 53 | - cb = combined_events(inputs, paste_threshold=3) | ||
| 52 | + eg = EventGenerator(list('abc')) | ||
| 53 | + cb = combined_events(eg, paste_threshold=3) | ||
| 54 | 54 | e = next(cb) | |
| 55 | 55 | self.assertIsInstance(e, curtsies.events.PasteEvent) | |
| 56 | 56 | self.assertEqual(e.events, list('abc')) | |
| 57 | 57 | self.assertEqual(next(cb), None) | |
| 58 | 58 | ||
| 59 | - inputs = combined_events(EventGenerator(list('abc'))) | ||
| 60 | - cb = combined_events(inputs, paste_threshold=4) | ||
| 59 | + eg = EventGenerator(list('abc')) | ||
| 60 | + cb = combined_events(eg, paste_threshold=4) | ||
| 61 | 61 | self.assertEqual(next(cb), 'a') | |
| 62 | 62 | self.assertEqual(next(cb), 'b') | |
| 63 | 63 | self.assertEqual(next(cb), 'c') | |
@@ -67,8 +67,7 @@ def test_set_timeout(self): | |||
| 67 | 67 | eg = EventGenerator('a', zip('bcdefg', [1, 2, 3, 3, 3, 4])) | |
| 68 | 68 | eg.schedule_event(curtsies.events.SigIntEvent(), 5) | |
| 69 | 69 | eg.schedule_event('h', 6) | |
| 70 | - inputs = combined_events(eg) | ||
| 71 | - cb = combined_events(inputs, paste_threshold=3) | ||
| 70 | + cb = combined_events(eg, paste_threshold=3) | ||
| 72 | 71 | self.assertEqual(next(cb), 'a') | |
| 73 | 72 | self.assertEqual(cb.send(0), None) | |
| 74 | 73 | self.assertEqual(next(cb), 'b') | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,8 @@ | |||
| 20 | 20 | from bpython.test import (FixLanguageTestCase as TestCase, MagicIterMock, mock, | |
| 21 | 21 | builtin_target, unittest) | |
| 22 | 22 | ||
| 23 | + from curtsies import events | ||
| 24 | + | ||
| 23 | 25 | ||
| 24 | 26 | def setup_config(conf): | |
| 25 | 27 | config_struct = config.Struct() | |
@@ -402,5 +404,29 @@ def test_startup_event_latin1(self): | |||
| 402 | 404 | self.assertIn('a', self.repl.interp.locals) | |
| 403 | 405 | ||
| 404 | 406 | ||
| 407 | + class TestCurtsiesPasteEvents(TestCase): | ||
| 408 | + | ||
| 409 | + def setUp(self): | ||
| 410 | + self.repl = create_repl() | ||
| 411 | + | ||
| 412 | + def test_control_events_in_small_paste(self): | ||
| 413 | + self.assertGreaterEqual(curtsiesrepl.MAX_EVENTS_POSSIBLY_NOT_PASTE, 6, | ||
| 414 | + 'test assumes UI lag could cause 6 events') | ||
| 415 | + p = events.PasteEvent() | ||
| 416 | + p.events = ['a', 'b', 'c', 'd', '<Ctrl-a>', 'e'] | ||
| 417 | + self.repl.process_event(p) | ||
| 418 | + self.assertEqual(self.repl.current_line, 'eabcd') | ||
| 419 | + | ||
| 420 | + | ||
| 421 | + def test_control_events_in_large_paste(self): | ||
| 422 | + """Large paste events should ignore control characters""" | ||
| 423 | + p = events.PasteEvent() | ||
| 424 | + p.events = (['a', '<Ctrl-a>'] + | ||
| 425 | + ['e'] * curtsiesrepl.MAX_EVENTS_POSSIBLY_NOT_PASTE) | ||
| 426 | + self.repl.process_event(p) | ||
| 427 | + self.assertEqual(self.repl.current_line, | ||
| 428 | + 'a' + 'e'*curtsiesrepl.MAX_EVENTS_POSSIBLY_NOT_PASTE) | ||
| 429 | + | ||
| 430 | + | ||
| 405 | 431 | if __name__ == '__main__': | |
| 406 | 432 | unittest.main() | |
| Back | FazBrowse Home | New Git URL |
0 commit comments