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

Code before:

/// Free and clear fmark_T item
void clear_fmark(fmark_T *const fm, const Timestamp timestamp)
  FUNC_ATTR_NONNULL_ALL
{
  free_fmark(*fm);
  *fm = (fmark_T)INIT_FMARK;
  fm->timestamp = timestamp;
}

/// Execute "MarkSet" autocommand.
///
/// @param c The name of the mark, e.g., 'a'.
/// @param pos Position of the mark in the buffer.
/// @param buf The buffer of the mark.
static void do_markset_autocmd(char c, pos_T *pos, buf_T *buf)
{
  MAXSIZE_TEMP_DICT(data, 3);
  char mark_str[2] = { c, '\0' };
  PUT_C(data, "mark", STRING_OBJ(((String){ .data = mark_str, .size = 1 })));
  PUT_C(data, "line", INTEGER_OBJ(pos->lnum));
  PUT_C(data, "col", INTEGER_OBJ(pos->col));
  queue_safe_autocommand(EVENT_MARKSET, buf->b_fname, buf->b_fname, AUGROUP_ALL, buf, NULL,
                         &DICT_OBJ(data));
}

// Set named mark "c" to position "pos".
// When "c" is upper case use file "fnum".
// Returns OK on success, FAIL if bad name given.
int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt)
{
  int i;
  fmarkv_T view = view_pt != NULL ? *view_pt : (fmarkv_T)INIT_FMARKV;

  // Check for a special key (may cause islower() to crash).
  if (c < 0) {
    return FAIL;
  }

  if (c == '\'' || c == '`') {
    if (pos == &curwin->w_cursor) {
      setpcmark();
      // keep it even when the cursor doesn't move
      curwin->w_prev_pcmark = curwin->w_pcmark;
    } else {
      curwin->w_pcmark = *pos;
    }
    return OK;
  }

  // Can't set a mark in a non-existent buffer.

Review comment (suggestion):
should be skipped if there are no MarkSet commands (`!has_event(EVENT_MARKSET)`).

off topic: other things like `do_autocmd_progress` should also do that... https://github.com/neovim/neovim/pull/35871


Code after:

/// Free and clear fmark_T item
void clear_fmark(fmark_T *const fm, const Timestamp timestamp)
  FUNC_ATTR_NONNULL_ALL
{
  free_fmark(*fm);
  *fm = (fmark_T)INIT_FMARK;
  fm->timestamp = timestamp;
}

/// Schedules "MarkSet" event.
///
/// @param c The name of the mark, e.g., 'a'.
/// @param pos Position of the mark in the buffer.
/// @param buf The buffer of the mark.
static void do_markset_autocmd(char c, pos_T *pos, buf_T *buf)
{
  if (!has_event(EVENT_MARKSET)) {
    return;
  }

  MAXSIZE_TEMP_DICT(data, 3);
  char mark_str[2] = { c, '\0' };
  PUT_C(data, "name", STRING_OBJ(((String){ .data = mark_str, .size = 1 })));
  PUT_C(data, "line", INTEGER_OBJ(pos->lnum));
  PUT_C(data, "col", INTEGER_OBJ(pos->col));
  aucmd_defer(EVENT_MARKSET, mark_str, NULL, AUGROUP_ALL, buf, NULL, &DICT_OBJ(data));
}

// Set named mark "c" to position "pos".
// When "c" is upper case use file "fnum".
// Returns OK on success, FAIL if bad name given.
int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt)
{
  int i;
  fmarkv_T view = view_pt != NULL ? *view_pt : (fmarkv_T)INIT_FMARKV;

  // Check for a special key (may cause islower() to crash).
  if (c < 0) {
    return FAIL;
  }

  if (c == '\'' || c == '`') {
    if (pos == &curwin->w_cursor) {
      setpcmark();
      // keep it even when the cursor doesn't move
      curwin->w_prev_pcmark = curwin->w_pcmark;
    } else {
      curwin->w_pcmark = *pos;
    }
    return OK;