Show More
@@ -802,7 +802,10 def xattrs(item, mode): | |||||
802 | try: |
|
802 | try: | |
803 | func = item.__xattrs__ |
|
803 | func = item.__xattrs__ | |
804 | except AttributeError: |
|
804 | except AttributeError: | |
805 | return (None,) |
|
805 | if mode == "detail": | |
|
806 | return dir(item) | |||
|
807 | else: | |||
|
808 | return (None,) | |||
806 | else: |
|
809 | else: | |
807 | try: |
|
810 | try: | |
808 | return func(mode) |
|
811 | return func(mode) | |
@@ -2517,8 +2520,12 if curses is not None: | |||||
2517 | # Character to use for "empty" cell (i.e. for non-existing attributes) |
|
2520 | # Character to use for "empty" cell (i.e. for non-existing attributes) | |
2518 | nodatachar = "-" |
|
2521 | nodatachar = "-" | |
2519 |
|
2522 | |||
2520 | # Prompt for the goto command |
|
2523 | # Prompts for modes that require keyboard input | |
2521 | prompt_goto = "goto object #: " |
|
2524 | prompts = { | |
|
2525 | "goto": "goto object #: ", | |||
|
2526 | "find": "find expression: ", | |||
|
2527 | "findbackwards": "find backwards expression: " | |||
|
2528 | } | |||
2522 |
|
2529 | |||
2523 | # Maps curses key codes to "function" names |
|
2530 | # Maps curses key codes to "function" names | |
2524 | keymap = { |
|
2531 | keymap = { | |
@@ -2556,6 +2563,8 if curses is not None: | |||||
2556 | ord("v"): "sortattrasc", |
|
2563 | ord("v"): "sortattrasc", | |
2557 | ord("V"): "sortattrdesc", |
|
2564 | ord("V"): "sortattrdesc", | |
2558 | ord("g"): "goto", |
|
2565 | ord("g"): "goto", | |
|
2566 | ord("f"): "find", | |||
|
2567 | ord("b"): "findbackwards", | |||
2559 | } |
|
2568 | } | |
2560 |
|
2569 | |||
2561 | def __init__(self, *attrs): |
|
2570 | def __init__(self, *attrs): | |
@@ -2647,51 +2656,6 if curses is not None: | |||||
2647 | self._styles[style.fg, style.bg, style.attrs] = c |
|
2656 | self._styles[style.fg, style.bg, style.attrs] = c | |
2648 | return c |
|
2657 | return c | |
2649 |
|
2658 | |||
2650 | def format(self, value): |
|
|||
2651 | """ |
|
|||
2652 | Formats one attribute and returns an ``(alignment, string, style)`` |
|
|||
2653 | tuple. |
|
|||
2654 | """ |
|
|||
2655 | if value is None: |
|
|||
2656 | return (-1, repr(value), style_type_none) |
|
|||
2657 | elif isinstance(value, str): |
|
|||
2658 | return (-1, repr(value.expandtabs(tab))[1:-1], style_default) |
|
|||
2659 | elif isinstance(value, unicode): |
|
|||
2660 | return (-1, repr(value.expandtabs(tab))[2:-1], style_default) |
|
|||
2661 | elif isinstance(value, datetime.datetime): |
|
|||
2662 | # Don't use strftime() here, as this requires year >= 1900 |
|
|||
2663 | return (-1, "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \ |
|
|||
2664 | (value.year, value.month, value.day, |
|
|||
2665 | value.hour, value.minute, value.second, |
|
|||
2666 | value.microsecond), |
|
|||
2667 | style_type_datetime) |
|
|||
2668 | elif isinstance(value, datetime.date): |
|
|||
2669 | return (-1, "%04d-%02d-%02d" % \ |
|
|||
2670 | (value.year, value.month, value.day), |
|
|||
2671 | style_type_datetime) |
|
|||
2672 | elif isinstance(value, datetime.time): |
|
|||
2673 | return (-1, "%02d:%02d:%02d.%06d" % \ |
|
|||
2674 | (value.hour, value.minute, value.second, |
|
|||
2675 | value.microsecond), |
|
|||
2676 | style_type_datetime) |
|
|||
2677 | elif isinstance(value, datetime.timedelta): |
|
|||
2678 | return (-1, repr(value), style_type_datetime) |
|
|||
2679 | elif isinstance(value, bool): |
|
|||
2680 | return (-1, repr(value), style_type_bool) |
|
|||
2681 | elif isinstance(value, (int, long, float)): |
|
|||
2682 | return (1, repr(value), style_type_number) |
|
|||
2683 | elif isinstance(value, complex): |
|
|||
2684 | return (-1, repr(value), style_type_number) |
|
|||
2685 | elif isinstance(value, Exception): |
|
|||
2686 | if value.__class__.__module__ == "exceptions": |
|
|||
2687 | value = "%s: %s" % (value.__class__.__name__, value) |
|
|||
2688 | else: |
|
|||
2689 | value = "%s.%s: %s" % \ |
|
|||
2690 | (value.__class__.__module__, value.__class__.__name__, |
|
|||
2691 | value) |
|
|||
2692 | return (-1, value, style_error) |
|
|||
2693 | return (-1, repr(value), style_default) |
|
|||
2694 |
|
||||
2695 | def addstr(self, y, x, begx, endx, text, style): |
|
2659 | def addstr(self, y, x, begx, endx, text, style): | |
2696 | """ |
|
2660 | """ | |
2697 | A version of ``curses.addstr()`` that can handle ``x`` coordinates |
|
2661 | A version of ``curses.addstr()`` that can handle ``x`` coordinates | |
@@ -2754,6 +2718,20 if curses is not None: | |||||
2754 | ) |
|
2718 | ) | |
2755 | self.levels.append(level) |
|
2719 | self.levels.append(level) | |
2756 |
|
2720 | |||
|
2721 | def startkeyboardinput(self, mode): | |||
|
2722 | """ | |||
|
2723 | Enter mode ``mode``, which requires keyboard input. | |||
|
2724 | """ | |||
|
2725 | self.mode = mode | |||
|
2726 | self.keyboardinput = "" | |||
|
2727 | self.cursorpos = 0 | |||
|
2728 | ||||
|
2729 | def executekeyboardinput(self, mode): | |||
|
2730 | exe = getattr(self, "exe_%s" % mode, None) | |||
|
2731 | if exe is not None: | |||
|
2732 | exe() | |||
|
2733 | self.mode = "default" | |||
|
2734 | ||||
2757 | def keylabel(self, keycode): |
|
2735 | def keylabel(self, keycode): | |
2758 | """ |
|
2736 | """ | |
2759 | Return a pretty name for the ``curses`` key ``keycode`` (used in the |
|
2737 | Return a pretty name for the ``curses`` key ``keycode`` (used in the | |
@@ -3058,8 +3036,56 if curses is not None: | |||||
3058 | level.sort(key, reverse=True) |
|
3036 | level.sort(key, reverse=True) | |
3059 |
|
3037 | |||
3060 | def cmd_goto(self): |
|
3038 | def cmd_goto(self): | |
3061 |
self. |
|
3039 | self.startkeyboardinput("goto") | |
3062 | self.goto = "" |
|
3040 | ||
|
3041 | def exe_goto(self): | |||
|
3042 | level = self.levels[-1] | |||
|
3043 | if self.keyboardinput: | |||
|
3044 | level.moveto(level.curx, int(self.keyboardinput)) | |||
|
3045 | ||||
|
3046 | def cmd_find(self): | |||
|
3047 | self.startkeyboardinput("find") | |||
|
3048 | ||||
|
3049 | def exe_find(self): | |||
|
3050 | level = self.levels[-1] | |||
|
3051 | if self.keyboardinput: | |||
|
3052 | while True: | |||
|
3053 | cury = level.cury | |||
|
3054 | level.moveto(level.curx, cury+1) | |||
|
3055 | if cury == level.cury: | |||
|
3056 | curses.beep() | |||
|
3057 | break | |||
|
3058 | item = level.items[level.cury].item | |||
|
3059 | try: | |||
|
3060 | if eval(self.keyboardinput, globals(), _AttrNamespace(item)): | |||
|
3061 | break | |||
|
3062 | except (KeyboardInterrupt, SystemExit): | |||
|
3063 | raise | |||
|
3064 | except Exception, exc: | |||
|
3065 | self.report(exc) | |||
|
3066 | curses.beep() | |||
|
3067 | break # break on error | |||
|
3068 | ||||
|
3069 | def cmd_findbackwards(self): | |||
|
3070 | self.startkeyboardinput("findbackwards") | |||
|
3071 | ||||
|
3072 | def exe_findbackwards(self): | |||
|
3073 | level = self.levels[-1] | |||
|
3074 | if self.keyboardinput: | |||
|
3075 | while level.cury: | |||
|
3076 | level.moveto(level.curx, level.cury-1) | |||
|
3077 | item = level.items[level.cury].item | |||
|
3078 | try: | |||
|
3079 | if eval(self.keyboardinput, globals(), _AttrNamespace(item)): | |||
|
3080 | break | |||
|
3081 | except (KeyboardInterrupt, SystemExit): | |||
|
3082 | raise | |||
|
3083 | except Exception, exc: | |||
|
3084 | self.report(exc) | |||
|
3085 | curses.beep() | |||
|
3086 | break # break on error | |||
|
3087 | else: | |||
|
3088 | curses.beep() | |||
3063 |
|
3089 | |||
3064 | def cmd_help(self): |
|
3090 | def cmd_help(self): | |
3065 | """ |
|
3091 | """ | |
@@ -3260,9 +3286,11 if curses is not None: | |||||
3260 | break |
|
3286 | break | |
3261 |
|
3287 | |||
3262 | try: |
|
3288 | try: | |
3263 |
# Display |
|
3289 | # Display input prompt | |
3264 |
if self.mode |
|
3290 | if self.mode in self.prompts: | |
3265 |
scr.addstr(self.scrsizey-1, 0, |
|
3291 | scr.addstr(self.scrsizey-1, 0, | |
|
3292 | self.prompts[self.mode] + self.keyboardinput, | |||
|
3293 | self.getstyle(style_default)) | |||
3266 | # Display report |
|
3294 | # Display report | |
3267 | else: |
|
3295 | else: | |
3268 | if self._report is not None: |
|
3296 | if self._report is not None: | |
@@ -3288,8 +3316,8 if curses is not None: | |||||
3288 | scr.clrtoeol() |
|
3316 | scr.clrtoeol() | |
3289 |
|
3317 | |||
3290 | # Position cursor |
|
3318 | # Position cursor | |
3291 |
if self.mode |
|
3319 | if self.mode in self.prompts: | |
3292 |
scr.move(self.scrsizey-1, len(self.prompt |
|
3320 | scr.move(self.scrsizey-1, len(self.prompts[self.mode])+self.cursorpos) | |
3293 | else: |
|
3321 | else: | |
3294 | scr.move( |
|
3322 | scr.move( | |
3295 | 1+self._headerlines+level.cury-level.datastarty, |
|
3323 | 1+self._headerlines+level.cury-level.datastarty, | |
@@ -3300,23 +3328,44 if curses is not None: | |||||
3300 | # Check keyboard |
|
3328 | # Check keyboard | |
3301 | while True: |
|
3329 | while True: | |
3302 | c = scr.getch() |
|
3330 | c = scr.getch() | |
3303 |
if self.mode |
|
3331 | if self.mode in self.prompts: | |
3304 | if ord("0") <= c <= ord("9"): |
|
3332 | if c in (8, 127, curses.KEY_BACKSPACE): | |
3305 |
self. |
|
3333 | if self.cursorpos: | |
3306 | break # Redisplay |
|
3334 | self.keyboardinput = self.keyboardinput[:self.cursorpos-1] + self.keyboardinput[self.cursorpos:] | |
3307 | elif c in (8, 127, curses.KEY_BACKSPACE, ord("x")): |
|
3335 | self.cursorpos -= 1 | |
3308 | if self.goto: |
|
|||
3309 | self.goto = self.goto[:-1] |
|
|||
3310 | break |
|
3336 | break | |
3311 | else: |
|
3337 | else: | |
3312 | curses.beep() |
|
3338 | curses.beep() | |
3313 |
elif c == |
|
3339 | elif c == curses.KEY_LEFT: | |
|
3340 | if self.cursorpos: | |||
|
3341 | self.cursorpos -= 1 | |||
|
3342 | break | |||
|
3343 | else: | |||
|
3344 | curses.beep() | |||
|
3345 | elif c == curses.KEY_RIGHT: | |||
|
3346 | if self.cursorpos < len(self.keyboardinput): | |||
|
3347 | self.cursorpos += 1 | |||
|
3348 | break | |||
|
3349 | else: | |||
|
3350 | curses.beep() | |||
|
3351 | elif c in (curses.KEY_UP, curses.KEY_DOWN): # cancel | |||
3314 | self.mode = "default" |
|
3352 | self.mode = "default" | |
3315 |
|
|
3353 | break | |
3316 | level.moveto(level.curx, int(self.goto)) |
|
3354 | elif c == ord("\n"): | |
|
3355 | self.executekeyboardinput(self.mode) | |||
3317 | break |
|
3356 | break | |
3318 | elif c != -1: |
|
3357 | elif c != -1: | |
3319 |
|
|
3358 | try: | |
|
3359 | c = chr(c) | |||
|
3360 | except ValueError: | |||
|
3361 | curses.beep() | |||
|
3362 | else: | |||
|
3363 | if (self.mode == "goto" and not "0" <= c <= "9"): | |||
|
3364 | curses.beep() | |||
|
3365 | else: | |||
|
3366 | self.keyboardinput = self.keyboardinput[:self.cursorpos] + c + self.keyboardinput[self.cursorpos:] | |||
|
3367 | self.cursorpos += 1 | |||
|
3368 | break # Redisplay | |||
3320 | else: |
|
3369 | else: | |
3321 | # if no key is pressed slow down and beep again |
|
3370 | # if no key is pressed slow down and beep again | |
3322 | if c == -1: |
|
3371 | if c == -1: |
General Comments 0
You need to be logged in to leave comments.
Login now