Repository: neovim/neovim
File: src/nvim/autocmd.c (C)

Code before:
        }
        curbuf->b_nwindows--;
        curbuf = aco->new_curbuf.br_buf;
        curwin->w_buffer = curbuf;
        curbuf->b_nwindows++;
      }

      curwin = save_curwin;
      curbuf = curwin->w_buffer;
      prevwin = win_find_by_handle(aco->save_prevwin_handle);

      // In case the autocommand moves the cursor to a position that does not
      // exist in curbuf
      VIsual_active = aco->save_VIsual_active;
      check_cursor(curwin);
    }
  }

  VIsual_active = aco->save_VIsual_active;
  check_cursor(curwin);  // just in case lines got deleted
  if (VIsual_active) {
    check_pos(curbuf, &VIsual);
  }
}

/// Put a safe autocommand event on the queue, to be triggered at a safe time.
///
/// @param event event that occurred
/// @param fname filename, NULL or empty means use actual file name
/// @param fname_io filename to use for <afile> on cmdline,
///                 NULL means use `fname`.
/// @param group autocmd group ID or AUGROUP_ALL
/// @param buf Buffer for <abuf>
/// @param eap Ex command arguments
void queue_safe_autocommand(event_T event, char *fname, char *fname_io, int group, buf_T *buf,
                            exarg_T *eap, Object *data)
{
  SafeAutocommandEvent *evdata = xmalloc(sizeof(SafeAutocommandEvent));
  evdata->event = event;
  evdata->fname = fname;
  evdata->fname_io = fname_io;
  evdata->group = group;
  evdata->buf = buf->handle;
  evdata->eap = eap;
  if (data) {
    evdata->data = xmalloc(sizeof(Object));
    *evdata->data = copy_object(*data, NULL);
  } else {
    evdata->data = NULL;
  }


Review comment (suggestion):
```suggestion
/// Schedules an autocommand event, to be executed at the next event-loop tick.
```

Code after:
  } else {
    // Restore curwin.  Use the window ID, a window may have been closed
    // and the memory re-used for another one.
    win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle);
    if (save_curwin != NULL) {
      // Restore the buffer which was previously edited by curwin, if it was
      // changed, we are still the same window and the buffer is valid.
      if (curwin->handle == aco->new_curwin_handle
          && curbuf != aco->new_curbuf.br_buf
          && bufref_valid(&aco->new_curbuf)
          && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) {
        if (curwin->w_s == &curbuf->b_s) {
          curwin->w_s = &aco->new_curbuf.br_buf->b_s;
        }
        curbuf->b_nwindows--;
        curbuf = aco->new_curbuf.br_buf;
        curwin->w_buffer = curbuf;
        curbuf->b_nwindows++;
      }

      curwin = save_curwin;
      curbuf = curwin->w_buffer;
      prevwin = win_find_by_handle(aco->save_prevwin_handle);

      // In case the autocommand moves the cursor to a position that does not
      // exist in curbuf
      VIsual_active = aco->save_VIsual_active;
      check_cursor(curwin);
    }
  }

  VIsual_active = aco->save_VIsual_active;
  check_cursor(curwin);  // just in case lines got deleted
  if (VIsual_active) {
    check_pos(curbuf, &VIsual);
  }
}

/// Schedules an autocommand event, to be executed at the next event-loop tick.
///
/// @param event Event to schedule
/// @param fname Name to use as `<amatch>` (the "pattern"). NULL/empty means use actual filename.
/// @param fname_io Filename to use for <afile> on cmdline, NULL means use `fname`.
/// @param group Group ID or AUGROUP_ALL
/// @param buf Buffer for <abuf>
/// @param eap Ex command arguments
/// @param data Event-specific data. Will be copied, caller must free `data`.
/// The `data` items will also be copied to `v:event`.
void aucmd_defer(event_T event, char *fname, char *fname_io, int group, buf_T *buf, exarg_T *eap,
                 Object *data)
{