# File lib/rbreadline.rb, line 7609
  def rl_do_undo()
    start = _end = waiting_for_begin = 0
    begin
      return 0 if @rl_undo_list.nil?

      @_rl_doing_an_undo = true
      rl_setstate(RL_STATE_UNDOING)

      # To better support vi-mode, a start or end value of -1 means
      # rl_point, and a value of -2 means rl_end.
      if (@rl_undo_list.what == UNDO_DELETE || @rl_undo_list.what == UNDO_INSERT)
        start = trans(@rl_undo_list.start)
        _end = trans(@rl_undo_list.end)
      end

      case (@rl_undo_list.what)
        # Undoing deletes means inserting some text.
      when UNDO_DELETE
        @rl_point = start
        rl_insert_text(@rl_undo_list.text)
        @rl_undo_list.text = nil

        # Undoing inserts means deleting some text.
      when UNDO_INSERT
        rl_delete_text(start, _end)
        @rl_point = start
        # Undoing an END means undoing everything 'til we get to a BEGIN.
      when UNDO_END
        waiting_for_begin+=1
        # Undoing a BEGIN means that we are done with this group.
      when UNDO_BEGIN
        if (waiting_for_begin!=0)
          waiting_for_begin-=1
        else
          rl_ding()
        end
      end

      @_rl_doing_an_undo = false
      rl_unsetstate(RL_STATE_UNDOING)

      release = @rl_undo_list
      @rl_undo_list = @rl_undo_list.next
      replace_history_data(-1, release, @rl_undo_list)
      release = nil
    end while (waiting_for_begin!=0)

    1
  end