ronantakizawa/codereview-bench huggingface dataset:
Repository: neovim/neovim
File: src/nvim/os/env.c (C)

Code before:
      return NULL;
    }
  }
  char *str = environ[index];
  assert(str != NULL);
  const char * const end = strchr(str, '=');
  assert(end != NULL);
  ptrdiff_t len = end - str;
  assert(len > 0);
  return xmemdupz(str, (size_t)len);
#endif
}

/// Get the process ID of the Nvim process.
///
/// @return the process ID.
int64_t os_get_pid(void)
{
#ifdef MSWIN
  return (int64_t)GetCurrentProcessId();
#else
  return (int64_t)getpid();
#endif
}

/// Apply a priority appropriate for interactive work to the Nvim process.
void os_hint_priority(void)
{
#ifdef __APPLE__
  // Inform the macOS scheduler that Nvim renders UI, and so shouldn’t have its threads’ quality
  // of service classes clamped. The main thread runs at User Interactive by default so we don’t
  // need to adjust that.
  integer_t policy = TASK_DEFAULT_APPLICATION;
  task_policy_set(mach_task_self(), TASK_CATEGORY_POLICY, &policy, 1);
#endif
}

/// Gets the hostname of the current machine.
///
/// @param hostname   Buffer to store the hostname.
/// @param size       Size of `hostname`.
void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
  struct utsname vutsname;

  if (uname(&vutsname) < 0) {
    *hostname = NUL;
  } else {
    xstrlcpy(hostname, vutsname.nodename, size);
  }

Review comment (suggestion):
```suggestion
/// Signals to the OS that Nvim is an application for "interactive work"
/// which should be prioritized similar to a GUI app.
```

Code after:
      return NULL;
    }
  }
  char *str = environ[index];
  assert(str != NULL);
  const char * const end = strchr(str, '=');
  assert(end != NULL);
  ptrdiff_t len = end - str;
  assert(len > 0);
  return xmemdupz(str, (size_t)len);
#endif
}

/// Get the process ID of the Nvim process.
///
/// @return the process ID.
int64_t os_get_pid(void)
{
#ifdef MSWIN
  return (int64_t)GetCurrentProcessId();
#else
  return (int64_t)getpid();
#endif
}

/// Signals to the OS that Nvim is an application for "interactive work"
/// which should be prioritized similar to a GUI app.
void os_hint_priority(void)
{
#ifdef __APPLE__
  // By default, processes have the TASK_UNSPECIFIED "role", which means all of its threads are
  // clamped to Default QoS. Setting the role to TASK_DEFAULT_APPLICATION removes this clamp.
  integer_t policy = TASK_DEFAULT_APPLICATION;
  task_policy_set(mach_task_self(), TASK_CATEGORY_POLICY, &policy, 1);
#endif
}

/// Gets the hostname of the current machine.
///
/// @param hostname   Buffer to store the hostname.
/// @param size       Size of `hostname`.
void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
  struct utsname vutsname;

  if (uname(&vutsname) < 0) {
    *hostname = NUL;
  } else {
    xstrlcpy(hostname, vutsname.nodename, size);
  }
Repository: neovim/neovim
File: src/nvim/os/env.c (C)

Code before:
  assert(end != NULL);
  ptrdiff_t len = end - str;
  assert(len > 0);
  return xmemdupz(str, (size_t)len);
#endif
}

/// Get the process ID of the Nvim process.
///
/// @return the process ID.
int64_t os_get_pid(void)
{
#ifdef MSWIN
  return (int64_t)GetCurrentProcessId();
#else
  return (int64_t)getpid();
#endif
}

/// Apply a priority appropriate for interactive work to the Nvim process.
void os_hint_priority(void)
{
#ifdef __APPLE__
  // Inform the macOS scheduler that Nvim renders UI, and so shouldn’t have its threads’ quality
  // of service classes clamped. The main thread runs at User Interactive by default so we don’t
  // need to adjust that.
  integer_t policy = TASK_DEFAULT_APPLICATION;
  task_policy_set(mach_task_self(), TASK_CATEGORY_POLICY, &policy, 1);
#endif
}

