Show More
@@ -446,6 +446,211 b' class _BrowserLevel(object):' | |||||
446 | self.moveto(self.curx, cury, refresh=True) |
|
446 | self.moveto(self.curx, cury, refresh=True) | |
447 |
|
447 | |||
448 |
|
448 | |||
|
449 | class _CommandInput(object): | |||
|
450 | keymap = { | |||
|
451 | curses.KEY_LEFT: "left", | |||
|
452 | curses.KEY_RIGHT: "right", | |||
|
453 | curses.KEY_HOME: "home", | |||
|
454 | curses.KEY_END: "end", | |||
|
455 | # FIXME: What's happening here? | |||
|
456 | 8: "backspace", | |||
|
457 | 127: "backspace", | |||
|
458 | curses.KEY_BACKSPACE: "backspace", | |||
|
459 | curses.KEY_DC: "delete", | |||
|
460 | ord("x"): "delete", | |||
|
461 | ord("\n"): "execute", | |||
|
462 | ord("\r"): "execute", | |||
|
463 | curses.KEY_UP: "up", | |||
|
464 | curses.KEY_DOWN: "down", | |||
|
465 | # CTRL-X | |||
|
466 | 0x18: "exit", | |||
|
467 | } | |||
|
468 | ||||
|
469 | def __init__(self, prompt): | |||
|
470 | self.prompt = prompt | |||
|
471 | self.history = [] | |||
|
472 | self.maxhistory = 100 | |||
|
473 | self.input = "" | |||
|
474 | self.curx = 0 | |||
|
475 | self.cury = -1 # blank line | |||
|
476 | ||||
|
477 | def start(self): | |||
|
478 | self.input = "" | |||
|
479 | self.curx = 0 | |||
|
480 | self.cury = -1 # blank line | |||
|
481 | ||||
|
482 | def handlekey(self, browser, key): | |||
|
483 | cmdname = self.keymap.get(key, None) | |||
|
484 | if cmdname is not None: | |||
|
485 | cmdfunc = getattr(self, "cmd_%s" % cmdname, None) | |||
|
486 | if cmdfunc is not None: | |||
|
487 | return cmdfunc(browser) | |||
|
488 | curses.beep() | |||
|
489 | elif key != -1: | |||
|
490 | try: | |||
|
491 | char = chr(key) | |||
|
492 | except ValueError: | |||
|
493 | curses.beep() | |||
|
494 | else: | |||
|
495 | return self.handlechar(browser, char) | |||
|
496 | ||||
|
497 | def handlechar(self, browser, char): | |||
|
498 | self.input = self.input[:self.curx] + char + self.input[self.curx:] | |||
|
499 | self.curx += 1 | |||
|
500 | return True | |||
|
501 | ||||
|
502 | def dohistory(self): | |||
|
503 | self.history.insert(0, self.input) | |||
|
504 | del self.history[:-self.maxhistory] | |||
|
505 | ||||
|
506 | def cmd_backspace(self, browser): | |||
|
507 | if self.curx: | |||
|
508 | self.input = self.input[:self.curx-1] + self.input[self.curx:] | |||
|
509 | self.curx -= 1 | |||
|
510 | return True | |||
|
511 | else: | |||
|
512 | curses.beep() | |||
|
513 | ||||
|
514 | def cmd_delete(self, browser): | |||
|
515 | if self.curx<len(self.input): | |||
|
516 | self.input = self.input[:self.curx] + self.input[self.curx+1:] | |||
|
517 | return True | |||
|
518 | else: | |||
|
519 | curses.beep() | |||
|
520 | ||||
|
521 | def cmd_left(self, browser): | |||
|
522 | if self.curx: | |||
|
523 | self.curx -= 1 | |||
|
524 | return True | |||
|
525 | else: | |||
|
526 | curses.beep() | |||
|
527 | ||||
|
528 | def cmd_right(self, browser): | |||
|
529 | if self.curx < len(self.input): | |||
|
530 | self.curx += 1 | |||
|
531 | return True | |||
|
532 | else: | |||
|
533 | curses.beep() | |||
|
534 | ||||
|
535 | def cmd_home(self, browser): | |||
|
536 | if self.curx: | |||
|
537 | self.curx = 0 | |||
|
538 | return True | |||
|
539 | else: | |||
|
540 | curses.beep() | |||
|
541 | ||||
|
542 | def cmd_end(self, browser): | |||
|
543 | if self.curx < len(self.input): | |||
|
544 | self.curx = len(self.input) | |||
|
545 | return True | |||
|
546 | else: | |||
|
547 | curses.beep() | |||
|
548 | ||||
|
549 | def cmd_up(self, browser): | |||
|
550 | if self.cury < len(self.history)-1: | |||
|
551 | self.cury += 1 | |||
|
552 | self.input = self.history[self.cury] | |||
|
553 | self.curx = len(self.input) | |||
|
554 | return True | |||
|
555 | else: | |||
|
556 | curses.beep() | |||
|
557 | ||||
|
558 | def cmd_down(self, browser): | |||
|
559 | if self.cury >= 0: | |||
|
560 | self.cury -= 1 | |||
|
561 | if self.cury>=0: | |||
|
562 | self.input = self.history[self.cury] | |||
|
563 | else: | |||
|
564 | self.input = "" | |||
|
565 | self.curx = len(self.input) | |||
|
566 | return True | |||
|
567 | else: | |||
|
568 | curses.beep() | |||
|
569 | ||||
|
570 | def cmd_exit(self, browser): | |||
|
571 | browser.mode = "default" | |||
|
572 | return True | |||
|
573 | ||||
|
574 | def cmd_execute(self, browser): | |||
|
575 | raise NotImplementedError | |||
|
576 | ||||
|
577 | ||||
|
578 | class _CommandGoto(_CommandInput): | |||
|
579 | def __init__(self): | |||
|
580 | _CommandInput.__init__(self, "goto object #") | |||
|
581 | ||||
|
582 | def handlechar(self, browser, char): | |||
|
583 | # Only accept digits | |||
|
584 | if not "0" <= char <= "9": | |||
|
585 | curses.beep() | |||
|
586 | else: | |||
|
587 | return _CommandInput.handlechar(self, browser, char) | |||
|
588 | ||||
|
589 | def cmd_execute(self, browser): | |||
|
590 | level = browser.levels[-1] | |||
|
591 | if self.input: | |||
|
592 | self.dohistory() | |||
|
593 | level.moveto(level.curx, int(self.input)) | |||
|
594 | browser.mode = "default" | |||
|
595 | return True | |||
|
596 | ||||
|
597 | ||||
|
598 | class _CommandFind(_CommandInput): | |||
|
599 | def __init__(self): | |||
|
600 | _CommandInput.__init__(self, "find expression") | |||
|
601 | ||||
|
602 | def cmd_execute(self, browser): | |||
|
603 | level = browser.levels[-1] | |||
|
604 | if self.input: | |||
|
605 | self.dohistory() | |||
|
606 | while True: | |||
|
607 | cury = level.cury | |||
|
608 | level.moveto(level.curx, cury+1) | |||
|
609 | if cury == level.cury: | |||
|
610 | curses.beep() | |||
|
611 | break # hit end | |||
|
612 | item = level.items[level.cury].item | |||
|
613 | try: | |||
|
614 | globals = ipipe.getglobals(None) | |||
|
615 | if eval(self.input, globals, ipipe.AttrNamespace(item)): | |||
|
616 | break # found something | |||
|
617 | except (KeyboardInterrupt, SystemExit): | |||
|
618 | raise | |||
|
619 | except Exception, exc: | |||
|
620 | browser.report(exc) | |||
|
621 | curses.beep() | |||
|
622 | break # break on error | |||
|
623 | browser.mode = "default" | |||
|
624 | return True | |||
|
625 | ||||
|
626 | ||||
|
627 | class _CommandFindBackwards(_CommandInput): | |||
|
628 | def __init__(self): | |||
|
629 | _CommandInput.__init__(self, "find backwards expression") | |||
|
630 | ||||
|
631 | def cmd_execute(self, browser): | |||
|
632 | level = browser.levels[-1] | |||
|
633 | if self.input: | |||
|
634 | self.dohistory() | |||
|
635 | while level.cury: | |||
|
636 | level.moveto(level.curx, level.cury-1) | |||
|
637 | item = level.items[level.cury].item | |||
|
638 | try: | |||
|
639 | globals = ipipe.getglobals(None) | |||
|
640 | if eval(self.input, globals, ipipe.AttrNamespace(item)): | |||
|
641 | break # found something | |||
|
642 | except (KeyboardInterrupt, SystemExit): | |||
|
643 | raise | |||
|
644 | except Exception, exc: | |||
|
645 | browser.report(exc) | |||
|
646 | curses.beep() | |||
|
647 | break # break on error | |||
|
648 | else: | |||
|
649 | curses.beep() | |||
|
650 | browser.mode = "default" | |||
|
651 | return True | |||
|
652 | ||||
|
653 | ||||
449 | class ibrowse(ipipe.Display): |
|
654 | class ibrowse(ipipe.Display): | |
450 | # Show this many lines from the previous screen when paging horizontally |
|
655 | # Show this many lines from the previous screen when paging horizontally | |
451 | pageoverlapx = 1 |
|
656 | pageoverlapx = 1 | |
@@ -511,9 +716,9 b' class ibrowse(ipipe.Display):' | |||||
511 |
|
716 | |||
512 | # Prompts for modes that require keyboard input |
|
717 | # Prompts for modes that require keyboard input | |
513 | prompts = { |
|
718 | prompts = { | |
514 |
"goto": |
|
719 | "goto": _CommandGoto(), | |
515 | "find": "find expression: ", |
|
720 | "find": _CommandFind(), | |
516 |
"findbackwards": |
|
721 | "findbackwards": _CommandFindBackwards() | |
517 | } |
|
722 | } | |
518 |
|
723 | |||
519 | # Maps curses key codes to "function" names |
|
724 | # Maps curses key codes to "function" names | |
@@ -537,6 +742,7 b' class ibrowse(ipipe.Display):' | |||||
537 | ord("m"): "pickmarked", |
|
742 | ord("m"): "pickmarked", | |
538 | ord("M"): "pickmarkedattr", |
|
743 | ord("M"): "pickmarkedattr", | |
539 | ord("\n"): "enterdefault", |
|
744 | ord("\n"): "enterdefault", | |
|
745 | ord("\r"): "enterdefault", | |||
540 | # FIXME: What's happening here? |
|
746 | # FIXME: What's happening here? | |
541 | 8: "leave", |
|
747 | 8: "leave", | |
542 | 127: "leave", |
|
748 | 127: "leave", | |
@@ -712,14 +918,7 b' class ibrowse(ipipe.Display):' | |||||
712 | Enter mode ``mode``, which requires keyboard input. |
|
918 | Enter mode ``mode``, which requires keyboard input. | |
713 | """ |
|
919 | """ | |
714 | self.mode = mode |
|
920 | self.mode = mode | |
715 | self.keyboardinput = "" |
|
921 | self.prompts[mode].start() | |
716 | self.cursorpos = 0 |
|
|||
717 |
|
||||
718 | def executekeyboardinput(self, mode): |
|
|||
719 | exe = getattr(self, "exe_%s" % mode, None) |
|
|||
720 | if exe is not None: |
|
|||
721 | exe() |
|
|||
722 | self.mode = "default" |
|
|||
723 |
|
922 | |||
724 | def keylabel(self, keycode): |
|
923 | def keylabel(self, keycode): | |
725 | """ |
|
924 | """ | |
@@ -1027,57 +1226,12 b' class ibrowse(ipipe.Display):' | |||||
1027 | def cmd_goto(self): |
|
1226 | def cmd_goto(self): | |
1028 | self.startkeyboardinput("goto") |
|
1227 | self.startkeyboardinput("goto") | |
1029 |
|
1228 | |||
1030 | def exe_goto(self): |
|
|||
1031 | level = self.levels[-1] |
|
|||
1032 | if self.keyboardinput: |
|
|||
1033 | level.moveto(level.curx, int(self.keyboardinput)) |
|
|||
1034 |
|
||||
1035 | def cmd_find(self): |
|
1229 | def cmd_find(self): | |
1036 | self.startkeyboardinput("find") |
|
1230 | self.startkeyboardinput("find") | |
1037 |
|
1231 | |||
1038 | def exe_find(self): |
|
|||
1039 | level = self.levels[-1] |
|
|||
1040 | if self.keyboardinput: |
|
|||
1041 | while True: |
|
|||
1042 | cury = level.cury |
|
|||
1043 | level.moveto(level.curx, cury+1) |
|
|||
1044 | if cury == level.cury: |
|
|||
1045 | curses.beep() |
|
|||
1046 | break |
|
|||
1047 | item = level.items[level.cury].item |
|
|||
1048 | try: |
|
|||
1049 | globals = ipipe.getglobals(None) |
|
|||
1050 | if eval(self.keyboardinput, globals, ipipe.AttrNamespace(item)): |
|
|||
1051 | break |
|
|||
1052 | except (KeyboardInterrupt, SystemExit): |
|
|||
1053 | raise |
|
|||
1054 | except Exception, exc: |
|
|||
1055 | self.report(exc) |
|
|||
1056 | curses.beep() |
|
|||
1057 | break # break on error |
|
|||
1058 |
|
||||
1059 | def cmd_findbackwards(self): |
|
1232 | def cmd_findbackwards(self): | |
1060 | self.startkeyboardinput("findbackwards") |
|
1233 | self.startkeyboardinput("findbackwards") | |
1061 |
|
1234 | |||
1062 | def exe_findbackwards(self): |
|
|||
1063 | level = self.levels[-1] |
|
|||
1064 | if self.keyboardinput: |
|
|||
1065 | while level.cury: |
|
|||
1066 | level.moveto(level.curx, level.cury-1) |
|
|||
1067 | item = level.items[level.cury].item |
|
|||
1068 | try: |
|
|||
1069 | globals = ipipe.getglobals(None) |
|
|||
1070 | if eval(self.keyboardinput, globals, ipipe.AttrNamespace(item)): |
|
|||
1071 | break |
|
|||
1072 | except (KeyboardInterrupt, SystemExit): |
|
|||
1073 | raise |
|
|||
1074 | except Exception, exc: |
|
|||
1075 | self.report(exc) |
|
|||
1076 | curses.beep() |
|
|||
1077 | break # break on error |
|
|||
1078 | else: |
|
|||
1079 | curses.beep() |
|
|||
1080 |
|
||||
1081 | def cmd_help(self): |
|
1235 | def cmd_help(self): | |
1082 | """ |
|
1236 | """ | |
1083 | The help command |
|
1237 | The help command | |
@@ -1279,8 +1433,9 b' class ibrowse(ipipe.Display):' | |||||
1279 | try: |
|
1433 | try: | |
1280 | # Display input prompt |
|
1434 | # Display input prompt | |
1281 | if self.mode in self.prompts: |
|
1435 | if self.mode in self.prompts: | |
|
1436 | history = self.prompts[self.mode] | |||
1282 | scr.addstr(self.scrsizey-1, 0, |
|
1437 | scr.addstr(self.scrsizey-1, 0, | |
1283 |
|
|
1438 | history.prompt + ": " + history.input, | |
1284 | self.getstyle(astyle.style_default)) |
|
1439 | self.getstyle(astyle.style_default)) | |
1285 | # Display report |
|
1440 | # Display report | |
1286 | else: |
|
1441 | else: | |
@@ -1308,7 +1463,8 b' class ibrowse(ipipe.Display):' | |||||
1308 |
|
1463 | |||
1309 | # Position cursor |
|
1464 | # Position cursor | |
1310 | if self.mode in self.prompts: |
|
1465 | if self.mode in self.prompts: | |
1311 |
|
|
1466 | history = self.prompts[self.mode] | |
|
1467 | scr.move(self.scrsizey-1, len(history.prompt)+2+history.curx) | |||
1312 | else: |
|
1468 | else: | |
1313 | scr.move( |
|
1469 | scr.move( | |
1314 | 1+self._headerlines+level.cury-level.datastarty, |
|
1470 | 1+self._headerlines+level.cury-level.datastarty, | |
@@ -1320,42 +1476,7 b' class ibrowse(ipipe.Display):' | |||||
1320 | while True: |
|
1476 | while True: | |
1321 | c = scr.getch() |
|
1477 | c = scr.getch() | |
1322 | if self.mode in self.prompts: |
|
1478 | if self.mode in self.prompts: | |
1323 | if c in (8, 127, curses.KEY_BACKSPACE): |
|
1479 | if self.prompts[self.mode].handlekey(self, c): | |
1324 | if self.cursorpos: |
|
|||
1325 | self.keyboardinput = self.keyboardinput[:self.cursorpos-1] + self.keyboardinput[self.cursorpos:] |
|
|||
1326 | self.cursorpos -= 1 |
|
|||
1327 | break |
|
|||
1328 | else: |
|
|||
1329 | curses.beep() |
|
|||
1330 | elif c == curses.KEY_LEFT: |
|
|||
1331 | if self.cursorpos: |
|
|||
1332 | self.cursorpos -= 1 |
|
|||
1333 | break |
|
|||
1334 | else: |
|
|||
1335 | curses.beep() |
|
|||
1336 | elif c == curses.KEY_RIGHT: |
|
|||
1337 | if self.cursorpos < len(self.keyboardinput): |
|
|||
1338 | self.cursorpos += 1 |
|
|||
1339 | break |
|
|||
1340 | else: |
|
|||
1341 | curses.beep() |
|
|||
1342 | elif c in (curses.KEY_UP, curses.KEY_DOWN): # cancel |
|
|||
1343 | self.mode = "default" |
|
|||
1344 | break |
|
|||
1345 | elif c == ord("\n"): |
|
|||
1346 | self.executekeyboardinput(self.mode) |
|
|||
1347 | break |
|
|||
1348 | elif c != -1: |
|
|||
1349 | try: |
|
|||
1350 | c = chr(c) |
|
|||
1351 | except ValueError: |
|
|||
1352 | curses.beep() |
|
|||
1353 | else: |
|
|||
1354 | if (self.mode == "goto" and not "0" <= c <= "9"): |
|
|||
1355 | curses.beep() |
|
|||
1356 | else: |
|
|||
1357 | self.keyboardinput = self.keyboardinput[:self.cursorpos] + c + self.keyboardinput[self.cursorpos:] |
|
|||
1358 | self.cursorpos += 1 |
|
|||
1359 |
|
|
1480 | break # Redisplay | |
1360 | else: |
|
1481 | else: | |
1361 | # if no key is pressed slow down and beep again |
|
1482 | # if no key is pressed slow down and beep again |
@@ -1,3 +1,12 b'' | |||||
|
1 | 2006-06-10 Walter Doerwald <walter@livinglogic.de> | |||
|
2 | ||||
|
3 | * IPython/Extensions/ibrowse.py: Add a class _CommandInput that | |||
|
4 | implements the basic functionality of browser commands that require | |||
|
5 | input. Reimplement the goto, find and findbackwards commands as | |||
|
6 | subclasses of _CommandInput. Add an input history and keymaps to those | |||
|
7 | commands. Add "\r" as a keyboard shortcut for the enterdefault and | |||
|
8 | execute commands. | |||
|
9 | ||||
1 | 2006-06-07 Ville Vainio <vivainio@gmail.com> |
|
10 | 2006-06-07 Ville Vainio <vivainio@gmail.com> | |
2 |
|
11 | |||
3 | * iplib.py: ipython mybatch.ipy exits ipython immediately after |
|
12 | * iplib.py: ipython mybatch.ipy exits ipython immediately after |
General Comments 0
You need to be logged in to leave comments.
Login now