docs: function Inputter(options, components) {
    this.requisition = components.requisition;
    this.focusManager = components.focusManager;
  
    this.element = components.element;
    this.element.classList.add('gcli-in-input');
    this.element.spellcheck = false;
  
    this.document = this.element.ownerDocument;
  
    this.scratchpad = options.scratchpad;
  
    if (inputterCss != null) {
      this.style = util.importCss(inputterCss, this.document, 'gcli-inputter');
    }
  
    // Used to distinguish focus from TAB in CLI. See onKeyUp()
    this.lastTabDownAt = 0;
  
    // Used to effect caret changes. See _processCaretChange()
    this._caretChange = null;
  
    // Ensure that TAB/UP/DOWN isn't handled by the browser
    this.onKeyDown = this.onKeyDown.bind(this);
    this.onKeyUp = this.onKeyUp.bind(this);
    this.element.addEventListener('keydown', this.onKeyDown, false);
    this.element.addEventListener('keyup', this.onKeyUp, false);
  
    // Setup History
    this.history = new History();
    this._scrollingThroughHistory = false;
  
    // Used when we're selecting which prediction to complete with
    this._choice = null;
    this.onChoiceChange = util.createEvent('Inputter.onChoiceChange');
  
    // Cursor position affects hint severity
    this.onMouseUp = this.onMouseUp.bind(this);
    this.element.addEventListener('mouseup', this.onMouseUp, false);
  
    if (this.focusManager) {
      this.focusManager.addMonitoredElement(this.element, 'input');
    }
  
    // Start looking like an asynchronous completion isn't happening
    this._completed = RESOLVED;
  
    this.requisition.onTextChange.add(this.textChanged, this);
  
    this.assignment = this.requisition.getAssignmentAt(0);
    this.onAssignmentChange = util.createEvent('Inputter.onAssignmentChange');
    this.onInputChange = util.createEvent('Inputter.onInputChange');
  
    this.onResize = util.createEvent('Inputter.onResize');
    this.onWindowResize = this.onWindowResize.bind(this);
    this.document.defaultView.addEventListener('resize', this.onWindowResize, false);
  
    this.requisition.update(this.element.value || '');
  }