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 | class ifile(object): |
|
423 | class ifile(object): | |
|
424 | """ | |||
|
425 | file (or directory) object. | |||
|
426 | """ | |||
424 | __slots__ = ("name", "_abspath", "_realpath", "_stat", "_lstat") |
|
427 | __slots__ = ("name", "_abspath", "_realpath", "_stat", "_lstat") | |
425 |
|
428 | |||
426 | def __init__(self, name): |
|
429 | def __init__(self, name): | |
@@ -674,6 +677,9 b' class iparentdir(ifile):' | |||||
674 |
|
677 | |||
675 |
|
678 | |||
676 | class ils(Table): |
|
679 | class ils(Table): | |
|
680 | """ | |||
|
681 | This ``Table`` lists a directory. | |||
|
682 | """ | |||
677 | def __init__(self, base=os.curdir): |
|
683 | def __init__(self, base=os.curdir): | |
678 | self.base = os.path.expanduser(base) |
|
684 | self.base = os.path.expanduser(base) | |
679 |
|
685 | |||
@@ -691,6 +697,10 b' class ils(Table):' | |||||
691 |
|
697 | |||
692 |
|
698 | |||
693 | class iglob(Table): |
|
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 | def __init__(self, glob): |
|
704 | def __init__(self, glob): | |
695 | self.glob = glob |
|
705 | self.glob = glob | |
696 |
|
706 | |||
@@ -709,6 +719,10 b' class iglob(Table):' | |||||
709 |
|
719 | |||
710 |
|
720 | |||
711 | class iwalk(Table): |
|
721 | class iwalk(Table): | |
|
722 | """ | |||
|
723 | This `Table`` lists all files and directories in a directory and it's | |||
|
724 | subdirectory. | |||
|
725 | """ | |||
712 | def __init__(self, base=os.curdir, dirs=True, files=True): |
|
726 | def __init__(self, base=os.curdir, dirs=True, files=True): | |
713 | self.base = os.path.expanduser(base) |
|
727 | self.base = os.path.expanduser(base) | |
714 | self.dirs = dirs |
|
728 | self.dirs = dirs | |
@@ -734,6 +748,10 b' class iwalk(Table):' | |||||
734 |
|
748 | |||
735 |
|
749 | |||
736 | class ipwdentry(object): |
|
750 | class ipwdentry(object): | |
|
751 | """ | |||
|
752 | ``ipwdentry`` objects encapsulate entries in the Unix user account and | |||
|
753 | password database. | |||
|
754 | """ | |||
737 | def __init__(self, id): |
|
755 | def __init__(self, id): | |
738 | self._id = id |
|
756 | self._id = id | |
739 | self._entry = None |
|
757 | self._entry = None | |
@@ -793,6 +811,10 b' class ipwdentry(object):' | |||||
793 |
|
811 | |||
794 |
|
812 | |||
795 | class ipwd(Table): |
|
813 | class ipwd(Table): | |
|
814 | """ | |||
|
815 | This ``Table`` lists all entries in the Unix user account and password | |||
|
816 | database. | |||
|
817 | """ | |||
796 | def __iter__(self): |
|
818 | def __iter__(self): | |
797 | for entry in pwd.getpwall(): |
|
819 | for entry in pwd.getpwall(): | |
798 | yield ipwdentry(entry.pw_name) |
|
820 | yield ipwdentry(entry.pw_name) | |
@@ -804,6 +826,9 b' class ipwd(Table):' | |||||
804 |
|
826 | |||
805 |
|
827 | |||
806 | class igrpentry(object): |
|
828 | class igrpentry(object): | |
|
829 | """ | |||
|
830 | ``igrpentry`` objects encapsulate entries in the Unix group database. | |||
|
831 | """ | |||
807 | def __init__(self, id): |
|
832 | def __init__(self, id): | |
808 | self._id = id |
|
833 | self._id = id | |
809 | self._entry = None |
|
834 | self._entry = None | |
@@ -856,6 +881,9 b' class igrpentry(object):' | |||||
856 |
|
881 | |||
857 |
|
882 | |||
858 | class igrp(Table): |
|
883 | class igrp(Table): | |
|
884 | """ | |||
|
885 | This ``Table`` lists all entries in the Unix group database. | |||
|
886 | """ | |||
859 | def __xiter__(self, mode): |
|
887 | def __xiter__(self, mode): | |
860 | for entry in grp.getgrall(): |
|
888 | for entry in grp.getgrall(): | |
861 | yield igrpentry(entry.gr_name) |
|
889 | yield igrpentry(entry.gr_name) | |
@@ -906,6 +934,10 b' class FieldTable(Table, list):' | |||||
906 |
|
934 | |||
907 |
|
935 | |||
908 | class ienv(Table): |
|
936 | class ienv(Table): | |
|
937 | """ | |||
|
938 | This ``Table`` lists environment variables. | |||
|
939 | """ | |||
|
940 | ||||
909 | def __xiter__(self, mode): |
|
941 | def __xiter__(self, mode): | |
910 | fields = ("key", "value") |
|
942 | fields = ("key", "value") | |
911 | for (key, value) in os.environ.iteritems(): |
|
943 | for (key, value) in os.environ.iteritems(): | |
@@ -918,7 +950,15 b' class ienv(Table):' | |||||
918 |
|
950 | |||
919 |
|
951 | |||
920 | class icsv(Pipe): |
|
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 | def __init__(self, **csvargs): |
|
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 | self.csvargs = csvargs |
|
962 | self.csvargs = csvargs | |
923 |
|
963 | |||
924 | def __xiter__(self, mode): |
|
964 | def __xiter__(self, mode): | |
@@ -947,6 +987,10 b' class icsv(Pipe):' | |||||
947 |
|
987 | |||
948 |
|
988 | |||
949 | class ix(Table): |
|
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 | def __init__(self, cmd): |
|
994 | def __init__(self, cmd): | |
951 | self.cmd = cmd |
|
995 | self.cmd = cmd | |
952 | self._pipe = None |
|
996 | self._pipe = None | |
@@ -974,7 +1018,16 b' class ix(Table):' | |||||
974 |
|
1018 | |||
975 |
|
1019 | |||
976 | class ifilter(Pipe): |
|
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 | def __init__(self, expr): |
|
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 | self.expr = expr |
|
1031 | self.expr = expr | |
979 |
|
1032 | |||
980 | def __xiter__(self, mode): |
|
1033 | def __xiter__(self, mode): | |
@@ -1015,7 +1068,15 b' class ifilter(Pipe):' | |||||
1015 |
|
1068 | |||
1016 |
|
1069 | |||
1017 | class ieval(Pipe): |
|
1070 | class ieval(Pipe): | |
|
1071 | """ | |||
|
1072 | This ``Pipe`` evaluates an expression for each object in the input pipe. | |||
|
1073 | """ | |||
|
1074 | ||||
1018 | def __init__(self, expr): |
|
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 | self.expr = expr |
|
1080 | self.expr = expr | |
1020 |
|
1081 | |||
1021 | def __xiter__(self, mode): |
|
1082 | def __xiter__(self, mode): | |
@@ -1061,7 +1122,16 b' class ienum(Pipe):' | |||||
1061 |
|
1122 | |||
1062 |
|
1123 | |||
1063 | class isort(Pipe): |
|
1124 | class isort(Pipe): | |
|
1125 | """ | |||
|
1126 | This ``Pipe`` sorts its input pipe. | |||
|
1127 | """ | |||
|
1128 | ||||
1064 | def __init__(self, key, reverse=False): |
|
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 | self.key = key |
|
1135 | self.key = key | |
1066 | self.reverse = reverse |
|
1136 | self.reverse = reverse | |
1067 |
|
1137 | |||
@@ -1349,6 +1419,12 b' Move the cursor to the first column.' | |||||
1349 | end |
|
1419 | end | |
1350 | Move the cursor to the last column. |
|
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 | pick |
|
1428 | pick | |
1353 | 'Pick' the object under the cursor (i.e. the row the cursor is on). This leaves |
|
1429 | 'Pick' the object under the cursor (i.e. the row the cursor is on). This leaves | |
1354 | the browser and returns the picked object to the caller. (In IPython this object |
|
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 | doc string and value of the object attributes (and it might show more attributes |
|
1469 | doc string and value of the object attributes (and it might show more attributes | |
1394 | than in the list view, depending on the object). |
|
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 | markrange |
|
1475 | markrange | |
1397 | Mark all objects from the last marked object before the current cursor position |
|
1476 | Mark all objects from the last marked object before the current cursor position | |
1398 | to the cursor position. |
|
1477 | to the cursor position. | |
@@ -1502,21 +1581,50 b' if curses is not None:' | |||||
1502 | self.browser = browser |
|
1581 | self.browser = browser | |
1503 | self.input = input |
|
1582 | self.input = input | |
1504 | self.header = xrepr(input, "header") |
|
1583 | self.header = xrepr(input, "header") | |
1505 |
|
|
1584 | # iterator for the input | |
1506 |
self. |
|
1585 | self.iterator = iterator | |
|
1586 | ||||
|
1587 | # is the iterator exhausted? | |||
|
1588 | self.exhausted = False | |||
|
1589 | ||||
|
1590 | # attributes to be display (autodetected if empty) | |||
1507 | self.attrs = attrs |
|
1591 | self.attrs = attrs | |
|
1592 | ||||
|
1593 | # fetched items (+ marked flag) | |||
1508 | self.items = deque() |
|
1594 | self.items = deque() | |
1509 | self.marked = 0 # Number of marked objects |
|
1595 | ||
1510 | self.cury = 0 # Vertical cursor position |
|
1596 | # Number of marked objects | |
1511 | self.curx = 0 # Horizontal cursor position |
|
1597 | self.marked = 0 | |
1512 | self.datastarty = 0 # Index of first data line |
|
1598 | ||
1513 | self.datastartx = 0 # Index of first data column |
|
1599 | # Vertical cursor position | |
1514 | self.mainsizey = mainsizey # height of the data display area |
|
1600 | self.cury = 0 | |
1515 | self.mainsizex = 0 # width of the data display area |
|
1601 | ||
1516 | self.numbersizex = 0 # Size of number at the left edge of the screen |
|
1602 | # Horizontal cursor position | |
1517 | self.displayattrs = [] # Attribute names to display (in this order) |
|
1603 | self.curx = 0 | |
1518 | self.displayattr = _default # Name of attribute under the cursor |
|
1604 | ||
1519 | self.colwidths = {} # Maps attribute names to column widths |
|
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 | self.fetch(mainsizey) |
|
1629 | self.fetch(mainsizey) | |
1522 | self.calcdisplayattrs() |
|
1630 | self.calcdisplayattrs() | |
@@ -1603,24 +1711,26 b' if curses is not None:' | |||||
1603 | # Find out on which attribute the cursor is on and store this |
|
1711 | # Find out on which attribute the cursor is on and store this | |
1604 | # information in ``self.displayattr``. |
|
1712 | # information in ``self.displayattr``. | |
1605 | pos = 0 |
|
1713 | pos = 0 | |
1606 | for attrname in self.displayattrs: |
|
1714 | for (i, attrname) in enumerate(self.displayattrs): | |
1607 | if pos+self.colwidths[attrname] >= self.curx: |
|
1715 | if pos+self.colwidths[attrname] >= self.curx: | |
1608 | self.displayattr = attrname |
|
1716 | self.displayattr = (i, attrname) | |
1609 | break |
|
1717 | break | |
1610 | pos += self.colwidths[attrname]+1 |
|
1718 | pos += self.colwidths[attrname]+1 | |
1611 | else: |
|
1719 | else: | |
1612 | self.displayattr = None |
|
1720 | self.displayattr = (None, _default) | |
1613 |
|
1721 | |||
1614 | def moveto(self, x, y, refresh=False): |
|
1722 | def moveto(self, x, y, refresh=False): | |
1615 | # Move the cursor to the position ``(x,y)`` (in data coordinates, |
|
1723 | # Move the cursor to the position ``(x,y)`` (in data coordinates, | |
1616 | # not in screen coordinates). If ``refresh`` is true, all cached |
|
1724 | # not in screen coordinates). If ``refresh`` is true, all cached | |
1617 | # values will be recalculated (e.g. because the list has been |
|
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 | olddatastarty = self.datastarty |
|
1727 | olddatastarty = self.datastarty | |
1620 | oldx = self.curx |
|
1728 | oldx = self.curx | |
1621 | oldy = self.cury |
|
1729 | oldy = self.cury | |
1622 | x = int(x+0.5) |
|
1730 | x = int(x+0.5) | |
1623 | y = int(y+0.5) |
|
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 | scrollbordery = min(self.browser.scrollbordery, self.mainsizey//2) |
|
1735 | scrollbordery = min(self.browser.scrollbordery, self.mainsizey//2) | |
1626 | scrollborderx = min(self.browser.scrollborderx, self.mainsizex//2) |
|
1736 | scrollborderx = min(self.browser.scrollborderx, self.mainsizex//2) | |
@@ -1693,11 +1803,8 b' if curses is not None:' | |||||
1693 | self.datastartx = max(0, min(x-self.mainsizex+scrollborderx+1, |
|
1803 | self.datastartx = max(0, min(x-self.mainsizex+scrollborderx+1, | |
1694 | self.datasizex-self.mainsizex)) |
|
1804 | self.datasizex-self.mainsizex)) | |
1695 |
|
1805 | |||
1696 | if x == oldx and y == oldy: # couldn't move |
|
1806 | if x == oldx and y == oldy and (x != newx or y != newy): # couldn't move | |
1697 |
|
|
1807 | self.browser.beep() | |
1698 | curses.beep() |
|
|||
1699 | # don't beep again (as long as the same key is pressed) |
|
|||
1700 | self.browser._dobeep = False |
|
|||
1701 | else: |
|
1808 | else: | |
1702 | self.curx = x |
|
1809 | self.curx = x | |
1703 | self.cury = y |
|
1810 | self.cury = y | |
@@ -1805,6 +1912,8 b' if curses is not None:' | |||||
1805 | curses.KEY_RIGHT: "right", |
|
1912 | curses.KEY_RIGHT: "right", | |
1806 | curses.KEY_HOME: "home", |
|
1913 | curses.KEY_HOME: "home", | |
1807 | curses.KEY_END: "end", |
|
1914 | curses.KEY_END: "end", | |
|
1915 | ord("<"): "prevattr", | |||
|
1916 | ord(">"): "nextattr", | |||
1808 | ord("p"): "pick", |
|
1917 | ord("p"): "pick", | |
1809 | ord("P"): "pickattr", |
|
1918 | ord("P"): "pickattr", | |
1810 | ord("C"): "pickallattrs", |
|
1919 | ord("C"): "pickallattrs", | |
@@ -1820,6 +1929,7 b' if curses is not None:' | |||||
1820 | ord("e"): "enter", |
|
1929 | ord("e"): "enter", | |
1821 | ord("E"): "enterattr", |
|
1930 | ord("E"): "enterattr", | |
1822 | ord("d"): "detail", |
|
1931 | ord("d"): "detail", | |
|
1932 | ord("D"): "detailattr", | |||
1823 | ord(" "): "tooglemark", |
|
1933 | ord(" "): "tooglemark", | |
1824 | ord("r"): "markrange", |
|
1934 | ord("r"): "markrange", | |
1825 | ord("v"): "sortattrasc", |
|
1935 | ord("v"): "sortattrasc", | |
@@ -1863,6 +1973,9 b' if curses is not None:' | |||||
1863 | # report in the footer line (error, executed command etc.) |
|
1973 | # report in the footer line (error, executed command etc.) | |
1864 | self._report = None |
|
1974 | self._report = None | |
1865 |
|
1975 | |||
|
1976 | # value to be returned to the caller (set by commands) | |||
|
1977 | self.returnvalue = None | |||
|
1978 | ||||
1866 | def nextstepx(self, step): |
|
1979 | def nextstepx(self, step): | |
1867 | """ |
|
1980 | """ | |
1868 | Accelerate horizontally. |
|
1981 | Accelerate horizontally. | |
@@ -2013,6 +2126,258 b' if curses is not None:' | |||||
2013 | return name |
|
2126 | return name | |
2014 | return str(keycode) |
|
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 | def cmd_help(self): |
|
2381 | def cmd_help(self): | |
2017 | """ |
|
2382 | """ | |
2018 | The help command |
|
2383 | The help command | |
@@ -2087,7 +2452,7 b' if curses is not None:' | |||||
2087 | strattrname = _attrname(attrname) |
|
2452 | strattrname = _attrname(attrname) | |
2088 | cwidth = level.colwidths[attrname] |
|
2453 | cwidth = level.colwidths[attrname] | |
2089 | header = strattrname.ljust(cwidth) |
|
2454 | header = strattrname.ljust(cwidth) | |
2090 | if attrname == level.displayattr: |
|
2455 | if attrname == level.displayattr[1]: | |
2091 | style = self.style_colheaderhere |
|
2456 | style = self.style_colheaderhere | |
2092 | else: |
|
2457 | else: | |
2093 | style = self.style_colheader |
|
2458 | style = self.style_colheader | |
@@ -2162,8 +2527,12 b' if curses is not None:' | |||||
2162 | scr.addstr(self.scrsizey-footery, self.scrsizex-len(helpmsg)-1, helpmsg, self.getstyle(self.style_footer)) |
|
2527 | scr.addstr(self.scrsizey-footery, self.scrsizex-len(helpmsg)-1, helpmsg, self.getstyle(self.style_footer)) | |
2163 |
|
2528 | |||
2164 | msg = "%d%s objects (%d marked)" % (len(level.items), flag, level.marked) |
|
2529 | msg = "%d%s objects (%d marked)" % (len(level.items), flag, level.marked) | |
|
2530 | attrname = level.displayattr[1] | |||
2165 | try: |
|
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 | except IndexError: # empty |
|
2536 | except IndexError: # empty | |
2168 | pass |
|
2537 | pass | |
2169 | self.addstr(self.scrsizey-footery, 1, 1, self.scrsizex-len(helpmsg)-1, msg, self.style_footer) |
|
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 | self.stepx = 1. |
|
2583 | self.stepx = 1. | |
2215 | self.stepy = 1. |
|
2584 | self.stepy = 1. | |
2216 | self._dobeep = True |
|
2585 | self._dobeep = True | |
2217 | cmd = self.keymap.get(c, None) |
|
2586 | cmdname = self.keymap.get(c, None) | |
2218 |
if cmd |
|
2587 | if cmdname is None: | |
2219 |
|
|
2588 | self.report( | |
2220 | elif cmd == "up": |
|
2589 | UnassignedKeyError("Unassigned key %s" % | |
2221 |
self. |
|
2590 | self.keylabel(c))) | |
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,))) |
|
|||
2333 | else: |
|
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 | self.stepx = self.nextstepx(self.stepx) |
|
2601 | self.stepx = self.nextstepx(self.stepx) | |
2336 | self.stepy = self.nextstepy(self.stepy) |
|
2602 | self.stepy = self.nextstepy(self.stepy) | |
2337 | curses.flushinp() # get rid of type ahead |
|
2603 | curses.flushinp() # get rid of type ahead |
General Comments 0
You need to be logged in to leave comments.
Login now