/// Gets the hostname of the current machine.
///
/// @param hostname   Buffer to store the hostname.
/// @param size       Size of `hostname`.
void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
  struct utsname vutsname;

  if (uname(&vutsname) < 0) {
    *hostname = NUL;
  } else {
    xstrlcpy(hostname, vutsname.nodename, size);
  }
#elif defined(MSWIN)
  wchar_t host_utf16[MAX_COMPUTERNAME_LENGTH + 1];
  DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]);
  if (GetComputerNameW(host_utf16, &host_wsize) == 0) {
    *hostname = NUL;
    DWORD err = GetLastError();

Review comment (suggestion):
```suggestion
  // By default, processes have the TASK_UNSPECIFIED "role", which means all of its threads are
  // clamped to Default QoS. Setting the role to TASK_DEFAULT_APPLICATION removes this clamp.
```

Code after:
  assert(end != NULL);
  ptrdiff_t len = end - str;
  assert(len > 0);
  return xmemdupz(str, (size_t)len);
#endif
}

/// Get the process ID of the Nvim process.
///
/// @return the process ID.
int64_t os_get_pid(void)
{
#ifdef MSWIN
  return (int64_t)GetCurrentProcessId();
#else
  return (int64_t)getpid();
#endif
}

/// Signals to the OS that Nvim is an application for "interactive work"
/// which should be prioritized similar to a GUI app.
void os_hint_priority(void)
{
#ifdef __APPLE__
  // By default, processes have the TASK_UNSPECIFIED "role", which means all of its threads are
  // clamped to Default QoS. Setting the role to TASK_DEFAULT_APPLICATION removes this clamp.
  integer_t policy = TASK_DEFAULT_APPLICATION;
  task_policy_set(mach_task_self(), TASK_CATEGORY_POLICY, &policy, 1);
#endif
}

/// Gets the hostname of the current machine.
///
/// @param hostname   Buffer to store the hostname.
/// @param size       Size of `hostname`.
void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
  struct utsname vutsname;

  if (uname(&vutsname) < 0) {
    *hostname = NUL;
  } else {
    xstrlcpy(hostname, vutsname.nodename, size);
  }
#elif defined(MSWIN)
  wchar_t host_utf16[MAX_COMPUTERNAME_LENGTH + 1];
  DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]);
  if (GetComputerNameW(host_utf16, &host_wsize) == 0) {
    *hostname = NUL;
    DWORD err = GetLastError();
Repository: neovim/neovim
File: src/nvim/api/vim.c (C)

Code before:
                || strequal(opts->status.data, "cancel")),
               "status", "success|failed|running|cancel", opts->status.data, {
    goto error;
  });

  VALIDATE_RANGE(!is_progress || (opts->percent >= 0 && opts->percent <= 100),
                 "percent", {
    goto error;
  });

  MessageData msg_data = { .title = opts->title, .status = opts->status,
                           .percent = opts->percent, .data = opts->data };

  id = msg_multihl(opts->id, hl_msg, kind, history, opts->err, &msg_data, &needs_clear);

  if (opts->verbose) {
    verbose_leave();
    verbose_stop();  // flush now
  }

  if (is_progress) {
    do_autocmd_progress(id, hl_msg, &msg_data);
  }

  if (!needs_clear) {
    // history takes ownership
    return id;
  }

error:
  hl_msg_free(hl_msg);
  return id;
}

