Show More
This diff has been collapsed as it changes many lines, (548 lines changed) Show them Hide them | |||
@@ -421,6 +421,9 b' class ichain(Pipe):' | |||
|
421 | 421 | |
|
422 | 422 | |
|
423 | 423 | class ifile(object): |
|
424 | """ | |
|
425 | file (or directory) object. | |
|
426 | """ | |
|
424 | 427 | __slots__ = ("name", "_abspath", "_realpath", "_stat", "_lstat") |
|
425 | 428 | |
|
426 | 429 | def __init__(self, name): |
@@ -674,6 +677,9 b' class iparentdir(ifile):' | |||
|
674 | 677 | |
|
675 | 678 | |
|
676 | 679 | class ils(Table): |
|
680 | """ | |
|
681 | This ``Table`` lists a directory. | |
|
682 | """ | |
|
677 | 683 | def __init__(self, base=os.curdir): |
|
678 | 684 | self.base = os.path.expanduser(base) |
|
679 | 685 | |
@@ -691,6 +697,10 b' class ils(Table):' | |||
|
691 | 697 | |
|
692 | 698 | |
|
693 | 699 | class iglob(Table): |
|
700 | """ | |
|
701 | This `Table`` lists all files and directories matching a specified pattern. | |
|
702 | (See ``glob.glob()`` for more info.) | |
|
703 | """ | |
|
694 | 704 | def __init__(self, glob): |
|
695 | 705 | self.glob = glob |
|
696 | 706 | |
@@ -709,6 +719,10 b' class iglob(Table):' | |||
|
709 | 719 | |
|
710 | 720 | |
|
711 | 721 | class iwalk(Table): |
|
722 | """ | |
|
723 | This `Table`` lists all files and directories in a directory and it's | |
|
724 | subdirectory. | |
|
725 | """ | |
|
712 | 726 | def __init__(self, base=os.curdir, dirs=True, files=True): |
|
713 | 727 | self.base = os.path.expanduser(base) |
|
714 | 728 | self.dirs = dirs |
@@ -734,6 +748,10 b' class iwalk(Table):' | |||
|
734 | 748 | |
|
735 | 749 | |
|
736 | 750 | class ipwdentry(object): |
|
751 | """ | |
|
752 | ``ipwdentry`` objects encapsulate entries in the Unix user account and | |
|
753 | password database. | |
|
754 | """ | |
|
737 | 755 | def __init__(self, id): |
|
738 | 756 | self._id = id |
|
739 | 757 | self._entry = None |
@@ -793,6 +811,10 b' class ipwdentry(object):' | |||
|
793 | 811 | |
|
794 | 812 | |
|
795 | 813 | class ipwd(Table): |
|
814 | """ | |
|
815 | This ``Table`` lists all entries in the Unix user account and password | |
|
816 | database. | |
|
817 | """ | |
|
796 | 818 | def __iter__(self): |
|
797 | 819 | for entry in pwd.getpwall(): |
|
798 | 820 | yield ipwdentry(entry.pw_name) |
@@ -804,6 +826,9 b' class ipwd(Table):' | |||
|
804 | 826 | |
|
805 | 827 | |
|
806 | 828 | class igrpentry(object): |
|
829 | """ | |
|
830 | ``igrpentry`` objects encapsulate entries in the Unix group database. | |
|
831 | """ | |
|
807 | 832 | def __init__(self, id): |
|
808 | 833 | self._id = id |
|
809 | 834 | self._entry = None |
@@ -856,6 +881,9 b' class igrpentry(object):' | |||
|
856 | 881 | |
|
857 | 882 | |
|
858 | 883 | class igrp(Table): |
|
884 | """ | |
|
885 | This ``Table`` lists all entries in the Unix group database. | |
|
886 | """ | |
|
859 | 887 | def __xiter__(self, mode): |
|
860 | 888 | for entry in grp.getgrall(): |
|
861 | 889 | yield igrpentry(entry.gr_name) |
@@ -906,6 +934,10 b' class FieldTable(Table, list):' | |||
|
906 | 934 | |
|
907 | 935 | |
|
908 | 936 | class ienv(Table): |
|
937 | """ | |
|
938 | This ``Table`` lists environment variables. | |
|
939 | """ | |
|
940 | ||
|
909 | 941 | def __xiter__(self, mode): |
|
910 | 942 | fields = ("key", "value") |
|
911 | 943 | for (key, value) in os.environ.iteritems(): |
@@ -918,7 +950,15 b' class ienv(Table):' | |||
|
918 | 950 | |
|
919 | 951 | |
|
920 | 952 | class icsv(Pipe): |
|
953 | """ | |
|
954 | This ``Pipe`` lists turn the input (with must be a pipe outputting lines | |
|
955 | or an ``ifile``) into lines of CVS columns. | |
|
956 | """ | |
|
921 | 957 | def __init__(self, **csvargs): |
|
958 | """ | |
|
959 | Create an ``icsv`` object. ``cvsargs`` will be passed through as | |
|
960 | keyword arguments to ``cvs.reader()``. | |
|
961 | """ | |
|
922 | 962 | self.csvargs = csvargs |
|
923 | 963 | |
|
924 | 964 | def __xiter__(self, mode): |
@@ -947,6 +987,10 b' class icsv(Pipe):' | |||
|
947 | 987 | |
|
948 | 988 | |
|
949 | 989 | class ix(Table): |
|
990 | """ | |
|
991 | This ``Table`` executes a system command and lists its output as lines | |
|
992 | (similar to ``os.popen()``). | |
|
993 | """ | |
|
950 | 994 | def __init__(self, cmd): |
|
951 | 995 | self.cmd = cmd |
|
952 | 996 | self._pipe = None |
@@ -974,7 +1018,16 b' class ix(Table):' | |||
|
974 | 1018 | |
|
975 | 1019 | |
|
976 | 1020 | class ifilter(Pipe): |
|
1021 | """ | |
|
1022 | This ``Pipe`` filters an input pipe. Only objects where an expression | |
|
1023 | evaluates to true (and doesn't raise an exception) are listed. | |
|
1024 | """ | |
|
1025 | ||
|
977 | 1026 | def __init__(self, expr): |
|
1027 | """ | |
|
1028 | Create an ``ifilter`` object. ``expr`` can be a callable or a string | |
|
1029 | containing an expression. | |
|
1030 | """ | |
|
978 | 1031 | self.expr = expr |
|
979 | 1032 | |
|
980 | 1033 | def __xiter__(self, mode): |
@@ -1015,7 +1068,15 b' class ifilter(Pipe):' | |||
|
1015 | 1068 | |
|
1016 | 1069 | |
|
1017 | 1070 | class ieval(Pipe): |
|
1071 | """ | |
|
1072 | This ``Pipe`` evaluates an expression for each object in the input pipe. | |
|
1073 | """ | |
|
1074 | ||
|
1018 | 1075 | def __init__(self, expr): |
|
1076 | """ | |
|
1077 | Create an ``ieval`` object. ``expr`` can be a callable or a string | |
|
1078 | containing an expression. | |
|
1079 | """ | |
|
1019 | 1080 | self.expr = expr |
|
1020 | 1081 | |
|
1021 | 1082 | def __xiter__(self, mode): |
@@ -1061,7 +1122,16 b' class ienum(Pipe):' | |||
|
1061 | 1122 | |
|
1062 | 1123 | |
|
1063 | 1124 | class isort(Pipe): |
|
1125 | """ | |
|
1126 | This ``Pipe`` sorts its input pipe. | |
|
1127 | """ | |
|
1128 | ||
|
1064 | 1129 | def __init__(self, key, reverse=False): |
|
1130 | """ | |
|
1131 | Create an ``isort`` object. ``key`` can be a callable or a string | |
|
1132 | containing an expression. If ``reverse`` is true the sort order will | |
|
1133 | be reversed. | |
|
1134 | """ | |
|
1065 | 1135 | self.key = key |
|
1066 | 1136 | self.reverse = reverse |
|
1067 | 1137 | |
@@ -1349,6 +1419,12 b' Move the cursor to the first column.' | |||
|
1349 | 1419 | end |
|
1350 | 1420 | Move the cursor to the last column. |
|
1351 | 1421 | |
|
1422 | prevattr | |
|
1423 | Move the cursor one attribute column to the left. | |
|
1424 | ||
|
1425 | nextattr | |
|
1426 | Move the cursor one attribute column to the right. | |
|
1427 | ||
|
1352 | 1428 | pick |
|
1353 | 1429 | 'Pick' the object under the cursor (i.e. the row the cursor is on). This leaves |
|
1354 | 1430 | the browser and returns the picked object to the caller. (In IPython this object |
@@ -1393,6 +1469,9 b' Show a detail view of the object under the cursor. This shows the name, type,' | |||
|
1393 | 1469 | doc string and value of the object attributes (and it might show more attributes |
|
1394 | 1470 | than in the list view, depending on the object). |
|
1395 | 1471 | |
|
1472 | detailattr | |
|
1473 | Show a detail view of the attribute under the cursor. | |
|
1474 | ||
|
1396 | 1475 | markrange |
|
1397 | 1476 | Mark all objects from the last marked object before the current cursor position |
|
1398 | 1477 | to the cursor position. |
@@ -1502,21 +1581,50 b' if curses is not None:' | |||
|
1502 | 1581 | self.browser = browser |
|
1503 | 1582 | self.input = input |
|
1504 | 1583 | self.header = xrepr(input, "header") |
|
1505 |
|
|
|
1506 |
self. |
|
|
1584 | # iterator for the input | |
|
1585 | self.iterator = iterator | |
|
1586 | ||
|
1587 | # is the iterator exhausted? | |
|
1588 | self.exhausted = False | |
|
1589 | ||
|
1590 | # attributes to be display (autodetected if empty) | |
|
1507 | 1591 | self.attrs = attrs |
|
1592 | ||
|
1593 | # fetched items (+ marked flag) | |
|
1508 | 1594 | self.items = deque() |
|
1509 | self.marked = 0 # Number of marked objects | |
|
1510 | self.cury = 0 # Vertical cursor position | |
|
1511 | self.curx = 0 # Horizontal cursor position | |
|
1512 | self.datastarty = 0 # Index of first data line | |
|
1513 | self.datastartx = 0 # Index of first data column | |
|
1514 | self.mainsizey = mainsizey # height of the data display area | |
|
1515 | self.mainsizex = 0 # width of the data display area | |
|
1516 | self.numbersizex = 0 # Size of number at the left edge of the screen | |
|
1517 | self.displayattrs = [] # Attribute names to display (in this order) | |
|
1518 | self.displayattr = _default # Name of attribute under the cursor | |
|
1519 | self.colwidths = {} # Maps attribute names to column widths | |
|
1595 | ||
|
1596 | # Number of marked objects | |
|
1597 | self.marked = 0 | |
|
1598 | ||
|
1599 | # Vertical cursor position | |
|
1600 | self.cury = 0 | |
|
1601 | ||
|
1602 | # Horizontal cursor position | |
|
1603 | self.curx = 0 | |
|
1604 | ||
|
1605 | # Index of first data column | |
|
1606 | self.datastartx = 0 | |
|
1607 | ||
|
1608 | # Index of first data line | |
|
1609 | self.datastarty = 0 | |
|
1610 | ||
|
1611 | # height of the data display area | |
|
1612 | self.mainsizey = mainsizey | |
|
1613 | ||
|
1614 | # width of the data display area (changes when scrolling) | |
|
1615 | self.mainsizex = 0 | |
|
1616 | ||
|
1617 | # Size of row number (changes when scrolling) | |
|
1618 | self.numbersizex = 0 | |
|
1619 | ||
|
1620 | # Attribute names to display (in this order) | |
|
1621 | self.displayattrs = [] | |
|
1622 | ||
|
1623 | # index and name of attribute under the cursor | |
|
1624 | self.displayattr = (None, _default) | |
|
1625 | ||
|
1626 | # Maps attribute names to column widths | |
|
1627 | self.colwidths = {} | |
|
1520 | 1628 | |
|
1521 | 1629 | self.fetch(mainsizey) |
|
1522 | 1630 | self.calcdisplayattrs() |
@@ -1603,24 +1711,26 b' if curses is not None:' | |||
|
1603 | 1711 | # Find out on which attribute the cursor is on and store this |
|
1604 | 1712 | # information in ``self.displayattr``. |
|
1605 | 1713 | pos = 0 |
|
1606 | for attrname in self.displayattrs: | |
|
1714 | for (i, attrname) in enumerate(self.displayattrs): | |
|
1607 | 1715 | if pos+self.colwidths[attrname] >= self.curx: |
|
1608 | self.displayattr = attrname | |
|
1716 | self.displayattr = (i, attrname) | |
|
1609 | 1717 | break |
|
1610 | 1718 | pos += self.colwidths[attrname]+1 |
|
1611 | 1719 | else: |
|
1612 | self.displayattr = None | |
|
1720 | self.displayattr = (None, _default) | |
|
1613 | 1721 | |
|
1614 | 1722 | def moveto(self, x, y, refresh=False): |
|
1615 | 1723 | # Move the cursor to the position ``(x,y)`` (in data coordinates, |
|
1616 | 1724 | # not in screen coordinates). If ``refresh`` is true, all cached |
|
1617 | 1725 | # values will be recalculated (e.g. because the list has been |
|
1618 |
# resorted |
|
|
1726 | # resorted, so screen positions etc. are no longer valid). | |
|
1619 | 1727 | olddatastarty = self.datastarty |
|
1620 | 1728 | oldx = self.curx |
|
1621 | 1729 | oldy = self.cury |
|
1622 | 1730 | x = int(x+0.5) |
|
1623 | 1731 | y = int(y+0.5) |
|
1732 | newx = x # remember where we wanted to move | |
|
1733 | newy = y # remember where we wanted to move | |
|
1624 | 1734 | |
|
1625 | 1735 | scrollbordery = min(self.browser.scrollbordery, self.mainsizey//2) |
|
1626 | 1736 | scrollborderx = min(self.browser.scrollborderx, self.mainsizex//2) |
@@ -1693,11 +1803,8 b' if curses is not None:' | |||
|
1693 | 1803 | self.datastartx = max(0, min(x-self.mainsizex+scrollborderx+1, |
|
1694 | 1804 | self.datasizex-self.mainsizex)) |
|
1695 | 1805 | |
|
1696 | if x == oldx and y == oldy: # couldn't move | |
|
1697 |
|
|
|
1698 | curses.beep() | |
|
1699 | # don't beep again (as long as the same key is pressed) | |
|
1700 | self.browser._dobeep = False | |
|
1806 | if x == oldx and y == oldy and (x != newx or y != newy): # couldn't move | |
|
1807 | self.browser.beep() | |
|
1701 | 1808 | else: |
|
1702 | 1809 | self.curx = x |
|
1703 | 1810 | self.cury = y |
@@ -1805,6 +1912,8 b' if curses is not None:' | |||
|
1805 | 1912 | curses.KEY_RIGHT: "right", |
|
1806 | 1913 | curses.KEY_HOME: "home", |
|
1807 | 1914 | curses.KEY_END: "end", |
|
1915 | ord("<"): "prevattr", | |
|
1916 | ord(">"): "nextattr", | |
|
1808 | 1917 | ord("p"): "pick", |
|
1809 | 1918 | ord("P"): "pickattr", |
|
1810 | 1919 | ord("C"): "pickallattrs", |
@@ -1820,6 +1929,7 b' if curses is not None:' | |||
|
1820 | 1929 | ord("e"): "enter", |
|
1821 | 1930 | ord("E"): "enterattr", |
|
1822 | 1931 | ord("d"): "detail", |
|
1932 | ord("D"): "detailattr", | |
|
1823 | 1933 | ord(" "): "tooglemark", |
|
1824 | 1934 | ord("r"): "markrange", |
|
1825 | 1935 | ord("v"): "sortattrasc", |
@@ -1863,6 +1973,9 b' if curses is not None:' | |||
|
1863 | 1973 | # report in the footer line (error, executed command etc.) |
|
1864 | 1974 | self._report = None |
|
1865 | 1975 | |
|
1976 | # value to be returned to the caller (set by commands) | |
|
1977 | self.returnvalue = None | |
|
1978 | ||
|
1866 | 1979 | def nextstepx(self, step): |
|
1867 | 1980 | """ |
|
1868 | 1981 | Accelerate horizontally. |
@@ -2013,6 +2126,258 b' if curses is not None:' | |||
|
2013 | 2126 | return name |
|
2014 | 2127 | return str(keycode) |
|
2015 | 2128 | |
|
2129 | def beep(self, force=False): | |
|
2130 | if force or self._dobeep: | |
|
2131 | curses.beep() | |
|
2132 | # don't beep again (as long as the same key is pressed) | |
|
2133 | self._dobeep = False | |
|
2134 | ||
|
2135 | def cmd_quit(self): | |
|
2136 | self.returnvalue = None | |
|
2137 | return True | |
|
2138 | ||
|
2139 | def cmd_up(self): | |
|
2140 | level = self.levels[-1] | |
|
2141 | self.report("up") | |
|
2142 | level.moveto(level.curx, level.cury-self.stepy) | |
|
2143 | ||
|
2144 | def cmd_down(self): | |
|
2145 | level = self.levels[-1] | |
|
2146 | self.report("down") | |
|
2147 | level.moveto(level.curx, level.cury+self.stepy) | |
|
2148 | ||
|
2149 | def cmd_pageup(self): | |
|
2150 | level = self.levels[-1] | |
|
2151 | self.report("page up") | |
|
2152 | level.moveto(level.curx, level.cury-level.mainsizey+self.pageoverlapy) | |
|
2153 | ||
|
2154 | def cmd_pagedown(self): | |
|
2155 | level = self.levels[-1] | |
|
2156 | self.report("page down") | |
|
2157 | level.moveto(level.curx, level.cury+level.mainsizey-self.pageoverlapy) | |
|
2158 | ||
|
2159 | def cmd_left(self): | |
|
2160 | level = self.levels[-1] | |
|
2161 | self.report("left") | |
|
2162 | level.moveto(level.curx-self.stepx, level.cury) | |
|
2163 | ||
|
2164 | def cmd_right(self): | |
|
2165 | level = self.levels[-1] | |
|
2166 | self.report("right") | |
|
2167 | level.moveto(level.curx+self.stepx, level.cury) | |
|
2168 | ||
|
2169 | def cmd_home(self): | |
|
2170 | level = self.levels[-1] | |
|
2171 | self.report("home") | |
|
2172 | level.moveto(0, level.cury) | |
|
2173 | ||
|
2174 | def cmd_end(self): | |
|
2175 | level = self.levels[-1] | |
|
2176 | self.report("end") | |
|
2177 | level.moveto(level.datasizex+level.mainsizey-self.pageoverlapx, level.cury) | |
|
2178 | ||
|
2179 | def cmd_prevattr(self): | |
|
2180 | level = self.levels[-1] | |
|
2181 | if level.displayattr[0] is None or level.displayattr[0] == 0: | |
|
2182 | self.beep() | |
|
2183 | else: | |
|
2184 | self.report("prevattr") | |
|
2185 | pos = 0 | |
|
2186 | for (i, attrname) in enumerate(level.displayattrs): | |
|
2187 | if i == level.displayattr[0]-1: | |
|
2188 | break | |
|
2189 | pos += level.colwidths[attrname] + 1 | |
|
2190 | level.moveto(pos, level.cury) | |
|
2191 | ||
|
2192 | def cmd_nextattr(self): | |
|
2193 | level = self.levels[-1] | |
|
2194 | if level.displayattr[0] is None or level.displayattr[0] == len(level.displayattrs)-1: | |
|
2195 | self.beep() | |
|
2196 | else: | |
|
2197 | self.report("nextattr") | |
|
2198 | pos = 0 | |
|
2199 | for (i, attrname) in enumerate(level.displayattrs): | |
|
2200 | if i == level.displayattr[0]+1: | |
|
2201 | break | |
|
2202 | pos += level.colwidths[attrname] + 1 | |
|
2203 | level.moveto(pos, level.cury) | |
|
2204 | ||
|
2205 | def cmd_pick(self): | |
|
2206 | level = self.levels[-1] | |
|
2207 | self.returnvalue = level.items[level.cury].item | |
|
2208 | return True | |
|
2209 | ||
|
2210 | def cmd_pickattr(self): | |
|
2211 | level = self.levels[-1] | |
|
2212 | attrname = level.displayattr[1] | |
|
2213 | if attrname is _default: | |
|
2214 | curses.beep() | |
|
2215 | self.report(AttributeError(_attrname(attrname))) | |
|
2216 | return | |
|
2217 | attr = _getattr(level.items[level.cury].item, attrname) | |
|
2218 | if attr is _default: | |
|
2219 | curses.beep() | |
|
2220 | self.report(AttributeError(_attrname(attrname))) | |
|
2221 | else: | |
|
2222 | self.returnvalue = attr | |
|
2223 | return True | |
|
2224 | ||
|
2225 | def cmd_pickallattrs(self): | |
|
2226 | level = self.levels[-1] | |
|
2227 | attrname = level.displayattr[1] | |
|
2228 | if attrname is _default: | |
|
2229 | curses.beep() | |
|
2230 | self.report(AttributeError(_attrname(attrname))) | |
|
2231 | return | |
|
2232 | result = [] | |
|
2233 | for cache in level.items: | |
|
2234 | attr = _getattr(cache.item, attrname) | |
|
2235 | if attr is not _default: | |
|
2236 | result.append(attr) | |
|
2237 | self.returnvalue = result | |
|
2238 | return True | |
|
2239 | ||
|
2240 | def cmd_pickmarked(self): | |
|
2241 | level = self.levels[-1] | |
|
2242 | self.returnvalue = [cache.item for cache in level.items if cache.marked] | |
|
2243 | return True | |
|
2244 | ||
|
2245 | def cmd_pickmarkedattr(self): | |
|
2246 | level = self.levels[-1] | |
|
2247 | attrname = level.displayattr[1] | |
|
2248 | if attrname is _default: | |
|
2249 | curses.beep() | |
|
2250 | self.report(AttributeError(_attrname(attrname))) | |
|
2251 | return | |
|
2252 | result = [] | |
|
2253 | for cache in level.items: | |
|
2254 | if cache.marked: | |
|
2255 | attr = _getattr(cache.item, attrname) | |
|
2256 | if attr is not _default: | |
|
2257 | result.append(attr) | |
|
2258 | self.returnvalue = result | |
|
2259 | return True | |
|
2260 | ||
|
2261 | def cmd_markrange(self): | |
|
2262 | level = self.levels[-1] | |
|
2263 | self.report("markrange") | |
|
2264 | start = None | |
|
2265 | if level.items: | |
|
2266 | for i in xrange(level.cury, -1, -1): | |
|
2267 | if level.items[i].marked: | |
|
2268 | start = i | |
|
2269 | break | |
|
2270 | if start is None: | |
|
2271 | self.report(CommandError("no mark before cursor")) | |
|
2272 | curses.beep() | |
|
2273 | else: | |
|
2274 | for i in xrange(start, level.cury+1): | |
|
2275 | cache = level.items[i] | |
|
2276 | if not cache.marked: | |
|
2277 | cache.marked = True | |
|
2278 | level.marked += 1 | |
|
2279 | ||
|
2280 | def cmd_enterdefault(self): | |
|
2281 | level = self.levels[-1] | |
|
2282 | self.report("entering object (default mode)...") | |
|
2283 | self.enter(level.items[level.cury].item, "default") | |
|
2284 | ||
|
2285 | def cmd_leave(self): | |
|
2286 | self.report("leave") | |
|
2287 | if len(self.levels) > 1: | |
|
2288 | self._calcheaderlines(len(self.levels)-1) | |
|
2289 | self.levels.pop(-1) | |
|
2290 | else: | |
|
2291 | self.report(CommandError("This is the last level")) | |
|
2292 | curses.beep() | |
|
2293 | ||
|
2294 | def cmd_enter(self): | |
|
2295 | level = self.levels[-1] | |
|
2296 | self.report("entering object...") | |
|
2297 | self.enter(level.items[level.cury].item, None) | |
|
2298 | ||
|
2299 | def cmd_enterattr(self): | |
|
2300 | level = self.levels[-1] | |
|
2301 | attrname = level.displayattr[1] | |
|
2302 | if attrname is _default: | |
|
2303 | curses.beep() | |
|
2304 | self.report(AttributeError(_attrname(attrname))) | |
|
2305 | return | |
|
2306 | attr = _getattr(level.items[level.cury].item, attrname) | |
|
2307 | if attr is _default: | |
|
2308 | self.report(AttributeError(_attrname(attrname))) | |
|
2309 | else: | |
|
2310 | self.report("entering object attribute %s..." % _attrname(attrname)) | |
|
2311 | self.enter(attr, None) | |
|
2312 | ||
|
2313 | def cmd_detail(self): | |
|
2314 | level = self.levels[-1] | |
|
2315 | self.report("entering detail view for object...") | |
|
2316 | self.enter(level.items[level.cury].item, "detail") | |
|
2317 | ||
|
2318 | def cmd_detailattr(self): | |
|
2319 | level = self.levels[-1] | |
|
2320 | attrname = level.displayattr[1] | |
|
2321 | if attrname is _default: | |
|
2322 | curses.beep() | |
|
2323 | self.report(AttributeError(_attrname(attrname))) | |
|
2324 | return | |
|
2325 | attr = _getattr(level.items[level.cury].item, attrname) | |
|
2326 | if attr is _default: | |
|
2327 | self.report(AttributeError(_attrname(attrname))) | |
|
2328 | else: | |
|
2329 | self.report("entering detail view for attribute...") | |
|
2330 | self.enter(attr, "detail") | |
|
2331 | ||
|
2332 | def cmd_tooglemark(self): | |
|
2333 | level = self.levels[-1] | |
|
2334 | self.report("toggle mark") | |
|
2335 | try: | |
|
2336 | item = level.items[level.cury] | |
|
2337 | except IndexError: # no items? | |
|
2338 | pass | |
|
2339 | else: | |
|
2340 | if item.marked: | |
|
2341 | item.marked = False | |
|
2342 | level.marked -= 1 | |
|
2343 | else: | |
|
2344 | item.marked = True | |
|
2345 | level.marked += 1 | |
|
2346 | ||
|
2347 | def cmd_sortattrasc(self): | |
|
2348 | level = self.levels[-1] | |
|
2349 | attrname = level.displayattr[1] | |
|
2350 | if attrname is _default: | |
|
2351 | curses.beep() | |
|
2352 | self.report(AttributeError(_attrname(attrname))) | |
|
2353 | return | |
|
2354 | self.report("sort by %s (ascending)" % _attrname(attrname)) | |
|
2355 | def key(item): | |
|
2356 | try: | |
|
2357 | return _getattr(item, attrname, None) | |
|
2358 | except (KeyboardInterrupt, SystemExit): | |
|
2359 | raise | |
|
2360 | except Exception: | |
|
2361 | return None | |
|
2362 | level.sort(key) | |
|
2363 | ||
|
2364 | def cmd_sortattrdesc(self): | |
|
2365 | level = self.levels[-1] | |
|
2366 | attrname = level.displayattr[1] | |
|
2367 | if attrname is _default: | |
|
2368 | curses.beep() | |
|
2369 | self.report(AttributeError(_attrname(attrname))) | |
|
2370 | return | |
|
2371 | self.report("sort by %s (descending)" % _attrname(attrname)) | |
|
2372 | def key(item): | |
|
2373 | try: | |
|
2374 | return _getattr(item, attrname, None) | |
|
2375 | except (KeyboardInterrupt, SystemExit): | |
|
2376 | raise | |
|
2377 | except Exception: | |
|
2378 | return None | |
|
2379 | level.sort(key, reverse=True) | |
|
2380 | ||
|
2016 | 2381 | def cmd_help(self): |
|
2017 | 2382 | """ |
|
2018 | 2383 | The help command |
@@ -2087,7 +2452,7 b' if curses is not None:' | |||
|
2087 | 2452 | strattrname = _attrname(attrname) |
|
2088 | 2453 | cwidth = level.colwidths[attrname] |
|
2089 | 2454 | header = strattrname.ljust(cwidth) |
|
2090 | if attrname == level.displayattr: | |
|
2455 | if attrname == level.displayattr[1]: | |
|
2091 | 2456 | style = self.style_colheaderhere |
|
2092 | 2457 | else: |
|
2093 | 2458 | style = self.style_colheader |
@@ -2162,8 +2527,12 b' if curses is not None:' | |||
|
2162 | 2527 | scr.addstr(self.scrsizey-footery, self.scrsizex-len(helpmsg)-1, helpmsg, self.getstyle(self.style_footer)) |
|
2163 | 2528 | |
|
2164 | 2529 | msg = "%d%s objects (%d marked)" % (len(level.items), flag, level.marked) |
|
2530 | attrname = level.displayattr[1] | |
|
2165 | 2531 | try: |
|
2166 | msg += ": %s > %s" % (xrepr(level.items[level.cury].item, "footer"), _attrname(level.displayattr)) | |
|
2532 | if attrname is not _default: | |
|
2533 | msg += ": %s > %s" % (xrepr(level.items[level.cury].item, "footer"), _attrname(attrname)) | |
|
2534 | else: | |
|
2535 | msg += ": %s > no attribute" % xrepr(level.items[level.cury].item, "footer") | |
|
2167 | 2536 | except IndexError: # empty |
|
2168 | 2537 | pass |
|
2169 | 2538 | self.addstr(self.scrsizey-footery, 1, 1, self.scrsizex-len(helpmsg)-1, msg, self.style_footer) |
@@ -2214,124 +2583,21 b' if curses is not None:' | |||
|
2214 | 2583 | self.stepx = 1. |
|
2215 | 2584 | self.stepy = 1. |
|
2216 | 2585 | self._dobeep = True |
|
2217 | cmd = self.keymap.get(c, None) | |
|
2218 |
if cmd |
|
|
2219 |
|
|
|
2220 | elif cmd == "up": | |
|
2221 |
self. |
|
|
2222 | level.moveto(level.curx, level.cury-self.stepy) | |
|
2223 | elif cmd == "down": | |
|
2224 | self.report("down") | |
|
2225 | level.moveto(level.curx, level.cury+self.stepy) | |
|
2226 | elif cmd == "pageup": | |
|
2227 | self.report("page up") | |
|
2228 | level.moveto(level.curx, level.cury-level.mainsizey+self.pageoverlapy) | |
|
2229 | elif cmd == "pagedown": | |
|
2230 | self.report("page down") | |
|
2231 | level.moveto(level.curx, level.cury+level.mainsizey-self.pageoverlapy) | |
|
2232 | elif cmd == "left": | |
|
2233 | self.report("left") | |
|
2234 | level.moveto(level.curx-self.stepx, level.cury) | |
|
2235 | elif cmd == "right": | |
|
2236 | self.report("right") | |
|
2237 | level.moveto(level.curx+self.stepx, level.cury) | |
|
2238 | elif cmd == "home": | |
|
2239 | self.report("home") | |
|
2240 | level.moveto(0, level.cury) | |
|
2241 | elif cmd == "end": | |
|
2242 | self.report("end") | |
|
2243 | level.moveto(level.datasizex+level.mainsizey-self.pageoverlapx, level.cury) | |
|
2244 | elif cmd == "pick": | |
|
2245 | return level.items[level.cury].item | |
|
2246 | elif cmd == "pickattr": | |
|
2247 | attr = _getattr(level.items[level.cury].item, level.displayattr) | |
|
2248 | if attr is _default: | |
|
2249 | curses.beep() | |
|
2250 | self.report(AttributeError(_attrname(level.displayattr))) | |
|
2251 | else: | |
|
2252 | return attr | |
|
2253 | elif cmd == "pickallattrs": | |
|
2254 | result = [] | |
|
2255 | for cache in level.items: | |
|
2256 | attr = _getattr(cache.item, level.displayattr) | |
|
2257 | if attr is not _default: | |
|
2258 | result.append(attr) | |
|
2259 | return result | |
|
2260 | elif cmd == "pickmarked": | |
|
2261 | return [cache.item for cache in level.items if cache.marked] | |
|
2262 | elif cmd == "pickmarkedattr": | |
|
2263 | result = [] | |
|
2264 | for cache in level.items: | |
|
2265 | if cache.marked: | |
|
2266 | attr = _getattr(cache.item, level.displayattr) | |
|
2267 | if attr is not _default: | |
|
2268 | result.append(attr) | |
|
2269 | return result | |
|
2270 | elif cmd == "markrange": | |
|
2271 | self.report("markrange") | |
|
2272 | start = None | |
|
2273 | if level.items: | |
|
2274 | for i in xrange(level.cury, -1, -1): | |
|
2275 | if level.items[i].marked: | |
|
2276 | start = i | |
|
2277 | break | |
|
2278 | if start is None: | |
|
2279 | self.report(CommandError("no mark before cursor")) | |
|
2280 | curses.beep() | |
|
2281 | else: | |
|
2282 | for i in xrange(start, level.cury+1): | |
|
2283 | cache = level.items[i] | |
|
2284 | if not cache.marked: | |
|
2285 | cache.marked = True | |
|
2286 | level.marked += 1 | |
|
2287 | elif cmd == "enterdefault": | |
|
2288 | self.report("entering object (default mode)...") | |
|
2289 | self.enter(level.items[level.cury].item, "default") | |
|
2290 | elif cmd == "leave": | |
|
2291 | self.report("leave") | |
|
2292 | if len(self.levels) > 1: | |
|
2293 | self._calcheaderlines(len(self.levels)-1) | |
|
2294 | self.levels.pop(-1) | |
|
2295 | else: | |
|
2296 | self.report(CommandError("this is the last level")) | |
|
2297 | curses.beep() | |
|
2298 | elif cmd == "enter": | |
|
2299 | self.report("entering object...") | |
|
2300 | self.enter(level.items[level.cury].item, None) | |
|
2301 | elif cmd == "enterattr": | |
|
2302 | self.report("entering object attribute %s..." % _attrname(level.displayattr)) | |
|
2303 | self.enter(_getattr(level.items[level.cury].item, level.displayattr), None) | |
|
2304 | elif cmd == "detail": | |
|
2305 | self.enter(level.items[level.cury].item, "detail") | |
|
2306 | elif cmd == "tooglemark": | |
|
2307 | self.report("toggle mark") | |
|
2308 | try: | |
|
2309 | item = level.items[level.cury] | |
|
2310 | except IndexError: # no items? | |
|
2311 | pass | |
|
2312 | else: | |
|
2313 | if item.marked: | |
|
2314 | item.marked = False | |
|
2315 | level.marked -= 1 | |
|
2316 | else: | |
|
2317 | item.marked = True | |
|
2318 | level.marked += 1 | |
|
2319 | elif cmd == "sortattrasc": | |
|
2320 | self.report("sort by %s (ascending)" % _attrname(level.displayattr)) | |
|
2321 | def key(item): | |
|
2322 | return _getattr(item, level.displayattr) | |
|
2323 | level.sort(key) | |
|
2324 | elif cmd == "sortattrdesc": | |
|
2325 | self.report("sort by %s (descending)" % _attrname(level.displayattr)) | |
|
2326 | def key(item): | |
|
2327 | return _getattr(item, level.displayattr) | |
|
2328 | level.sort(key, reverse=True) | |
|
2329 | elif cmd == "help": | |
|
2330 | self.cmd_help() | |
|
2331 | elif cmd is not None: | |
|
2332 | self.report(UnknownCommandError("Unknown command %r" % (cmd,))) | |
|
2586 | cmdname = self.keymap.get(c, None) | |
|
2587 | if cmdname is None: | |
|
2588 | self.report( | |
|
2589 | UnassignedKeyError("Unassigned key %s" % | |
|
2590 | self.keylabel(c))) | |
|
2333 | 2591 | else: |
|
2334 | self.report(UnassignedKeyError("Unassigned key %s" % self.keylabel(c))) | |
|
2592 | cmdfunc = getattr(self, "cmd_%s" % cmdname, None) | |
|
2593 | if cmdfunc is None: | |
|
2594 | self.report( | |
|
2595 | UnknownCommandError("Unknown command %r" % | |
|
2596 | (cmdname,))) | |
|
2597 | elif cmdfunc(): | |
|
2598 | returnvalue = self.returnvalue | |
|
2599 | self.returnvalue = None | |
|
2600 | return returnvalue | |
|
2335 | 2601 | self.stepx = self.nextstepx(self.stepx) |
|
2336 | 2602 | self.stepy = self.nextstepy(self.stepy) |
|
2337 | 2603 | curses.flushinp() # get rid of type ahead |
General Comments 0
You need to be logged in to leave comments.
Login now