@@ -60,7 +60,17 @@ def pr(self, script=False, expanded=False, verbose=False) -> str:
6060
6161
6262class History (list ):
63- """ A list of HistoryItems that knows how to respond to user requests. """
63+ """A list of HistoryItems that knows how to respond to user requests.
64+
65+ Here are some key methods:
66+
67+ select() - parse user input and return a list of relevant history items
68+ str_search() - return a list of history items which contain the given string
69+ regex_search() - return a list of history items which match a given regex
70+ get() - return a single element of the list, using 1 based indexing
71+ span() - given a 1-based slice, return the appropriate list of history items
72+
73+ """
6474
6575 # noinspection PyMethodMayBeStatic
6676 def _zero_based_index (self , onebased : int ) -> int :
@@ -80,10 +90,30 @@ def _to_index(self, raw: str) -> Optional[int]:
8090 spanpattern = re .compile (r'^\s*(?P<start>-?\d+)?\s*(?P<separator>:|(\.{2,}))?\s*(?P<end>-?\d+)?\s*$' )
8191
8292 def span (self , raw : str ) -> List [HistoryItem ]:
83- """Parses the input string search for a span pattern and if if found, returns a slice from the History list.
93+ """Parses the input string and return a slice from the History list.
94+
95+ :param raw: string potentially containing a span
96+ :return: a list of HistoryItems
97+
98+ This method can accommodate input in any of these forms:
99+
100+ a
101+ -a
102+ a..b or a:b
103+ a.. or a:
104+ ..a or :a
105+ -a.. or -a:
106+ ..-a or :-a
107+
108+ Different from native python indexing and slicing of arrays, this method
109+ uses 1-based array numbering. Users who are not programmers can't grok
110+ 0 based numbering. Programmers can grok either. Which reminds me, there
111+ are only two hard problems in programming:
112+
113+ - naming
114+ - cache invalidation
115+ - off by one errors
84116
85- :param raw: string potentially containing a span of the forms a..b, a:b, a:, ..b
86- :return: slice from the History list
87117 """
88118 if raw .lower () in ('*' , '-' , 'all' ):
89119 raw = ':'
@@ -116,37 +146,30 @@ def append(self, new: Statement) -> None:
116146 list .append (self , new )
117147 new .idx = len (self )
118148
119- def get (self , getme : Optional [ Union [int , str ]] = None ) -> List [ HistoryItem ] :
120- """Get an item or items from the History list using 1-based indexing.
149+ def get (self , index : Union [int , str ]) -> HistoryItem :
150+ """Get item from the History list using 1-based indexing.
121151
122- :param getme : optional item(s) to get (either an integer index or string to search for )
123- :return: list of HistoryItems matching the retrieval criteria
152+ :param index : optional item to get (index as either integer or string)
153+ :return: a single HistoryItem
124154 """
125- if not getme :
126- return self
127- try :
128- getme = int (getme )
129- if getme < 0 :
130- return self [:(- 1 * getme )]
131- else :
132- return [self [getme - 1 ]]
133- except IndexError :
134- return []
135- except ValueError :
136- range_result = self .rangePattern .search (getme )
137- if range_result :
138- start = range_result .group ('start' ) or None
139- end = range_result .group ('start' ) or None
140- if start :
141- start = int (start ) - 1
142- if end :
143- end = int (end )
144- return self [start :end ]
145-
146- getme = getme .strip ()
147-
148- if getme .startswith (r'/' ) and getme .endswith (r'/' ):
149- finder = re .compile (getme [1 :- 1 ], re .DOTALL | re .MULTILINE | re .IGNORECASE )
155+ index = int (index )
156+ if index == 0 :
157+ raise IndexError
158+ elif index < 0 :
159+ return self [index ]
160+ else :
161+ return self [index - 1 ]
162+
163+
164+
165+ def str_search (self , search : str ) -> List [HistoryItem ]:
166+ pass
167+
168+ def regex_search (self , regex : str ) -> List [HistoryItem ]:
169+ regex = regex .strip ()
170+
171+ if regex .startswith (r'/' ) and regex .endswith (r'/' ):
172+ finder = re .compile (regex [1 :- 1 ], re .DOTALL | re .MULTILINE | re .IGNORECASE )
150173
151174 def isin (hi ):
152175 """Listcomp filter function for doing a regular expression search of History.
@@ -162,6 +185,6 @@ def isin(hi):
162185 :param hi: HistoryItem
163186 :return: bool - True if search matches
164187 """
165- srch = utils .norm_fold (getme )
188+ srch = utils .norm_fold (regex )
166189 return srch in utils .norm_fold (hi ) or srch in utils .norm_fold (hi .expanded )
167190 return [itm for itm in self if isin (itm )]
0 commit comments