/// Gets the current list of buffers.
///
/// Includes unlisted (unloaded/deleted) buffers, like `:ls!`.
/// Use |nvim_buf_is_loaded()| to check if a buffer is loaded.
///
/// @return List of buffer ids
ArrayOf(Buffer) nvim_list_bufs(Arena *arena)
  FUNC_API_SINCE(1)
{
  size_t n = 0;

  FOR_ALL_BUFFERS(b) {
    n++;
  }

  Array rv = arena_array(arena, n);


Review comment (suggestion):
```suggestion
    // history takes ownership of `hl_msg`.
```

Code after:
                || strequal(opts->status.data, "cancel")),
               "status", "success|failed|running|cancel", opts->status.data, {
    goto error;
  });

  VALIDATE_RANGE(!is_progress || (opts->percent >= 0 && opts->percent <= 100),
                 "percent", {
    goto error;
  });

  MessageData msg_data = { .title = opts->title, .status = opts->status,
                           .percent = opts->percent, .data = opts->data };

  id = msg_multihl(opts->id, hl_msg, kind, history, opts->err, &msg_data, &needs_clear);

  if (opts->verbose) {
    verbose_leave();
    verbose_stop();  // flush now
  }

  if (is_progress) {
    do_autocmd_progress(id, hl_msg, &msg_data);
  }

  if (!needs_clear) {
    // history takes ownership of `hl_msg`
    return id;
  }

error:
  hl_msg_free(hl_msg);
  return id;
}

