diff options
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r-- | cmd2/cmd2.py | 141 |
1 files changed, 1 insertions, 140 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index ba2b6e8a..69a6c2aa 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -50,6 +50,7 @@ from . import utils from .argparse_completer import AutoCompleter, ACArgumentParser, ACTION_ARG_CHOICES from .clipboard import can_clip, get_paste_buffer, write_to_paste_buffer from .parsing import StatementParser, Statement, Macro, MacroArg +from .history import History, HistoryItem # Set up readline from .rl_utils import rl_type, RlType, rl_get_point, rl_set_prompt, vt100_support, rl_make_safe_prompt @@ -287,39 +288,6 @@ class EmptyStatement(Exception): pass -class HistoryItem(str): - """Class used to represent an item in the History list""" - listformat = ' {:>4} {}\n' - ex_listformat = ' Ex: {}\n' - - def __new__(cls, statement: Statement): - """Create a new instance of HistoryItem - - We must override __new__ because we are subclassing `str` which is - immutable and takes a different number of arguments as Statement. - """ - hi = super().__new__(cls, statement.raw) - hi.statement = statement - hi.idx = None - return hi - - @property - def expanded(self) -> str: - """Return the command as run which includes shortcuts and aliases resolved plus any changes made in hooks""" - return self.statement.expanded_command_line - - def pr(self, verbose: bool) -> str: - """Represent a HistoryItem in a pretty fashion suitable for printing. - - :return: pretty print string version of a HistoryItem - """ - ret_str = self.listformat.format(self.idx, str(self).rstrip()) - if verbose and self != self.expanded: - ret_str += self.ex_listformat.format(self.expanded.rstrip()) - - return ret_str - - class Cmd(cmd.Cmd): """An easy but powerful framework for writing line-oriented command interpreters. @@ -3810,113 +3778,6 @@ class Cmd(cmd.Cmd): self._cmdfinalization_hooks.append(func) -class History(list): - """ A list of HistoryItems that knows how to respond to user requests. """ - - # noinspection PyMethodMayBeStatic - def _zero_based_index(self, onebased: int) -> int: - """Convert a one-based index to a zero-based index.""" - result = onebased - if result > 0: - result -= 1 - return result - - def _to_index(self, raw: str) -> Optional[int]: - if raw: - result = self._zero_based_index(int(raw)) - else: - result = None - return result - - spanpattern = re.compile(r'^\s*(?P<start>-?\d+)?\s*(?P<separator>:|(\.{2,}))?\s*(?P<end>-?\d+)?\s*$') - - def span(self, raw: str) -> List[HistoryItem]: - """Parses the input string search for a span pattern and if if found, returns a slice from the History list. - - :param raw: string potentially containing a span of the forms a..b, a:b, a:, ..b - :return: slice from the History list - """ - if raw.lower() in ('*', '-', 'all'): - raw = ':' - results = self.spanpattern.search(raw) - if not results: - raise IndexError - if not results.group('separator'): - return [self[self._to_index(results.group('start'))]] - start = self._to_index(results.group('start')) or 0 # Ensure start is not None - end = self._to_index(results.group('end')) - reverse = False - if end is not None: - if end < start: - (start, end) = (end, start) - reverse = True - end += 1 - result = self[start:end] - if reverse: - result.reverse() - return result - - rangePattern = re.compile(r'^\s*(?P<start>[\d]+)?\s*-\s*(?P<end>[\d]+)?\s*$') - - def append(self, new: Statement) -> None: - """Append a HistoryItem to end of the History list - - :param new: command line to convert to HistoryItem and add to the end of the History list - """ - new = HistoryItem(new) - list.append(self, new) - new.idx = len(self) - - def get(self, getme: Optional[Union[int, str]]=None) -> List[HistoryItem]: - """Get an item or items from the History list using 1-based indexing. - - :param getme: optional item(s) to get (either an integer index or string to search for) - :return: list of HistoryItems matching the retrieval criteria - """ - if not getme: - return self - try: - getme = int(getme) - if getme < 0: - return self[:(-1 * getme)] - else: - return [self[getme - 1]] - except IndexError: - return [] - except ValueError: - range_result = self.rangePattern.search(getme) - if range_result: - start = range_result.group('start') or None - end = range_result.group('start') or None - if start: - start = int(start) - 1 - if end: - end = int(end) - return self[start:end] - - getme = getme.strip() - - if getme.startswith(r'/') and getme.endswith(r'/'): - finder = re.compile(getme[1:-1], re.DOTALL | re.MULTILINE | re.IGNORECASE) - - def isin(hi): - """Listcomp filter function for doing a regular expression search of History. - - :param hi: HistoryItem - :return: bool - True if search matches - """ - return finder.search(hi) - else: - def isin(hi): - """Listcomp filter function for doing a case-insensitive string search of History. - - :param hi: HistoryItem - :return: bool - True if search matches - """ - return utils.norm_fold(getme) in utils.norm_fold(hi) - return [itm for itm in self if isin(itm)] - - class Statekeeper(object): """Class used to save and restore state during load and py commands as well as when redirecting output or pipes.""" def __init__(self, obj: Any, attribs: Iterable) -> None: |