Moves the cursor of the Scanner to or by *offset* depending on the *mode*.
    Is is similar to a file's `seek()` function, however the *mode* parameter
    also accepts the string-mode values `'set'`, `'cur'` and `'end'`.

    Note that even for the `'end'` mode, the *offset* must be negative to
    actually reach back up from the end of the file.

    If *renew* is set to True, the line and column counting will always begin
    from the start of the file. Keep in mind that this could can be very slow
    because it has to go through each and every character until the desired
    position is reached.

    Otherwise, if *renew* is set to False, it will be decided if counting from
    the start is shorter than counting from the current cursor position.

def seek(self, offset, mode='set', renew=False):
    """
    Moves the cursor of the Scanner to or by *offset* depending on the *mode*.
    Is is similar to a file's `seek()` function, however the *mode* parameter
    also accepts the string-mode values `'set'`, `'cur'` and `'end'`.

    Note that even for the `'end'` mode, the *offset* must be negative to
    actually reach back up from the end of the file.

    If *renew* is set to True, the line and column counting will always begin
    from the start of the file. Keep in mind that this could can be very slow
    because it has to go through each and every character until the desired
    position is reached.

    Otherwise, if *renew* is set to False, it will be decided if counting from
    the start is shorter than counting from the current cursor position.
    """

    mapping = {os.SEEK_SET: 'set', os.SEEK_CUR: 'cur', os.SEEK_END: 'end'}
    mode = mapping.get(mode, mode)
    if mode not in ('set', 'cur', 'end'):
      raise ValueError('invalid mode: "{}"'.format(mode))

    # Translate the other modes into the 'set' mode.
    if mode == 'end':
      offset = len(self.text) + offset
      mode = 'set'
    elif mode == 'cur':
      offset = self.index + offset
      mode = 'set'

    assert mode == 'set'
    if offset < 0:
      offset = 0
    elif offset > len(self.text):
      offset = len(self.text) + 1

    if self.index == offset:
      return

    # Figure which path is shorter:
    # 1) Start counting from the beginning of the file,
    if offset <= abs(self.index - offset):
      text, index, lineno, colno = self.text, 0, 1, 0
      while index != offset:
        # Find the next newline in the string.
        nli = text.find('\n', index)
        if nli >= offset or nli < 0:
          colno = offset - index
          index = offset
          break
        else:
          colno = 0
          lineno += 1
          index = nli + 1

    # 2) or step from the current position of the cursor.
    else:
      text, index, lineno, colno = self.text, self.index, self.lineno, self.colno

      if offset < index:  # backwards
        while index != offset:
          nli = text.rfind('\n', 0, index)
          if nli < 0 or nli <= offset:
            if text[offset] == '\n':
              assert (offset - nli) == 0, (offset, nli)
              nli = text.rfind('\n', 0, index-1)
              lineno -= 1
            colno = offset - nli - 1
            index = offset
            break
          else:
            lineno -= 1
            index = nli - 1
      else:  # forwards
        while index != offset:
          nli = text.find('\n', index)
          if nli < 0 or nli >= offset:
            colno = offset - index
            index = offset
          else:
            lineno += 1
            index = nli + 1

    assert lineno >= 1
    assert colno >= 0
    assert index == offset
    self.index, self.lineno, self.colno = index, lineno, colno