/// Gets the current list of buffers.
///
/// Includes unlisted (unloaded/deleted) buffers, like `:ls!`.
/// Use |nvim_buf_is_loaded()| to check if a buffer is loaded.
///
/// @return List of buffer ids
ArrayOf(Buffer) nvim_list_bufs(Arena *arena)
  FUNC_API_SINCE(1)
{
  size_t n = 0;

  FOR_ALL_BUFFERS(b) {
    n++;
  }

  Array rv = arena_array(arena, n);
Repository: neovim/neovim
File: src/nvim/ex_docmd.c (C)

Code before:
/// Execute normal mode command "cmd".
/// "remap" can be REMAP_NONE or REMAP_YES.
void exec_normal_cmd(char *cmd, int remap, bool silent)
{
  // Stuff the argument into the typeahead buffer.
  ins_typebuf(cmd, remap, 0, true, silent);
  exec_normal(false, false);
}

/// Execute normal_cmd() until there is no typeahead left.
///
/// @param was_typed whether or not something was typed
/// @param use_vpeekc  true to use vpeekc() to check for available chars
void exec_normal(bool was_typed, bool use_vpeekc)
{
  oparg_T oa;
  int c;

  clear_oparg(&oa);
  finish_op = false;
  while ((!stuff_empty()
          || ((was_typed || !typebuf_typed())
              && typebuf.tb_len > 0)
          || (use_vpeekc && (c = vpeekc()) != NUL && c != Ctrl_C))
         && !got_int) {
    update_topline_cursor();
    normal_cmd(&oa, true);      // execute a Normal mode cmd
  }
}

static void ex_checkpath(exarg_T *eap)
{
  find_pattern_in_path(NULL, 0, 0, false, false, CHECK_PATH, 1,
                       eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
                       1, (linenr_T)MAXLNUM, eap->forceit, false);
}

/// ":psearch"
static void ex_psearch(exarg_T *eap)
{
  g_do_tagpreview = (int)p_pvh;
  ex_findpat(eap);
  g_do_tagpreview = 0;
}

static void ex_findpat(exarg_T *eap)
{
  bool whole = true;
  int action;

  switch (cmdnames[eap->cmdidx].cmd_name[2]) {

Review comment (suggestion):
The comment above is missing:
```c
    // When calling vpeekc() from feedkeys() it will return Ctrl_C when there
    // is nothing to get, so also check for Ctrl_C.
```

Code after:
/// Execute normal mode command "cmd".
/// "remap" can be REMAP_NONE or REMAP_YES.
void exec_normal_cmd(char *cmd, int remap, bool silent)
{
  // Stuff the argument into the typeahead buffer.
  ins_typebuf(cmd, remap, 0, true, silent);
  exec_normal(false, false);
}

/// Execute normal_cmd() until there is no typeahead left.
///
/// @param was_typed whether or not something was typed
/// @param use_vpeekc  true to use vpeekc() to check for available chars
void exec_normal(bool was_typed, bool use_vpeekc)
{
  oparg_T oa;
  int c;

  // When calling vpeekc() from feedkeys() it will return Ctrl_C when there
  // is nothing to get, so also check for Ctrl_C.
  clear_oparg(&oa);
  finish_op = false;
  while ((!stuff_empty()
          || ((was_typed || !typebuf_typed())
              && typebuf.tb_len > 0)
          || (use_vpeekc && (c = vpeekc()) != NUL && c != Ctrl_C))
         && !got_int) {
    update_topline_cursor();
    normal_cmd(&oa, true);      // execute a Normal mode cmd
  }
}

static void ex_checkpath(exarg_T *eap)
{
  find_pattern_in_path(NULL, 0, 0, false, false, CHECK_PATH, 1,
                       eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
                       1, (linenr_T)MAXLNUM, eap->forceit, false);
}

/// ":psearch"
static void ex_psearch(exarg_T *eap)
{
  g_do_tagpreview = (int)p_pvh;
  ex_findpat(eap);
  g_do_tagpreview = 0;
}

static void ex_findpat(exarg_T *eap)
{
  bool whole = true;
  int action;
Repository: neovim/neovim
File: test/functional/vimscript/screenchar_spec.lua (Lua)

Code before:
      eq({ 99 }, fn.screenchars(1, 4))
    end)

    it('screenstring()', function()
      eq('a', fn.screenstring(1, 1))
      eq('a', fn.screenstring(1, 2))
      eq('b', fn.screenstring(1, 3))
      eq('c', fn.screenstring(1, 4))
    end)
  end

  describe('with ext_multigrid', function()
    with_ext_multigrid(true)
  end)
  describe('without ext_multigrid', function()
    with_ext_multigrid(false)
  end)

  describe('hidden windows', function()
    before_each(function()
      clear()
      Screen.new(40, 7, {})
      api.nvim_buf_set_lines(0, 0, -1, true, { 'aaa', 'aaa' })
    end)

    local validate = function()
      eq('a', fn.screenstring(1, 1))
      eq(97, fn.screenchar(1, 1))
      eq({ 97 }, fn.screenchars(1, 1))
      eq(fn.screenattr(2, 1), fn.screenattr(1, 1))
    end

    it('manual', function()
      local bufnr = api.nvim_create_buf(false, true)
      api.nvim_buf_set_lines(bufnr, 0, -1, true, { 'bb' })
      local win_opts = { relative = 'editor', row = 0, col = 0, height = 1, width = 2, hide = true }
      api.nvim_open_win(bufnr, false, win_opts)

      validate()
    end)

    it('from ui2', function()
      n.exec_lua('require("vim._extui").enable({ enable = true })')

      validate()
    end)
  end)
end)


Review comment (suggestion):
let's call this `assert_something`, since that's the common convention here, and `validate` is very well established for `vim.validate`. also we always use `local function` where possible.
```suggestion
    local function assert_...()
```

Code after:
      eq({ 99 }, fn.screenchars(1, 4))
    end)

    it('screenstring()', function()
      eq('a', fn.screenstring(1, 1))
      eq('a', fn.screenstring(1, 2))
      eq('b', fn.screenstring(1, 3))
      eq('c', fn.screenstring(1, 4))
    end)
  end

  describe('with ext_multigrid', function()
    with_ext_multigrid(true)
  end)

  describe('without ext_multigrid', function()
    with_ext_multigrid(false)
  end)

  describe('hidden windows', function()
    before_each(function()
      clear()
      Screen.new(40, 7, {})
      api.nvim_buf_set_lines(0, 0, -1, true, { 'aaa', 'aaa' })
    end)

    local assert_screen_funcs = function()
      eq('a', fn.screenstring(1, 1))
      eq(97, fn.screenchar(1, 1))
      eq({ 97 }, fn.screenchars(1, 1))
      eq(fn.screenattr(2, 1), fn.screenattr(1, 1))
    end

    it('manual', function()
      local bufnr = api.nvim_create_buf(false, true)
      api.nvim_buf_set_lines(bufnr, 0, -1, true, { 'bb' })
      local win_opts = { relative = 'editor', row = 0, col = 0, height = 1, width = 2, hide = true }
      api.nvim_open_win(bufnr, false, win_opts)

      assert_screen_funcs()
    end)

    it('from ui2', function()
      n.exec_lua('require("vim._extui").enable({ enable = true })')
      command('echo "foo"')

      assert_screen_funcs()
    end)
  end)
end)
Repository: neovim/neovim
File: src/nvim/window.c (C)

