##// END OF EJS Templates
Add a class _CommandInput that implements the basic functionality of...
walter.doerwald -
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": "goto object #: ",
719 "goto": _CommandGoto(),
515 "find": "find expression: ",
720 "find": _CommandFind(),
516 "findbackwards": "find backwards expression: "
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,9 +1433,10 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 self.prompts[self.mode] + self.keyboardinput,
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:
1287 if self._report is not None:
1442 if self._report is not None:
@@ -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 scr.move(self.scrsizey-1, len(self.prompts[self.mode])+self.cursorpos)
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,43 +1476,8 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:
1480 break # Redisplay
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
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
1362 if c == -1:
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 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