Show More
@@ -446,6 +446,211 b' class _BrowserLevel(object):' | |||
|
446 | 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 | 654 | class ibrowse(ipipe.Display): |
|
450 | 655 | # Show this many lines from the previous screen when paging horizontally |
|
451 | 656 | pageoverlapx = 1 |
@@ -511,9 +716,9 b' class ibrowse(ipipe.Display):' | |||
|
511 | 716 | |
|
512 | 717 | # Prompts for modes that require keyboard input |
|
513 | 718 | prompts = { |
|
514 |
"goto": |
|
|
515 | "find": "find expression: ", | |
|
516 |
"findbackwards": |
|
|
719 | "goto": _CommandGoto(), | |
|
720 | "find": _CommandFind(), | |
|
721 | "findbackwards": _CommandFindBackwards() | |
|
517 | 722 | } |
|
518 | 723 | |
|
519 | 724 | # Maps curses key codes to "function" names |
@@ -537,6 +742,7 b' class ibrowse(ipipe.Display):' | |||
|
537 | 742 | ord("m"): "pickmarked", |
|
538 | 743 | ord("M"): "pickmarkedattr", |
|
539 | 744 | ord("\n"): "enterdefault", |
|
745 | ord("\r"): "enterdefault", | |
|
540 | 746 | # FIXME: What's happening here? |
|
541 | 747 | 8: "leave", |
|
542 | 748 | 127: "leave", |
@@ -712,14 +918,7 b' class ibrowse(ipipe.Display):' | |||
|
712 | 918 | Enter mode ``mode``, which requires keyboard input. |
|
713 | 919 | """ |
|
714 | 920 | self.mode = mode |
|
715 | self.keyboardinput = "" | |
|
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" | |
|
921 | self.prompts[mode].start() | |
|
723 | 922 | |
|
724 | 923 | def keylabel(self, keycode): |
|
725 | 924 | """ |
@@ -1027,57 +1226,12 b' class ibrowse(ipipe.Display):' | |||
|
1027 | 1226 | def cmd_goto(self): |
|
1028 | 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 | 1229 | def cmd_find(self): |
|
1036 | 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 | 1232 | def cmd_findbackwards(self): |
|
1060 | 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 | 1235 | def cmd_help(self): |
|
1082 | 1236 | """ |
|
1083 | 1237 | The help command |
@@ -1279,9 +1433,10 b' class ibrowse(ipipe.Display):' | |||
|
1279 | 1433 | try: |
|
1280 | 1434 | # Display input prompt |
|
1281 | 1435 | if self.mode in self.prompts: |
|
1436 | history = self.prompts[self.mode] | |
|
1282 | 1437 | scr.addstr(self.scrsizey-1, 0, |
|
1283 |
|
|
|
1284 | self.getstyle(astyle.style_default)) | |
|
1438 | history.prompt + ": " + history.input, | |
|
1439 | self.getstyle(astyle.style_default)) | |
|
1285 | 1440 | # Display report |
|
1286 | 1441 | else: |
|
1287 | 1442 | if self._report is not None: |
@@ -1308,7 +1463,8 b' class ibrowse(ipipe.Display):' | |||
|
1308 | 1463 | |
|
1309 | 1464 | # Position cursor |
|
1310 | 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 | 1468 | else: |
|
1313 | 1469 | scr.move( |
|
1314 | 1470 | 1+self._headerlines+level.cury-level.datastarty, |
@@ -1320,43 +1476,8 b' class ibrowse(ipipe.Display):' | |||
|
1320 | 1476 | while True: |
|
1321 | 1477 | c = scr.getch() |
|
1322 | 1478 | if self.mode in self.prompts: |
|
1323 | if c in (8, 127, curses.KEY_BACKSPACE): | |
|
1324 |
|
|
|
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 | break # Redisplay | |
|
1479 | if self.prompts[self.mode].handlekey(self, c): | |
|
1480 | break # Redisplay | |
|
1360 | 1481 | else: |
|
1361 | 1482 | # if no key is pressed slow down and beep again |
|
1362 | 1483 | if c == -1: |
@@ -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 | 10 | 2006-06-07 Ville Vainio <vivainio@gmail.com> |
|
2 | 11 | |
|
3 | 12 | * iplib.py: ipython mybatch.ipy exits ipython immediately after |
General Comments 0
You need to be logged in to leave comments.
Login now