Code before:
///
/// @param tp  tab page "win" is in, NULL for current
void win_remove(win_T *wp, tabpage_T *tp)
  FUNC_ATTR_NONNULL_ARG(1)
{
  assert(tp == NULL || tp != curtab);

  if (wp->w_prev != NULL) {
    wp->w_prev->w_next = wp->w_next;
  } else if (tp == NULL) {
    firstwin = curtab->tp_firstwin = wp->w_next;
  } else {
    tp->tp_firstwin = wp->w_next;
  }
  if (wp->w_next != NULL) {
    wp->w_next->w_prev = wp->w_prev;
  } else {
    if (tp == NULL) {
      lastwin = curtab->tp_lastwin = wp->w_prev;
    } else {
      tp->tp_lastwin = wp->w_prev;
    }
    win_T *new_last = (tp == NULL) ? lastwin : tp->tp_lastwin;
    if (new_last != NULL && !new_last->w_floating) {
      new_last->w_vsep_width = 0;
    }
  }
}

// Append frame "frp" in a frame list after frame "after".
static void frame_append(frame_T *after, frame_T *frp)
{
  frp->fr_next = after->fr_next;
  after->fr_next = frp;
  if (frp->fr_next != NULL) {
    frp->fr_next->fr_prev = frp;
  }
  frp->fr_prev = after;
}

// Insert frame "frp" in a frame list before frame "before".
static void frame_insert(frame_T *before, frame_T *frp)
{
  frp->fr_next = before;
  frp->fr_prev = before->fr_prev;
  before->fr_prev = frp;
  if (frp->fr_prev != NULL) {
    frp->fr_prev->fr_next = frp;
  } else {
    frp->fr_parent->fr_child = frp;
  }

Review comment (suggestion):
Looks like this doesn't fix the vsep issue if the window with the vsep isn't the last window:

```vim
botright vsplit
set winfixwidth
botright vsplit
botright split
wincmd p
quit
```

I think it's probably more appropriate to fixup the vsep somewhere like `winframe_remove` instead anyway? `win_remove` relates moreso to the window list.

Code after:

  wp->w_next = before;
  wp->w_prev = after;
  if (after == NULL) {
    *first = wp;
  } else {
    after->w_next = wp;
  }
  if (before == NULL) {
    *last = wp;
  } else {
    before->w_prev = wp;
  }
}

/// Remove a window from the window list.
///
/// @param tp  tab page "win" is in, NULL for current
void win_remove(win_T *wp, tabpage_T *tp)
  FUNC_ATTR_NONNULL_ARG(1)
{
  assert(tp == NULL || tp != curtab);

  if (wp->w_prev != NULL) {
    wp->w_prev->w_next = wp->w_next;
  } else if (tp == NULL) {
    firstwin = curtab->tp_firstwin = wp->w_next;
  } else {
    tp->tp_firstwin = wp->w_next;
  }
  if (wp->w_next != NULL) {
    wp->w_next->w_prev = wp->w_prev;
  } else if (tp == NULL) {
    lastwin = curtab->tp_lastwin = wp->w_prev;
  } else {
    tp->tp_lastwin = wp->w_prev;
  }
}

