class_docstr: Editing widget using the interior of a window object.
   Supports the following Emacs-like key bindings:
  
  Ctrl-A      Go to left edge of window.
  Ctrl-B      Cursor left, wrapping to previous line if appropriate.
  Ctrl-D      Delete character under cursor.
  Ctrl-E      Go to right edge (stripspaces off) or end of line (stripspaces on).
  Ctrl-F      Cursor right, wrapping to next line when appropriate.
  Ctrl-G      Terminate, returning the window contents.
  Ctrl-H      Delete character backward.
  Ctrl-J      Terminate if the window is 1 line, otherwise insert newline.
  Ctrl-K      If line is blank, delete it, otherwise clear to end of line.
  Ctrl-L      Refresh screen.
  Ctrl-N      Cursor down; move down one line.
  Ctrl-O      Insert a blank line at cursor location.
  Ctrl-P      Cursor up; move up one line.
  
  Move operations do nothing if the cursor is at an edge where the movement
  is not possible.  The following synonyms are supported where possible:
  
  KEY_LEFT = Ctrl-B, KEY_RIGHT = Ctrl-F, KEY_UP = Ctrl-P, KEY_DOWN = Ctrl-N
  KEY_BACKSPACE = Ctrl-h
class_docstr_tok: ["Editing","widget","using","the","interior","of","a","window","object",".","Supports","the","following","Emacs-like","key","bindings",":","Ctrl-A","Go","to","left","edge","of","window",".","Ctrl-B","Cursor","left",",","wrapping","to","previous","line","if","appropriate",".","Ctrl-D","Delete","character","under","cursor",".","Ctrl-E","Go","to","right","edge","(","stripspaces","off",")","or","end","of","line","(","stripspaces","on",")",".","Ctrl-F","Cursor","right",",","wrapping","to","next","line","when","appropriate",".","Ctrl-G","Terminate",",","returning","the","window","contents",".","Ctrl-H","Delete","character","backward",".","Ctrl-J","Terminate","if","the","window","is","1","line",",","otherwise","insert","newline",".","Ctrl-K","If","line","is","blank",",","delete","it",",","otherwise","clear","to","end","of","line",".","Ctrl-L","Refresh","screen",".","Ctrl-N","Cursor","down",";","move","down","one","line",".","Ctrl-O","Insert","a","blank","line","at","cursor","location",".","Ctrl-P","Cursor","up",";","move","up","one","line",".","Move","operations","do","nothing","if","the","cursor","is","at","an","edge","where","the","movement","is","not","possible",".","The","following","synonyms","are","supported","where","possible",":","KEY_LEFT","=","Ctrl-B",",","KEY_RIGHT","=","Ctrl-F",",","KEY_UP","=","Ctrl-P",",","KEY_DOWN","=","Ctrl-N","KEY_BACKSPACE","=","Ctrl-h"]
docstr: Process a single editing command.
docstr_tok: ["Process","a","single","editing","command","."]
code: def do_command(self, ch):
      "Process a single editing command."
      self._update_max_yx()
      (y, x) = self.win.getyx()
      self.lastcmd = ch
      if curses.ascii.isprint(ch):
          if y < self.maxy or x < self.maxx:
              self._insert_printable_char(ch)
      elif ch == curses.ascii.SOH:  # ^a
          self.win.move(y, 0)
      elif ch in (
          curses.ascii.STX,
          curses.KEY_LEFT,
          curses.ascii.BS,
          curses.KEY_BACKSPACE,
          curses.ascii.DEL,
      ):
          if x > 0:
              self.win.move(y, x - 1)
          elif y == 0:
              pass
          elif self.stripspaces:
              self.win.move(y - 1, self._end_of_line(y - 1))
          else:
              self.win.move(y - 1, self.maxx)
          if ch in (
              curses.ascii.BS,
              curses.KEY_BACKSPACE,
              curses.ascii.DEL,
          ):
              self.win.delch()
      elif ch == curses.ascii.EOT:  # ^d
          self.win.delch()
      elif ch == curses.ascii.ENQ:  # ^e
          if self.stripspaces:
              self.win.move(y, self._end_of_line(y))
          else:
              self.win.move(y, self.maxx)
      elif ch in (curses.ascii.ACK, curses.KEY_RIGHT):  # ^f
          if x < self.maxx:
              self.win.move(y, x + 1)
          elif y == self.maxy:
              pass
          else:
              self.win.move(y + 1, 0)
      elif ch == curses.ascii.BEL:  # ^g
          return 0
      elif ch == curses.ascii.NL:  # ^j
          if self.maxy == 0:
              return 0
          elif y < self.maxy:
              self.win.move(y + 1, 0)
      elif ch == curses.ascii.VT:  # ^k
          if x == 0 and self._end_of_line(y) == 0:
              self.win.deleteln()
          else:
              # first undo the effect of self._end_of_line
              self.win.move(y, x)
              self.win.clrtoeol()
      elif ch == curses.ascii.FF:  # ^l
          self.win.refresh()
      elif ch in (curses.ascii.SO, curses.KEY_DOWN):  # ^n
          if y < self.maxy:
              self.win.move(y + 1, x)
              if x > self._end_of_line(y + 1):
                  self.win.move(y + 1, self._end_of_line(y + 1))
      elif ch == curses.ascii.SI:  # ^o
          self.win.insertln()
      elif ch in (curses.ascii.DLE, curses.KEY_UP):  # ^p
          if y > 0:
              self.win.move(y - 1, x)
              if x > self._end_of_line(y - 1):
                  self.win.move(y - 1, self._end_of_line(y - 1))
      return 1
  
file_path: cpython/Lib/curses/textpad.py
imports: import curses
  import curses.ascii
label_desc: Use image node_id 5 for calling the Textbox obj's underlying member method code with example usage: obj.do_command(ch) and returns: int, int, int