class_docstr: A simple console text pager.
  
  This pager requires the entire contents to be available. The contents are
  written one page of lines at a time. The prompt is written after each page of
  lines. A one character response is expected. See HELP_TEXT below for more
  info.
  
  The contents are written as is. For example, ANSI control codes will be in
  effect. This is different from pagers like more(1) which is ANSI control code
  agnostic and miscalculates line lengths, and less(1) which displays control
  character names by default.
  
  Attributes:
    _attr: The current ConsoleAttr handle.
    _clear: A string that clears the prompt when written to _out.
    _contents: The entire contents of the text lines to page.
    _height: The terminal height in characters.
    _out: The output stream, log.out (effectively) if None.
    _prompt: The page break prompt.
    _search_direction: The search direction command, n:forward, N:reverse.
    _search_pattern: The current forward/reverse search compiled RE.
    _width: The termonal width in characters.
class_docstr_tok: ["A","simple","console","text","pager",".","This","pager","requires","the","entire","contents","to","be","available",".","The","contents","are","written","one","page","of","lines","at","a","time",".","The","prompt","is","written","after","each","page","of","lines",".","A","one","character","response","is","expected",".","See","HELP_TEXT","below","for","more","info",".","The","contents","are","written","as","is",".","For","example",",","ANSI","control","codes","will","be","in","effect",".","This","is","different","from","pagers","like","more","(","1",")","which","is","ANSI","control","code","agnostic","and","miscalculates","line","lengths",",","and","less","(","1",")","which","displays","control","character","names","by","default",".","Attributes",":","_attr",":","The","current","ConsoleAttr","handle",".","_clear",":","A","string","that","clears","the","prompt","when","written","to","_out",".","_contents",":","The","entire","contents","of","the","text","lines","to","page",".","_height",":","The","terminal","height","in","characters",".","_out",":","The","output","stream",",","log.out","(","effectively",")","if","None",".","_prompt",":","The","page","break","prompt",".","_search_direction",":","The","search","direction","command",",","n",":","forward",",","N",":","reverse",".","_search_pattern",":","The","current","forward\/reverse","search","compiled","RE",".","_width",":","The","termonal","width","in","characters","."]
docstr: Run the pager.
docstr_tok: ["Run","the","pager","."]
code: def Run(self):
      """Run the pager."""
      # No paging if the contents are small enough.
      if len(self._lines) <= self._height:
          self._Write(self._contents)
          return
  
      # We will not always reset previous values.
      reset_prev_values = True
      # Save room for the prompt at the bottom of the page.
      self._height -= 1
  
      # Loop over all the pages.
      pos = 0
      while pos < len(self._lines):
          # Write a page of lines.
          nxt = pos + self._height
          if nxt > len(self._lines):
              nxt = len(self._lines)
              pos = nxt - self._height
          # Checks if the starting position is in between the current printed lines
          # so we don't need to reprint all the lines.
          if self.prev_pos < pos < self.prev_nxt:
              # we start where the previous page ended.
              self._Write(
                  "\n".join(self._lines[self.prev_nxt : nxt]) + "\n"
              )
          elif pos != self.prev_pos and nxt != self.prev_nxt:
              self._Write("\n".join(self._lines[pos:nxt]) + "\n")
  
          # Handle the prompt response.
          percent = self._prompt.format(
              percent=100 * nxt // len(self._lines)
          )
          digits = ""
          while True:
              # We want to reset prev values if we just exited out of the while loop
              if reset_prev_values:
                  self.prev_pos, self.prev_nxt = pos, nxt
                  reset_prev_values = False
              self._Write(percent)
              c = self._attr.GetRawKey()
              self._Write(self._clear)
  
              # Parse the command.
              if c in (
                  None,  # EOF.
                  "q",  # Quit.
                  "Q",  # Quit.
                  "\x03",  # ^C  (unix & windows terminal interrupt)
                  "\x1b",  # ESC.
              ):
                  # Quit.
                  return
              elif c in ("/", "?"):
                  c = self._GetSearchCommand(c)
              elif c.isdigit():
                  # Collect digits for operation count.
                  digits += c
                  continue
  
              # Set the optional command count.
              if digits:
                  count = int(digits)
                  digits = ""
              else:
                  count = 0
  
              # Finally commit to command c.
              if c in ("<PAGE-UP>", "<LEFT-ARROW>", "b", "\x02"):
                  # Previous page.
                  nxt = pos - self._height
                  if nxt < 0:
                      nxt = 0
              elif c in (
                  "<PAGE-DOWN>",
                  "<RIGHT-ARROW>",
                  "f",
                  "\x06",
                  " ",
              ):
                  # Next page.
                  if nxt >= len(self._lines):
                      continue
                  nxt = pos + self._height
                  if nxt >= len(self._lines):
                      nxt = pos
              elif c in ("<HOME>", "g"):
                  # First page.
                  nxt = count - 1
                  if nxt > len(self._lines) - self._height:
                      nxt = len(self._lines) - self._height
                  if nxt < 0:
                      nxt = 0
              elif c in ("<END>", "G"):
                  # Last page.
                  nxt = len(self._lines) - count
                  if nxt > len(self._lines) - self._height:
                      nxt = len(self._lines) - self._height
                  if nxt < 0:
                      nxt = 0
              elif c == "h":
                  self._Help()
                  # Special case when we want to reprint the previous display.
                  (
                      self.prev_pos,
                      self.prev_nxt,
                  ) = self.PREV_POS_NXT_REPRINT
                  nxt = pos
                  break
              elif c in ("<DOWN-ARROW>", "j", "+", "\n", "\r"):
                  # Next line.
                  if nxt >= len(self._lines):
                      continue
                  nxt = pos + 1
                  if nxt >= len(self._lines):
                      nxt = pos
              elif c in ("<UP-ARROW>", "k", "-"):
                  # Previous line.
                  nxt = pos - 1
                  if nxt < 0:
                      nxt = 0
              elif c in ("n", "N"):
                  # Next pattern match search.
                  if not self._search_pattern:
                      continue
                  nxt = pos
                  i = pos
                  direction = 1 if c == self._search_direction else -1
                  while True:
                      i += direction
                      if i < 0 or i >= len(self._lines):
                          break
                      if self._search_pattern.search(self._lines[i]):
                          nxt = i
                          break
              else:
                  # Silently ignore everything else.
                  continue
              if nxt != pos:
                  # We will exit the while loop because position changed so we can reset
                  # prev values.
                  reset_prev_values = True
                  break
          pos = nxt
  
file_path: python-fire/fire/console/console_pager.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import unicode_literals
  import re
  import sys
  from fire.console import console_attr
label_desc: Use image node_id 5 for calling the Pager obj's underlying member method code with example usage: obj.Run() without return types