// Append frame "frp" in a frame list after frame "after".
static void frame_append(frame_T *after, frame_T *frp)
{
  frp->fr_next = after->fr_next;
  after->fr_next = frp;
  if (frp->fr_next != NULL) {
    frp->fr_next->fr_prev = frp;
  }
  frp->fr_prev = after;
}

// Insert frame "frp" in a frame list before frame "before".
Repository: neovim/neovim
File: src/nvim/window.c (C)

Code before:
    }
    frame_fix_height(wp);
    frame_fix_height(oldwin);
  }

  if (toplevel) {
    win_comp_pos();
  }

  // Both windows need redrawing.  Update all status lines, in case they
  // show something related to the window count or position.
  redraw_later(wp, UPD_NOT_VALID);
  redraw_later(oldwin, UPD_NOT_VALID);
  status_redraw_all();

  if (need_status) {
    msg_row = Rows - 1;
    msg_col = sc_col;
    msg_clr_eos_force();        // Old command/ruler may still be there
    comp_col();
    msg_row = Rows - 1;
    msg_col = 0;        // put position back at start of line
  }

  // equalize the window sizes.
  if ((do_equal || dir != 0) && !(flags & WSP_NOEQUAL)) {
    win_equal(wp, true, vertical ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v'));
  } else if (!is_aucmd_win(wp)) {
    win_fix_scroll(false);
  }

  int i;

  // Don't change the window height/width to 'winheight' / 'winwidth' if a
  // size was given.
  if (flags & WSP_VERT) {
    i = (int)p_wiw;
    if (size != 0) {
      p_wiw = size;
    }
  } else {
    i = (int)p_wh;
    if (size != 0) {
      p_wh = size;
    }
  }

  if (!(flags & WSP_NOENTER)) {
    // make the new window the current window
    win_enter_ext(wp, (new_wp == NULL ? WEE_TRIGGER_NEW_AUTOCMDS : 0) | WEE_TRIGGER_ENTER_AUTOCMDS
                  | WEE_TRIGGER_LEAVE_AUTOCMDS);

Review comment (bug):
Even without all the other changes in this PR, this change allows for zero-sized windows, which crashes Nvim. Pretty simple to trigger when not using `&wfw`.

I assume `do_equal` is usually set in these cases, so entirely ignoring it is probably wrong.

```lua
vim.cmd.vsplit()
vim.api.nvim_open_win(0, false, { win = -1, split = "right", width = 999 })
```

Code after:
    }
    frame_fix_height(wp);
    frame_fix_height(oldwin);
  }

  if (toplevel) {
    win_comp_pos();
  }

  // Both windows need redrawing.  Update all status lines, in case they
  // show something related to the window count or position.
  redraw_later(wp, UPD_NOT_VALID);
  redraw_later(oldwin, UPD_NOT_VALID);
  status_redraw_all();

  if (need_status) {
    msg_row = Rows - 1;
    msg_col = sc_col;
    msg_clr_eos_force();        // Old command/ruler may still be there
    comp_col();
    msg_row = Rows - 1;
    msg_col = 0;        // put position back at start of line
  }

  // equalize the window sizes.
  if (do_equal || dir != 0) {
    win_equal(wp, true, vertical ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v'));
  } else if (!is_aucmd_win(wp)) {
    win_fix_scroll(false);
  }

  int i;

  // Don't change the window height/width to 'winheight' / 'winwidth' if a
  // size was given.
  if (flags & WSP_VERT) {
    i = (int)p_wiw;
    if (size != 0) {
      p_wiw = size;
    }
  } else {
    i = (int)p_wh;
    if (size != 0) {
      p_wh = size;
    }
  }

  if (!(flags & WSP_NOENTER)) {
    // make the new window the current window
    win_enter_ext(wp, (new_wp == NULL ? WEE_TRIGGER_NEW_AUTOCMDS : 0) | WEE_TRIGGER_ENTER_AUTOCMDS
                  | WEE_TRIGGER_LEAVE_AUTOCMDS);
Repository: neovim/neovim
File: src/nvim/mark.c (C)

Code before:
  if (c == ']') {
    buf->b_op_end = *pos;
    return OK;
  }

  if (c == '<' || c == '>') {
    if (c == '<') {
      buf->b_visual.vi_start = *pos;
    } else {
      buf->b_visual.vi_end = *pos;
    }
    if (buf->b_visual.vi_mode == NUL) {
      // Visual_mode has not yet been set, use a sane default.
      buf->b_visual.vi_mode = 'v';
    }
    return OK;
  }

  if (ASCII_ISLOWER(c)) {
    i = c - 'a';
    RESET_FMARK(buf->b_namedm + i, *pos, fnum, view);
    return OK;
  }
  if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {
    if (ascii_isdigit(c)) {
      i = c - '0' + NMARKS;
    } else {
      i = c - 'A';
    }
    RESET_XFMARK(namedfm + i, *pos, fnum, view, NULL);
    return OK;
  }
  return FAIL;
}

/// Remove every jump list entry referring to a given buffer.
/// This function will also adjust the current jump list index.
void mark_jumplist_forget_file(win_T *wp, int fnum)
{
  // Remove all jump list entries that match the deleted buffer.
  for (int i = wp->w_jumplistlen - 1; i >= 0; i--) {
    if (wp->w_jumplist[i].fmark.fnum == fnum) {
      // Found an entry that we want to delete.
      free_xfmark(wp->w_jumplist[i]);

      // If the current jump list index is behind the entry we want to delete,
      // move it back by one.
      if (wp->w_jumplistidx > i) {
        wp->w_jumplistidx--;
      }


Review comment (suggestion):
side-note: would it make sense to extend `b_namedm` and drop the explicit `b_prompt_start` field? 

also just noticed something: do we need to update `NLOCALMARKS` or any other constants here?: https://github.com/neovim/neovim/blob/14e94f46177d3f562cdf9b8dc6b776fc64ca079e/src/nvim/mark_defs.h#L51-L55

Code after:
  if (c == ']') {
    buf->b_op_end = *pos;
    return OK;
  }

  if (c == '<' || c == '>') {
    if (c == '<') {
      buf->b_visual.vi_start = *pos;
    } else {
      buf->b_visual.vi_end = *pos;
    }
    if (buf->b_visual.vi_mode == NUL) {
      // Visual_mode has not yet been set, use a sane default.
      buf->b_visual.vi_mode = 'v';
    }
    return OK;
  }

  if (c == ':' && bt_prompt(buf)) {
    RESET_FMARK(&buf->b_prompt_start, *pos, buf->b_fnum, view);
    return OK;
  }

  if (ASCII_ISLOWER(c)) {
    i = c - 'a';
    RESET_FMARK(buf->b_namedm + i, *pos, fnum, view);
    return OK;
  }
  if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {
    if (ascii_isdigit(c)) {
      i = c - '0' + NMARKS;
    } else {
      i = c - 'A';
    }
    RESET_XFMARK(namedfm + i, *pos, fnum, view, NULL);
    return OK;
  }
  return FAIL;
}

/// Remove every jump list entry referring to a given buffer.
/// This function will also adjust the current jump list index.
void mark_jumplist_forget_file(win_T *wp, int fnum)
{
  // Remove all jump list entries that match the deleted buffer.
  for (int i = wp->w_jumplistlen - 1; i >= 0; i--) {
    if (wp->w_jumplist[i].fmark.fnum == fnum) {
      // Found an entry that we want to delete.
      free_xfmark(wp->w_jumplist[i]);

      // If the current jump list index is behind the entry we want to delete,