docs: def startCompletion(self, force=False):
          """
          Starts a new completion popup for the current object.
          
          :return     <bool> success
          """
          # add the top level items
          tree = self.completerTree()
          if not force and tree.isVisible():
              return
          
          tree.clear()
          
          # make sure we have a valid object
          obj, remain = self.objectAtCursor()
          
          if obj is None:
              tree.hide()
              return
          
          # determine the cursor position
          rect   = self.cursorRect()
          cursor = self.textCursor()
          point  = QPoint(rect.left(), rect.top() + 18)
          
          # compare the ids since some things might overload the __eq__
          # comparator
          if id(obj) == id(self._scope):
              o_keys = obj.keys()
          elif obj is not None:
              o_keys = dir(obj)
          
          keys = [key for key in sorted(o_keys) if not key.startswith('_')]
          if id(obj) == id(self._scope):
              if not remain:
                  return False
              else:
                  keys = filter(lambda x: x.startswith(remain[0]), keys)
          
          if not keys:
              return False
          
          for key in keys:
              tree.addTopLevelItem(QTreeWidgetItem([key]))
          
          tree.move(self.mapToGlobal(point))
          tree.show()
          return True